ref: 24e73840072b4214b3c5e2167a85bdc408fd3b03
parent: 918e791bc8e34f1298a4280d696f5559b35e9cf9
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Fri May 13 19:46:45 EDT 2016
rio: get rid of all mouse moves, fix cursor handling
--- a/sys/src/cmd/rio/dat.h
+++ b/sys/src/cmd/rio/dat.h
@@ -172,7 +172,6 @@
char *dir;
};
-int winborder(Window*, Point);
void winctl(void*);
void winshell(void*);
Window* wlookid(int);
--- a/sys/src/cmd/rio/fns.h
+++ b/sys/src/cmd/rio/fns.h
@@ -4,7 +4,7 @@
int parsewctl(char**, Rectangle, Rectangle*, int*, int*, int*, int*, char**, char*, char*);
int writewctl(Xfid*, char*);
Window *new(Image*, int, int, int, char*, char*, char**);
-void riosetcursor(Cursor*, int);
+void riosetcursor(Cursor*);
int min(int, int);
int max(int, int);
Rune* strrune(Rune*, Rune);
@@ -28,6 +28,7 @@
void getsnarf(void);
void timerinit(void);
int goodrect(Rectangle);
+int inborder(Rectangle, Point);
#define runemalloc(n) malloc((n)*sizeof(Rune))
#define runerealloc(a, n) realloc(a, (n)*sizeof(Rune))
--- a/sys/src/cmd/rio/rio.c
+++ b/sys/src/cmd/rio/rio.c
@@ -356,10 +356,50 @@
}
int
+inborder(Rectangle r, Point xy)
+{
+ return ptinrect(xy, r) && !ptinrect(xy, insetrect(r, Selborder));
+}
+
+Rectangle
+whichrect(Rectangle r, Point p, int which)
+{
+ switch(which){
+ case 0: /* top left */
+ r = Rect(p.x, p.y, r.max.x, r.max.y);
+ break;
+ case 2: /* top right */
+ r = Rect(r.min.x, p.y, p.x+1, r.max.y);
+ break;
+ case 6: /* bottom left */
+ r = Rect(p.x, r.min.y, r.max.x, p.y+1);
+ break;
+ case 8: /* bottom right */
+ r = Rect(r.min.x, r.min.y, p.x+1, p.y+1);
+ break;
+ case 1: /* top edge */
+ r = Rect(r.min.x, p.y, r.max.x, r.max.y);
+ break;
+ case 5: /* right edge */
+ r = Rect(r.min.x, r.min.y, p.x+1, r.max.y);
+ break;
+ case 7: /* bottom edge */
+ r = Rect(r.min.x, r.min.y, r.max.x, p.y+1);
+ break;
+ case 3: /* left edge */
+ r = Rect(p.x, r.min.y, r.max.x, r.max.y);
+ break;
+ }
+ return canonrect(r);
+}
+
+int
portion(int x, int lo, int hi)
{
x -= lo;
hi -= lo;
+ if(hi < 20)
+ return x > 0 ? 2 : 0;
if(x < 20)
return 0;
if(x > hi-20)
@@ -368,24 +408,15 @@
}
int
-whichcorner(Window *w, Point p)
+whichcorner(Rectangle r, Point p)
{
int i, j;
- i = portion(p.x, w->screenr.min.x, w->screenr.max.x);
- j = portion(p.y, w->screenr.min.y, w->screenr.max.y);
+ i = portion(p.x, r.min.x, r.max.x);
+ j = portion(p.y, r.min.y, r.max.y);
return 3*j+i;
}
-void
-cornercursor(Window *w, Point p, int force)
-{
- if(w!=nil && winborder(w, p))
- riosetcursor(corners[whichcorner(w, p)], force);
- else
- wsetcursor(w, force);
-}
-
/* thread to allow fsysproc to synchronize window closing with main proc */
void
winclosethread(void*)
@@ -449,7 +480,7 @@
void
mousethread(void*)
{
- int sending, inside, scrolling, moving, band;
+ int sending, inside, scrolling, moving;
Window *w, *winput;
Image *i;
Point xy;
@@ -509,7 +540,7 @@
else
scrolling = mouse->buttons && ptinrect(xy, winput->scrollr);
/* topped will be zero or less if window has been bottomed */
- if(sending == FALSE && !scrolling && winborder(winput, mouse->xy) && winput->topped>0){
+ if(sending == FALSE && !scrolling && inborder(winput->screenr, mouse->xy) && winput->topped>0){
moving = TRUE;
}else if(inside && (scrolling || winput->mouseopen || (mouse->buttons&1)))
sending = TRUE;
@@ -517,42 +548,31 @@
sending = FALSE;
if(sending){
Sending:
- if(mouse->buttons == 0){
- cornercursor(winput, mouse->xy, 0);
+ if(mouse->buttons == 0)
sending = FALSE;
- }else
- wsetcursor(winput, 0);
tmp = mousectl->Mouse;
tmp.xy = xy;
send(winput->mc.c, &tmp);
continue;
}
- w = wpointto(mouse->xy);
- /* change cursor if over anyone's border */
- if(w != nil)
- cornercursor(w, mouse->xy, 0);
- else
- riosetcursor(nil, 0);
if(moving && (mouse->buttons&7)){
incref(winput);
- band = mouse->buttons & 3;
- sweeping = 1;
- if(band)
+ sweeping = TRUE;
+ if(mouse->buttons & 3)
i = bandsize(winput);
else
i = drag(winput);
- sweeping = 0;
- if(i != nil){
+ sweeping = FALSE;
+ if(i != nil)
wsendctlmesg(winput, Reshaped, i->r, i);
- cornercursor(winput, mouse->xy, 1);
- }
- if(wclose(winput) == 0)
- w = winput;
- else {
- riosetcursor(nil, 0);
- w = winput = nil;
- }
+ wclose(winput);
+ continue;
}
+ w = wpointto(mouse->xy);
+ if(w!=nil && inborder(w->screenr, mouse->xy))
+ riosetcursor(corners[whichcorner(w->screenr, mouse->xy)]);
+ else
+ wsetcursor(w, FALSE);
/* we're not sending the event, but if button is down maybe we should */
if(mouse->buttons){
/* w->topped will be zero or less if window has been bottomed */
@@ -570,7 +590,7 @@
}else{
/* if button 1 event in the window, top the window and wait for button up. */
/* otherwise, top the window and pass the event on */
- if(wtop(mouse->xy) && (mouse->buttons!=1 || winborder(w, mouse->xy)))
+ if(wtop(mouse->xy) && (mouse->buttons!=1 || inborder(w->screenr, mouse->xy)))
goto Again;
goto Drain;
}
@@ -726,7 +746,7 @@
free(menu3str[i]);
menu3str[i] = nil;
}
- sweeping = 1;
+ sweeping = TRUE;
switch(i = menuhit(3, mousectl, &menu3, wscreen)){
case -1:
break;
@@ -755,7 +775,7 @@
unhide(i);
break;
}
- sweeping = 0;
+ sweeping = FALSE;
}
void
@@ -836,7 +856,7 @@
i = nil;
menuing = TRUE;
- riosetcursor(&crosscursor, 1);
+ riosetcursor(&crosscursor);
while(mouse->buttons == 0)
readmouse(mousectl);
p0 = onscreen(mouse->xy);
@@ -848,6 +868,7 @@
if(!eqpt(mouse->xy, p)){
p = onscreen(mouse->xy);
r = canonrect(Rpt(p0, p));
+ r = whichrect(r, p, whichcorner(r, p));
if(Dx(r)>5 && Dy(r)>5){
i = allocwindow(wscreen, r, Refnone, DNofill);
freeimage(oi);
@@ -869,18 +890,18 @@
freeimage(oi);
if(i == nil)
goto Rescue;
- cornercursor(input, mouse->xy, 1);
+ riosetcursor(corners[whichcorner(i->r, mouse->xy)]);
goto Return;
Rescue:
+ riosetcursor(nil);
freeimage(i);
i = nil;
- cornercursor(input, mouse->xy, 1);
+ flushimage(display, 1);
while(mouse->buttons)
readmouse(mousectl);
Return:
- moveto(mousectl, mouse->xy); /* force cursor update; ugly */
menuing = FALSE;
return i;
}
@@ -925,11 +946,11 @@
Rectangle r;
menuing = TRUE;
+ riosetcursor(&boxcursor);
om = mouse->xy;
- riosetcursor(&boxcursor, 1);
- dm = subpt(mouse->xy, w->screenr.min);
+ dm = subpt(om, w->screenr.min);
d = subpt(w->screenr.max, w->screenr.min);
- op = subpt(mouse->xy, dm);
+ op = subpt(om, dm);
drawborder(Rect(op.x, op.y, op.x+d.x, op.y+d.y), 1);
while(mouse->buttons==4){
p = subpt(mouse->xy, dm);
@@ -941,10 +962,11 @@
}
r = Rect(op.x, op.y, op.x+d.x, op.y+d.y);
drawborder(r, 0);
- cornercursor(w, mouse->xy, 1);
- moveto(mousectl, mouse->xy); /* force cursor update; ugly */
+ p = mouse->xy;
+ riosetcursor(inborder(r, p) ? corners[whichcorner(r, p)] : nil);
menuing = FALSE;
- if(mouse->buttons!=0 || !goodrect(r)){
+ if(mouse->buttons!=0 || !goodrect(r) || eqrect(r, screen->r)){
+ flushimage(display, 1);
while(mouse->buttons)
readmouse(mousectl);
return nil;
@@ -952,70 +974,6 @@
return allocwindow(wscreen, r, Refbackup, DNofill);
}
-Point
-cornerpt(Rectangle r, Point p, int which)
-{
- switch(which){
- case 0: /* top left */
- p = Pt(r.min.x, r.min.y);
- break;
- case 2: /* top right */
- p = Pt(r.max.x,r.min.y);
- break;
- case 6: /* bottom left */
- p = Pt(r.min.x, r.max.y);
- break;
- case 8: /* bottom right */
- p = Pt(r.max.x, r.max.y);
- break;
- case 1: /* top edge */
- p = Pt(p.x,r.min.y);
- break;
- case 5: /* right edge */
- p = Pt(r.max.x, p.y);
- break;
- case 7: /* bottom edge */
- p = Pt(p.x, r.max.y);
- break;
- case 3: /* left edge */
- p = Pt(r.min.x, p.y);
- break;
- }
- return p;
-}
-
-Rectangle
-whichrect(Rectangle r, Point p, int which)
-{
- switch(which){
- case 0: /* top left */
- r = Rect(p.x, p.y, r.max.x, r.max.y);
- break;
- case 2: /* top right */
- r = Rect(r.min.x, p.y, p.x, r.max.y);
- break;
- case 6: /* bottom left */
- r = Rect(p.x, r.min.y, r.max.x, p.y);
- break;
- case 8: /* bottom right */
- r = Rect(r.min.x, r.min.y, p.x, p.y);
- break;
- case 1: /* top edge */
- r = Rect(r.min.x, p.y, r.max.x, r.max.y);
- break;
- case 5: /* right edge */
- r = Rect(r.min.x, r.min.y, p.x, r.max.y);
- break;
- case 7: /* bottom edge */
- r = Rect(r.min.x, r.min.y, r.max.x, p.y);
- break;
- case 3: /* left edge */
- r = Rect(p.x, r.min.y, r.max.x, r.max.y);
- break;
- }
- return canonrect(r);
-}
-
Image*
bandsize(Window *w)
{
@@ -1025,10 +983,8 @@
p = mouse->xy;
but = mouse->buttons;
- which = whichcorner(w, p);
- p = cornerpt(w->screenr, p, which);
- wmovemouse(w, p);
- readmouse(mousectl);
+ which = whichcorner(w->screenr, p);
+ riosetcursor(corners[which]);
r = whichrect(w->screenr, p, which);
drawborder(r, 1);
or = r;
@@ -1045,14 +1001,13 @@
}
p = mouse->xy;
drawborder(or, 0);
- wsetcursor(w, 1);
- if(mouse->buttons!=0 || !goodrect(or)){
+ if(mouse->buttons!=0 || !goodrect(or) || eqrect(or, w->screenr)
+ || abs(p.x-startp.x)+abs(p.y-startp.y) <= 1){
+ flushimage(display, 1);
while(mouse->buttons)
readmouse(mousectl);
return nil;
}
- if(abs(p.x-startp.x)+abs(p.y-startp.y) <= 1)
- return nil;
return allocwindow(wscreen, or, Refbackup, DNofill);
}
@@ -1062,7 +1017,7 @@
Window *w;
menuing = TRUE;
- riosetcursor(&sightcursor, 1);
+ riosetcursor(&sightcursor);
while(mouse->buttons == 0)
readmouse(mousectl);
if(mouse->buttons == 4)
@@ -1072,7 +1027,7 @@
if(wait){
while(mouse->buttons){
if(mouse->buttons!=4 && w !=nil){ /* cancel */
- cornercursor(input, mouse->xy, 0);
+ riosetcursor(nil);
w = nil;
}
readmouse(mousectl);
@@ -1080,8 +1035,7 @@
if(w != nil && wpointto(mouse->xy) != w)
w = nil;
}
- cornercursor(input, mouse->xy, 0);
- moveto(mousectl, mouse->xy); /* force cursor update; ugly */
+ riosetcursor(nil);
menuing = FALSE;
return w;
}
@@ -1125,7 +1079,6 @@
i = drag(w);
if(i)
wsendctlmesg(w, Reshaped, i->r, i);
- cornercursor(w, mouse->xy, 1);
wclose(w);
}
--- a/sys/src/cmd/rio/wind.c
+++ b/sys/src/cmd/rio/wind.c
@@ -687,7 +687,7 @@
--w->holding;
else
w->holding++;
- wsetcursor(w, 0);
+ wsetcursor(w, FALSE);
wrepaint(w);
if(r == Kesc)
return;
@@ -871,9 +871,9 @@
m->data = runetobyte(w->r+p0, p1-p0, &m->ndata);
if(plumbsend(fd, m) < 0){
c = lastcursor;
- riosetcursor(&query, 1);
+ riosetcursor(&query);
sleep(300);
- riosetcursor(c, 1);
+ riosetcursor(c);
}
plumbfree(m);
}
@@ -903,12 +903,6 @@
wshow(w, i);
}
-int
-winborder(Window *w, Point xy)
-{
- return ptinrect(xy, w->screenr) && !ptinrect(xy, insetrect(w->screenr, Selborder));
-}
-
void
wmousectl(Window *w)
{
@@ -1199,7 +1193,7 @@
if(w->i==nil)
break;
if(w==input)
- wsetcursor(w, 0);
+ wsetcursor(w, FALSE);
wrepaint(w);
flushimage(display, 1);
break;
@@ -1299,6 +1293,8 @@
{
Cursor *p;
+ if(menuing || sweeping)
+ return;
if(w==nil || w->i==nil || Dx(w->screenr)<=0)
p = nil;
else if(wpointto(mouse->xy) == w){
@@ -1307,20 +1303,20 @@
p = &whitearrow;
}else
p = nil;
- if(!menuing)
- riosetcursor(p, force && !menuing);
+ if(force) /* force cursor reload */
+ lastcursor = nil;
+ riosetcursor(p);
}
void
-riosetcursor(Cursor *p, int force)
+riosetcursor(Cursor *p)
{
- if(!force && p==lastcursor)
+ if(p==lastcursor)
return;
setcursor(mousectl, p);
lastcursor = p;
}
-
void
wtopme(Window *w)
{
@@ -1377,7 +1373,7 @@
w->deleted = TRUE;
if(w == input){
input = nil;
- wsetcursor(w, 0);
+ wsetcursor(w, FALSE);
}
if(w == wkeyboard)
wkeyboard = nil;
--- a/sys/src/cmd/rio/xfid.c
+++ b/sys/src/cmd/rio/xfid.c
@@ -478,7 +478,7 @@
memmove(w->cursor.clr, x->data+2*4, 2*2*16);
w->cursorp = &w->cursor;
}
- wsetcursor(w, !sweeping);
+ wsetcursor(w, !sweeping && !menuing);
break;
case Qlabel: