patch for some acme scrolling issues that've been bugging me for years. 1) when middle-button scrolling to the bottom of a long document, acme doesn't go right to the end - there's a bit more of the document left below. 2) acme constrains the mouse to remain within the boundaries of the scrollbar. i find this unnecessary and sometimes unhelpful. 3) clicking with b1 or b3 on the very top line's-worth of the scrollbar does nothing, meaning that it's essentially dead space, and also that it's awkward to scroll very small (one or two line) windows. one gratuitous change: a piece of code from optionally using fixed-point arithmetic to use a vlong; it looks simpler that way and the overhead is negligible by my reckoning. YMMV. Notes: Thu Mar 17 23:18:08 EST 2005 rsc i picked up 1) and the vlong change. i changed 2) so that the mouse can't get out of the scroll bar ever, but kept the boundaries. i did not pick up 3) at all. you might convince me to special case clicking on the top line, but changing the click semantics is too big a change, and it destroys the very nice explanation that 1-clicking a line brings the top line to where you clicked, and 3-clicking brings the current line to the top. i changed cols.c so that you can 1 or 3 click in the space below the bottom window, in case the mouse ends up there after a 2-scroll. Reference: /n/sources/patch/applied/acmescroll Date: Tue Mar 15 02:35:27 CET 2005 Reviewed-by: rsc --- /sys/src/cmd/acme/scrl.c Tue Mar 15 02:15:53 2005 +++ /sys/src/cmd/acme/scrl.c Tue Mar 15 02:15:40 2005 @@ -112,53 +112,42 @@ s = insetrect(t->scrollr, 1); h = s.max.y-s.min.y; - x = (s.min.x+s.max.x)/2; oldp0 = ~0; first = TRUE; do{ flushimage(display, 1); - if(mouse->xy.xxy.x){ - readmouse(mousectl); - }else{ - my = mouse->xy.y; - if(my < s.min.y) - my = s.min.y; - if(my >= s.max.y) - my = s.max.y; - if(!eqpt(mouse->xy, Pt(x, my))){ - moveto(mousectl, Pt(x, my)); - readmouse(mousectl); /* absorb event generated by moveto() */ - } - if(but == 2){ - y = my; - if(y > s.max.y-2) - y = s.max.y-2; - if(t->file->nc > 1024*1024) - p0 = ((t->file->nc>>10)*(y-s.min.y)/h)<<10; - else - p0 = t->file->nc*(y-s.min.y)/h; - if(oldp0 != p0) - textsetorigin(t, p0, FALSE); - oldp0 = p0; - readmouse(mousectl); - continue; - } - if(but == 1) - p0 = textbacknl(t, t->org, (my-s.min.y)/t->font->height); - else - p0 = t->org+frcharofpt(t, Pt(s.max.x, my)); + my = mouse->xy.y; + if(my < s.min.y) + my = s.min.y; + if(my >= s.max.y) + my = s.max.y; + if(but == 2){ + y = my; + p0 = (vlong)t->file->nc * (y-s.min.y) / h; + if(p0 >= t->q1) + p0 = textbacknl(t, p0, 2); if(oldp0 != p0) - textsetorigin(t, p0, TRUE); + textsetorigin(t, p0, FALSE); oldp0 = p0; - /* debounce */ - if(first){ - flushimage(display, 1); - sleep(200); - nbrecv(mousectl->c, &mousectl->Mouse); - first = FALSE; - } - scrsleep(80); + readmouse(mousectl); + continue; + } + my += t->font->height; + if(but == 1) + p0 = textbacknl(t, t->org, (my-s.min.y)/t->font->height); + else + p0 = t->org+frcharofpt(t, Pt(s.max.x, my)); + if(oldp0 != p0) + textsetorigin(t, p0, TRUE); + oldp0 = p0; + /* debounce */ + if(first){ + flushimage(display, 1); + sleep(200); + nbrecv(mousectl->c, &mousectl->Mouse); + first = FALSE; } + scrsleep(80); }while(mouse->buttons & (1<<(but-1))); while(mouse->buttons) readmouse(mousectl);