diff --git a/sys/src/cmd/rio/dat.h b/sys/src/cmd/rio/dat.h index 9698914c4..324698f7b 100644 --- a/sys/src/cmd/rio/dat.h +++ b/sys/src/cmd/rio/dat.h @@ -195,7 +195,7 @@ void wclosewin(Window*); void wcurrent(Window*); void wcut(Window*); void wdelete(Window*, uint, uint); -void wdoubleclick(Window*, uint*, uint*); +void wstretchsel(Window*, uint*, uint*, int); void wfill(Window*); void wframescroll(Window*, int); void wkeyctl(Window*, Rune); diff --git a/sys/src/cmd/rio/fns.h b/sys/src/cmd/rio/fns.h index 5a2d1bb4a..8562c2cd9 100644 --- a/sys/src/cmd/rio/fns.h +++ b/sys/src/cmd/rio/fns.h @@ -9,6 +9,7 @@ int min(int, int); int max(int, int); Rune* strrune(Rune*, Rune); int isalnum(Rune); +int isspace(Rune); void timerstop(Timer*); void timercancel(Timer*); Timer* timerstart(int); diff --git a/sys/src/cmd/rio/util.c b/sys/src/cmd/rio/util.c index dffaaae79..0b9fa19e8 100644 --- a/sys/src/cmd/rio/util.c +++ b/sys/src/cmd/rio/util.c @@ -105,6 +105,13 @@ isalnum(Rune c) return TRUE; } +int +isspace(Rune c) +{ + return c == 0 || c == ' ' || c == '\t' || + c == '\n' || c == '\r' || c == '\v'; +} + Rune* strrune(Rune *s, Rune c) { diff --git a/sys/src/cmd/rio/wind.c b/sys/src/cmd/rio/wind.c index b583d1360..2a5e065bf 100644 --- a/sys/src/cmd/rio/wind.c +++ b/sys/src/cmd/rio/wind.c @@ -962,6 +962,7 @@ wdelete(Window *w, uint q0, uint q1) static Window *clickwin; static uint clickmsec; +static uint clickcount; static Window *selectwin; static uint selectq; @@ -1007,7 +1008,7 @@ void wselect(Window *w) { uint q0, q1; - int b, x, y, first; + int b, x, y, dx, dy, mode, first; first = 1; selectwin = w; @@ -1018,23 +1019,32 @@ wselect(Window *w) q0 = w->q0; q1 = w->q1; selectq = w->org+frcharofpt(w, w->mc.xy); - if(clickwin==w && w->mc.msec-clickmsec<500) - if(q0==q1 && selectq==w->q0){ - wdoubleclick(w, &q0, &q1); + clickcount++; + if(w->mc.msec-clickmsec >= 500 || clickwin != w || clickcount > 3) + clickcount = 0; + if(clickwin == w && clickcount >= 1 && w->mc.msec-clickmsec < 500){ + mode = (clickcount > 2) ? 2 : clickcount; + wstretchsel(w, &q0, &q1, mode); wsetselect(w, q0, q1); x = w->mc.xy.x; y = w->mc.xy.y; /* stay here until something interesting happens */ - do + while(1){ readmouse(&w->mc); - while(w->mc.buttons==b && abs(w->mc.xy.x-x)<3 && abs(w->mc.xy.y-y)<3); + dx = abs(w->mc.xy.x-x); + dy = abs(w->mc.xy.y-y); + if(w->mc.buttons != b || dx >= 3 && dy >= 3) + break; + clickcount++; + clickmsec = w->mc.msec; + } w->mc.xy.x = x; /* in case we're calling frselect */ w->mc.xy.y = y; q0 = w->q0; /* may have changed */ q1 = w->q1; selectq = q0; } - if(w->mc.buttons == b){ + if(w->mc.buttons == b && clickcount == 0){ w->scroll = framescroll; frselect(w, &w->mc); /* horrible botch: while asleep, may have lost selection altogether */ @@ -1051,15 +1061,13 @@ wselect(Window *w) q1 = w->org+w->p1; } if(q0 == q1){ - if(q0==w->q0 && clickwin==w && w->mc.msec-clickmsec<500){ - wdoubleclick(w, &q0, &q1); - clickwin = nil; - }else{ + mode = (clickcount > 2) ? 2 : clickcount; + if(q0==w->q0 && clickwin==w && w->mc.msec-clickmsec<500) + wstretchsel(w, &q0, &q1, mode); + else clickwin = w; - clickmsec = w->mc.msec; - } - }else - clickwin = nil; + clickmsec = w->mc.msec; + } wsetselect(w, q0, q1); while(w->mc.buttons){ w->mc.msec = 0; @@ -1079,7 +1087,8 @@ wselect(Window *w) wscrdraw(w); while(w->mc.buttons == b) readmouse(&w->mc); - clickwin = nil; + if(w->mc.msec-clickmsec >= 500) + clickwin = nil; } } @@ -1483,8 +1492,14 @@ Rune *right[] = { nil }; +int +inmode(Rune r, int mode) +{ + return (mode == 1) ? isalnum(r) : r && !isspace(r); +} + void -wdoubleclick(Window *w, uint *q0, uint *q1) +wstretchsel(Window *w, uint *q0, uint *q1, int mode) { int c, i; Rune *r, *l, *p; @@ -1522,10 +1537,10 @@ wdoubleclick(Window *w, uint *q0, uint *q1) } } /* try filling out word to right */ - while(*q1nr && isalnum(w->r[*q1])) + while(*q1nr && inmode(w->r[*q1], mode)) (*q1)++; /* try filling out word to left */ - while(*q0>0 && isalnum(w->r[*q0-1])) + while(*q0>0 && inmode(w->r[*q0-1], mode)) (*q0)--; }