ref: e1bb0942d72079e7659cff7a6743d7a3508b7eea
parent: ffcdfa59715eb8241bd2be721831e6c43fa3a7b3
author: qwx <qwx@sciops.net>
date: Mon Nov 3 05:19:57 EST 2025
Subject: [PATCH] samterm: Make scrollbar act like rio's Now, if you hold-click on the scrollbar, it will continuously scroll; this is instad of just showing where the scrollbar would be placed once the mouse is released. This uses the same host-flushing mechanism needed by frscroll(). Also, instead of the following scrollbar-to-line mapping, ———————————————— |[0]| Line 0 |[1]| Line 1 |[2]| Line 2 we should match rio's: ———————————————— |[1]| Line 0 |[1]| Line 1 |[2]| Line 2
--- a/sys/src/cmd/jamterm/io.c
+++ b/sys/src/cmd/jamterm/io.c
@@ -55,13 +55,6 @@
}
void
-getmouse(void)
-{- if(readmouse(mousectl) < 0)
- panic("mouse");-}
-
-void
mouseunblock(void)
{got &= ~(1<<RMouse);
@@ -73,13 +66,6 @@
block = (1<<RKeyboard)|(1<<RPlumb);
}
-int
-button(int but)
-{- getmouse();
- return mousep->buttons&(1<<(but-1));
-}
-
void
externload(int i)
{@@ -185,7 +171,30 @@
return (char*)hostp;
}
+/*
+ * when doing consecutive scrolling operations outside of the main loop
+ * in threadmain(), we need to wait for any RHost messages we've sent to
+ * come back from the host.
+ */
void
+forcenter(Flayer *l, ulong a, int n)
+{+ Text *t = l->user1;
+
+ flushdisplay();
+ center(l, a, n);
+ if(n > 0 && !t->lock)
+ /* no msg sent */
+ return;
+
+ do{+ block = ~(1 << RHost);
+ waitforio();
+ rcv();
+ }while(t->lock);
+}
+
+void
frscroll(Frame *f, int n)
{Flayer *l = which;
@@ -218,22 +227,8 @@
l->p1 = l->origin+f->p1;
}
}
-
- flushdisplay();
- center(l, l->origin, n);
- if(n > 0 && !t->lock)
- /* no msg sent */
- return;
-
- /*
- * we must pull io from host while we are in frame(2)
- */
scrselecting = 1;
- do{- block = ~(1 << RHost);
- waitforio();
- rcv();
- }while(t->lock);
+ forcenter(l, l->origin, n);
scrselecting = 0;
}
--- a/sys/src/cmd/jamterm/main.c
+++ b/sys/src/cmd/jamterm/main.c
@@ -319,7 +319,8 @@
buttons(int updown)
{while(((mousep->buttons&7)!=0) != updown)
- getmouse();
+ if(readmouse(mousectl) < 0)
+ panic("mouse");}
void
--- a/sys/src/cmd/jamterm/samterm.h
+++ b/sys/src/cmd/jamterm/samterm.h
@@ -100,15 +100,14 @@
void outcmd(void);
void rinit(Rasp*);
void startnewfile(int, Text*);
-void getmouse(void);
void mouseunblock(void);
void kbdblock(void);
void hoststart(void);
int plumbstart(void);
-int button(int but);
int load(char*, int);
int waitforio(void);
int rcvchar(void);
+void forcenter(Flayer*, ulong, int);
void frscroll(Frame*, int);
int getch(void);
int kbdchar(void);
@@ -163,7 +162,6 @@
void flushtyping(int);
void dumperrmsg(int, int, int, int);
int screensize(int*,int*);
-void getmouse(void);
Rectangle inflatepoint(Point);
int promptrect(Rectangle*, Flayer*, int);
Rectangle defaultcmdrect(void);
--- a/sys/src/cmd/jamterm/scroll.c
+++ b/sys/src/cmd/jamterm/scroll.c
@@ -9,7 +9,6 @@
#include "samterm.h"
static Image *scrtmp;
-static Image *scrback;
void
scrtemps(void)
@@ -21,8 +20,7 @@
if(screensize(0, &h) == 0)
h = 2048;
scrtmp = allocimage(display, Rect(0, 0, 32, h), screen->chan, 0, 0);
- scrback = allocimage(display, Rect(0, 0, 32, h), screen->chan, 0, 0);
- if(scrtmp==0 || scrback==0)
+ if(scrtmp==0)
panic("scrtemps");}
@@ -52,27 +50,6 @@
}
void
-scrmark(Flayer *l, Rectangle r)
-{- r.max.x--;
- if(rectclip(&r, l->scroll)) {- if (l->f.b == nil)
- panic("scrmark: nil l->f.b");- draw(l->f.b, r, l->f.cols[HIGH], nil, ZP);
- }
-}
-
-void
-scrunmark(Flayer *l, Rectangle r)
-{- if(rectclip(&r, l->scroll)) {- if (l->f.b == nil)
- panic("scrunmark: nil l->f.b");- draw(l->f.b, r, scrback, nil, Pt(0, r.min.y-l->scroll.min.y));
- }
-}
-
-void
scrdraw(Flayer *l, long tot)
{Rectangle r, r1, r2;
@@ -105,65 +82,46 @@
void
scroll(Flayer *l, int but)
{- int in = 0, oin;
- long tot = scrtotal(l);
- Rectangle scr, r, s, rt;
- int x, y, my, oy, n;
- long p0, o;
+ Rectangle s;
+ int my, n;
+ long o, tot;
+ int once;
if(l->visible==None)
return;
+ once = 0;
s = l->scroll;
- x = s.min.x+FLSCROLLWID/2;
- scr = scrpos(l->scroll, l->origin, l->origin+l->f.nchars, tot);
- r = scr;
- y = scr.min.y;
- my = mousep->xy.y;
- draw(scrback, Rect(0,0,Dx(l->scroll), Dy(l->scroll)), l->f.b, nil, l->scroll.min);
+ tot = scrtotal(l);
do{- oin = in;
- in = (but > 3) || (but == 2) || abs(x-mousep->xy.x)<=FLSCROLLWID/2;
- if(oin && !in)
- scrunmark(l, r);
- if(in){- scrmark(l, r);
- oy = y;
- my = mousep->xy.y;
- if(my < s.min.y)
- my = s.min.y;
- if(my >= s.max.y)
- my = s.max.y;
- if(but == 1 || but == 4){- p0 = l->origin-frcharofpt(&l->f, Pt(s.max.x, my));
- rt = scrpos(l->scroll, p0, p0+l->f.nchars, tot);
- y = rt.min.y;
- }else if(but == 2){- y = my;
- if(y > s.max.y-2)
- y = s.max.y-2;
- }else if(but == 3 || but == 5){- p0 = l->origin+frcharofpt(&l->f, Pt(s.max.x, my));
- rt = scrpos(l->scroll, p0, p0+l->f.nchars, tot);
- y = rt.min.y;
- }
- if(y != oy){- scrunmark(l, r);
- r = rectaddpt(scr, Pt(0, y-scr.min.y));
- scrmark(l, r);
- }
- }
- }while(but <= 3 && button(but));
- if(in){- scrunmark(l, r);
+ my = mousep->xy.y;
+ if(my < s.min.y)
+ my = s.min.y;
+ if(my > s.max.y)
+ my = s.max.y;
+ my -= s.min.y;
if(but == 2){+ o = (tot / (s.max.y - s.min.y)) * my;
n = 0;
- o = (tot / (s.max.y - s.min.y)) * (my - s.min.y);
}else{- n = (my - s.min.y)/l->f.font->height;
- n *= (but == 1 || but == 4)? -1: 1;
o = l->origin;
+ n = my/l->f.font->height;
+ if(n == 0)
+ n++;
+ if(but == 1 || but == 4)
+ n = -n;
+ if(!once){+ if(but == 4 || but == 5){+ center(l, o, n);
+ return;
+ }
+ once++;
+ sleep(175);
+ }
+ sleep(25);
}
- center(l, o, n);
- }
+ forcenter(l, o, n);
+ if(nbrecv(mousectl->c, mousectl) < 0)
+ panic("mouse");+ }while(mousectl->buttons & (1 << (but-1)));
}
--
⑨