shithub: riscv

Download patch

ref: 24e73840072b4214b3c5e2167a85bdc408fd3b03
parent: 918e791bc8e34f1298a4280d696f5559b35e9cf9
author: cinap_lenrek <[email protected]>
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: