abaco: pageselect1 ordering — same-line drag orders by X
Addresses the NOTES entry "fix text selection" on the click-drag path.
pageselect1 at page.c:541 decides p->top / p->bot ordering from a
strict-less-than comparison on raw pixel Y values. Mouse hardware
emits 1-2 pixel Y wobble during a drag. Within a single visual
text line that wobble flips opos.y vs npos.y between events, so
p->top / p->bot flip between canonical and reversed multiple times
per drag. In the reversed state (p->top to the right of p->bot on
same row, or diagonally offset on different rows), istextsel +
html.c drawing produces a two-piece highlight: from the start of
the row to p->bot, nothing in the middle, from p->top to the end
of the row — the "complement" symptom a user sees as a broken
highlight on in-line drags.
Multi-line drags aren't affected: different Lines occupy
non-overlapping Y ranges, so pixel-Y comparison is stable across
1-2 px wobble. Only same-line drags trip on the wobble.
Fix: if both points resolve to the same Line (via linewhich, which
pagedoubleclick already uses at page.c:583), order by X. Otherwise
fall back to the existing pixel-Y comparison.
Minimal fix: one if-else becomes one if-elseif-else, no new
variables, linewhich inlined. Three lines added net.
Also drops the NOTES "fix text selection and double clicking"
bullet — abaco-doubleclick-typo (bracket/quote) and
abaco-pagedoubleclick-guard (nil-deref past EOL) cover the other
two code issues the bullet referenced.
RFC relevance: none
--- sys/src/cmd/abaco/NOTES
+++ sys/src/cmd/abaco/NOTES
@@ -1,6 +1,5 @@
Bugs:
- * fix text selection and double clicking;
Not Bugs:
* complaints like "gif: decode <stdin> failed: ReadGIF: can't recognize format ��"
are caused by sites that return a jpeg and send Content-Type: image/gif.
--- sys/src/cmd/abaco/page.c
+++ sys/src/cmd/abaco/page.c
@@ -538,7 +538,14 @@
scrled = pagescrollxy(p, x, y);
npos = getpt(p, mp);
- if(opos.y < npos.y){
+ if(linewhich(p->lay, opos) == linewhich(p->lay, npos)){
+ /* same visual line — order by X (pixel-Y is
+ * unstable against 1-2 px mouse-hardware wobble) */
+ if(opos.x <= npos.x)
+ p->top = opos, p->bot = npos;
+ else
+ p->top = npos, p->bot = opos;
+ }else if(opos.y < npos.y){
p->top = opos;
p->bot = npos;
}else{
|