shithub: riscv

Download patch

ref: 25493360e37474fb656eb8eea336e80bf3e99c66
parent: 83b56186e46087b06b2af8d58ff293eda6be6bad
author: cinap_lenrek <[email protected]>
date: Sat Jan 28 22:52:41 EST 2012

winwatch: highlight window state

--- a/sys/src/cmd/winwatch.c
+++ b/sys/src/cmd/winwatch.c
@@ -4,16 +4,20 @@
 #include <event.h>
 #include <regexp.h>
 
+enum {
+	VISIBLE = 1,
+	CURRENT = 2,
+};
+
 typedef struct Win Win;
 struct Win {
 	int n;
 	int dirty;
+	int state;
 	char *label;
 	Rectangle r;
 };
 
-
-
 Reprog  *exclude  = nil;
 Win *win;
 int nwin;
@@ -21,6 +25,7 @@
 int onwin;
 int rows, cols;
 Image *lightblue;
+Image *statecol[4];
 
 enum {
 	PAD = 3,
@@ -63,14 +68,43 @@
 	return t;
 }
 
+int
+readfile(char *buf, int nbuf, char *file, ...)
+{
+	va_list arg;
+	int n, fd;
 
+	va_start(arg, file);
+	vsnprint(buf, nbuf, file, arg);
+	va_end(arg);
+
+	if((fd = open(buf, OREAD)) < 0){
+		buf[0] = 0;
+		return -1;
+	}
+	n = read(fd, buf, nbuf-1);
+	close(fd);
+	if(n < 0){
+		buf[0] = 0;
+		return -1;
+	}
+	buf[n] = 0;
+	return n;
+}
+
 void
 refreshwin(void)
 {
-	char label[128];
-	int i, fd, lfd, n, nr, nw, m;
+	char label[128], wctl[128], *tok[8];
+	int i, fd, n, nr, nw, state;
+	static int mywinid = -1;
 	Dir *pd;
 
+	if(mywinid < 0){
+		if(readfile(wctl, sizeof(wctl), "/dev/winid") > 0)
+			mywinid = atoi(wctl);
+	}
+
 	if((fd = open("/dev/wsys", OREAD)) < 0)
 		return;
 
@@ -79,18 +113,23 @@
 	while((nr=dirread(fd, &pd)) > 0){
 		for(i=0; i<nr; i++){
 			n = atoi(pd[i].name);
-			sprint(label, "/dev/wsys/%d/label", n);
-			if((lfd = open(label, OREAD)) < 0)
+			if(n == mywinid)
 				continue;
-			m = read(lfd, label, sizeof(label)-1);
-			close(lfd);
-			if(m < 0)
+			if(readfile(label, sizeof(label), "/dev/wsys/%d/label", n) <= 0)
 				continue;
-			label[m] = '\0';
 			if(exclude != nil && regexec(exclude,label,nil,0))
 				continue;
-
-			if(nw < nwin && win[nw].n == n && strcmp(win[nw].label, label)==0){
+			if(readfile(wctl, sizeof(wctl), "/dev/wsys/%d/wctl", n) <= 0)
+				continue;
+			if(tokenize(wctl, tok, nelem(tok)) != 6)
+				continue;
+			state = 0;
+			if(strcmp(tok[4], "current") == 0)
+				state |= CURRENT;
+			if(strcmp(tok[5], "visible") == 0)
+				state |= VISIBLE;
+			if(nw < nwin && win[nw].n == n && win[nw].state == state && 
+			   strcmp(win[nw].label, label)==0){
 				nw++;
 				continue;
 			}
@@ -106,6 +145,7 @@
 			}
 			win[nw].n = n;
 			win[nw].label = estrdup(label);
+			win[nw].state = state;
 			win[nw].dirty = 1;
 			win[nw].r = Rect(0,0,0,0);
 			nw++;
@@ -132,7 +172,7 @@
 void
 drawwin(int i)
 {
-	draw(screen, win[i].r, lightblue, nil, ZP);
+	draw(screen, win[i].r, statecol[win[i].state], nil, ZP);
 	_string(screen, addpt(win[i].r.min, Pt(2,0)), display->black, ZP,
 		font, win[i].label, nil, strlen(win[i].label), 
 		win[i].r, nil, ZP, SoverD);
@@ -191,45 +231,37 @@
 	redraw(screen, 1);
 }
 
-void
+int
 click(Mouse m)
 {
-	int fd, i, j;	
 	char buf[128];
+	int fd, i;	
 
-	if(m.buttons == 0 || (m.buttons & ~4))
-		return;
-
+	if((m.buttons & 7) != 4)
+		return 0;
 	for(i=0; i<nwin; i++)
 		if(ptinrect(m.xy, win[i].r))
 			break;
 	if(i == nwin)
-		return;
-
+		return 0;
 	do
 		m = emouse();
-	while(m.buttons == 4);
+	while((m.buttons & 7) == 4);
+	if((m.buttons & 7) || !ptinrect(m.xy, win[i].r))
+		return 0;
 
-	if(m.buttons != 0){
-		do
-			m = emouse();
-		while(m.buttons);
-		return;
-	}
-
-	for(j=0; j<nwin; j++)
-		if(ptinrect(m.xy, win[j].r))
-			break;
-	if(j != i)
-		return;
-
 	sprint(buf, "/dev/wsys/%d/wctl", win[i].n);
 	if((fd = open(buf, OWRITE)) < 0)
-		return;
-	write(fd, "unhide\n", 7);
-	write(fd, "top\n", 4);
-	write(fd, "current\n", 8);
+		return 0;
+	if(win[i].state == (CURRENT|VISIBLE))
+		write(fd, "hide\n", 5);
+	else {
+		write(fd, "unhide\n", 7);
+		write(fd, "top\n", 4);
+		write(fd, "current\n", 8);
+	}
 	close(fd);
+	return 1;
 }
 
 void
@@ -245,6 +277,7 @@
 	char *fontname = nil;
 	int Etimer;
 	Event e;
+	int i;
 
 	ARGBEGIN{
 	case 'f':
@@ -265,9 +298,16 @@
 	if(initdraw(0, fontname, "winwatch") < 0)
 		sysfatal("initdraw: %r");
 	lightblue = allocimagemix(display, DPalebluegreen, DWhite);
-	if(lightblue == nil)
-		sysfatal("allocimagemix: %r");
 
+	statecol[0] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xCCCCCCFF);
+	statecol[1] = lightblue;
+	statecol[2] = lightblue;
+	statecol[3] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPalegreygreen);
+
+	for(i=0; i<nelem(statecol); i++)
+		if(statecol[i] == nil)
+			sysfatal("allocimage: %r");
+
 	refreshwin();
 	redraw(screen, 1);
 	einit(Emouse|Ekeyboard);
@@ -280,8 +320,8 @@
 				exits(0);
 			break;
 		case Emouse:
-			if(e.mouse.buttons)
-				click(e.mouse);
+			if(click(e.mouse) == 0)
+				continue;
 			/* fall through  */
 		default:	/* Etimer */
 			refreshwin();