Commit Diff


commit - c005568a7fe03010dcd1b2df311e3cd7f7459448
commit + 4f30f3b44464f9b89512224095474200390b03e9
blob - fc81fa98d46926155e25f972c3e4e3c3fdef7f19
blob + fd73bec40e443d02781c630c2f91e2fac75574bc
--- CHANGES
+++ CHANGES
@@ -1,3 +1,11 @@
+March 29, 2004
+
+	Add window resizing by dragging borders to rio.
+	Code from Axel Belinfante.
+
+	Added code to make 9term fade itself when it loses
+	focus running under rio.
+
 March 26, 2004
 
 	Fix 9term chording paste bug reported by Sam.
blob - 2c190b23d99c61343572d180ba396e5ec9921d27
blob + 9b563faf467362bbb86e0f5bead98dfa8638d635
--- include/mouse.h
+++ include/mouse.h
@@ -48,6 +48,9 @@ extern void		drawgetrect(Rectangle, int);
 extern Rectangle	getrect(int, Mousectl*);
 extern int	 		menuhit(int, Mousectl*, Menu*, Screen*);
 
+extern void		bouncemouse(Mouse*);
+extern int			_windowhasfocus;	/* XXX do better */
+extern int			_wantfocuschanges;
 
 #if defined(__cplusplus)
 }
blob - f8eaf4328bf694b16dc611870cc477742a9b0256
blob + 2923deeae98637e02e5c0e5add7972ab0d6821a5
--- src/cmd/9term/9term.c
+++ src/cmd/9term/9term.c
@@ -152,6 +152,9 @@ char *menu2str[] = {
 
 Image* cols[NCOL];
 Image* hcols[NCOL];
+Image* palegrey;
+Image* paleblue;
+Image* blue;
 Image *plumbcolor;
 Image *execcolor;
 
@@ -187,6 +190,7 @@ threadmain(int argc, char *argv[])
 	char *p;
 
 	rfork(RFNOTEG);
+	_wantfocuschanges = 1;
 	mainpid = getpid();
 	ARGBEGIN{
 	default:
@@ -236,16 +240,22 @@ threadmain(int argc, char *argv[])
 	}
 	cols[TEXT] = display->black;
 	cols[HTEXT] = display->black;
+	palegrey = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0x666666FF);
 
 	hcols[BACK] = cols[BACK];
 	hcols[HIGH] = cols[HIGH];
-	hcols[BORD] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, DMedblue);
+	blue = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, DMedblue);
+	paleblue = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, DGreyblue);
+
+	hcols[BORD] = blue;
 	hcols[TEXT] = hcols[BORD];
 	hcols[HTEXT] = hcols[TEXT];
 
 	plumbcolor = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x006600FF);
 	execcolor = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xAA0000FF);
 
+	if(!blue || !palegrey || !paleblue || !plumbcolor || !execcolor)
+		sysfatal("alloc colors: %r");
 	draw(screen, screen->r, cols[BACK], nil, ZP);
 	geom();
 	loop();
@@ -364,6 +374,16 @@ geom(void)
 {
 	Point p;
 	Rectangle r;
+
+	if(!acmecolors){
+		if(_windowhasfocus){
+			cols[TEXT] = cols[HTEXT] = display->black;
+			hcols[TEXT] = hcols[HTEXT] = blue;
+		}else{
+			cols[TEXT] = cols[HTEXT] = palegrey;
+			hcols[TEXT] = hcols[HTEXT] = paleblue;
+		}
+	}
 
 	r = screen->r;
 	r.min.y++;
@@ -1535,7 +1555,7 @@ scrdraw(void)
 {
 	Rectangle r, r1, r2;
 	static Image *scrx;
-	
+
 	r = scrollr;
 	r.min.x += 1;	/* border between margin and bar */
 	r1 = r;
blob - d1fc5e1cc2fc57acb364b15eaa2104cc174e38e0
blob + d5dbef2ca298c439e46cf7e39fe3b903fcbc18a8
--- src/cmd/9term/win.c
+++ src/cmd/9term/win.c
@@ -572,7 +572,7 @@ sendtype(int fd0)
 	while(ntypebreak){
 		for(i=0; i<ntypeb; i++)
 			if(typing[i]=='\n' || typing[i]==0x04){
-				n = i + (typing[i] == '\n');
+				n = i+1;
 				i++;
 				if(write(fd0, typing, n) != n)
 					error("sending to program");
blob - 41800b3f0f4c9e62f49a87576f3a7258ed761222
blob + 8d4f61c6303dbb042ea9a4cc9ae57658df54efba
--- src/libdraw/x11-init.c
+++ src/libdraw/x11-init.c
@@ -188,6 +188,7 @@ xattach(char *label)
 	XWindow xrootwin;
 	XWindowAttributes wattr;
 	XWMHints hint;
+	Atom atoms[2];
 
 	/*
 	if(XInitThreads() == 0){
@@ -334,14 +335,6 @@ xattach(char *label)
 		CWBackPixel|CWBorderPixel|CWColormap,
 		&attr		/* attributes (the above aren't?!) */
 	);
-
-	if(!XGetWindowAttributes(_x.display, _x.drawable, &wattr))
-		fprint(2, "XGetWindowAttributes failed\n");
-	else if(wattr.width && wattr.height){
-		r.max.x = wattr.width;
-		r.max.y = wattr.height;
-		if(0) fprint(2, "new rect %dx%d\n", r.max.x, r.max.y);
-	}
 
 	/*
 	 * Label and other properties required by ICCCCM.
@@ -383,7 +376,41 @@ xattach(char *label)
 		&classhint	/* XA_WM_CLASSHINTS */
 	);
 	XFlush(_x.display);
+
+	/*
+	 * Look up clipboard atom.
+	 */
+	_x.clipboard = XInternAtom(_x.display, "CLIPBOARD", False);
+	_x.utf8string = XInternAtom(_x.display, "UTF8_STRING", False);
+	_x.targets = XInternAtom(_x.display, "TARGETS", False);
+	_x.text = XInternAtom(_x.display, "TEXT", False);
+	_x.compoundtext = XInternAtom(_x.display, "COMPOUND_TEXT", False);
+	_x.takefocus = XInternAtom(_x.display, "WM_TAKE_FOCUS", False);
+	_x.losefocus = XInternAtom(_x.display, "_9WM_LOSE_FOCUS", False);
+	_x.wmprotos = XInternAtom(_x.display, "WM_PROTOCOLS", False);
+
+	atoms[0] = _x.takefocus;
+	atoms[1] = _x.losefocus;
+	XChangeProperty(_x.display, _x.drawable, _x.wmprotos, XA_ATOM, 32,
+		PropModeReplace, (uchar*)atoms, 2);
+
+	/*
+	 * Put the window on the screen, check to see what size we actually got.
+	 */
+	XMapWindow(_x.display, _x.drawable);
+	XSync(_x.display, False);
 
+	if(!XGetWindowAttributes(_x.display, _x.drawable, &wattr))
+		fprint(2, "XGetWindowAttributes failed\n");
+	else if(wattr.width && wattr.height){
+		if(wattr.width != Dx(r) || wattr.height != Dy(r)){
+			r.max.x = wattr.width;
+			r.max.y = wattr.height;
+		}
+			fprint(2, "new rect %dx%d\n", r.max.x, r.max.y);
+	}else
+		fprint(2, "bad attrs\n");
+
 	/*
 	 * Allocate our local backing store.
 	 */
@@ -408,23 +435,8 @@ xattach(char *label)
 	_x.gczero0	= xgc(pmid, -1, -1);
 	_x.gcreplsrc0	= xgc(pmid, FillTiled, -1);
 	XFreePixmap(_x.display, pmid);
-
-	/*
-	 * Put the window on the screen.
-	 */
-	XMapWindow(_x.display, _x.drawable);
-	XFlush(_x.display);
 
 	/*
-	 * Look up clipboard atom.
-	 */
-	_x.clipboard = XInternAtom(_x.display, "CLIPBOARD", False);
-	_x.utf8string = XInternAtom(_x.display, "UTF8_STRING", False);
-	_x.targets = XInternAtom(_x.display, "TARGETS", False);
-	_x.text = XInternAtom(_x.display, "TEXT", False);
-	_x.compoundtext = XInternAtom(_x.display, "COMPOUND_TEXT", False);
-
-	/*
 	 * Lots of display connections for various procs.
 	 */
 	_x.kbdcon	= XOpenDisplay(NULL);
blob - 1e84b92638553d829c764a46a9a95480f6c1189a
blob + efd8dd7dddc2a9197a079cd03d503ec84fc45996
--- src/libdraw/x11-memdraw.h
+++ src/libdraw/x11-memdraw.h
@@ -69,6 +69,9 @@ struct Xprivate {
 	Atom		targets;
 	Atom		text;
 	Atom		compoundtext;
+	Atom		takefocus;
+	Atom		losefocus;
+	Atom		wmprotos;
 	uint		putsnarf;
 	uint		assertsnarf;
 	int		destroyed;
blob - 93f7ecf4f4d678158ed3d7e3aea34e0fded092d0
blob + d2d0126bf744803db9ac75cf7ff25deaeca83766
--- src/libdraw/x11-mouse.c
+++ src/libdraw/x11-mouse.c
@@ -8,6 +8,9 @@
 #include <memdraw.h>
 #include "x11-memdraw.h"
 
+int _windowhasfocus = 1;
+int _wantfocuschanges;
+
 void
 moveto(Mousectl *m, Point pt)
 {
@@ -48,6 +51,7 @@ void
 _ioproc(void *arg)
 {
 	int fd, one;
+	Atom a;
 	ulong mask;
 	Mouse m;
 	Mousectl *mc;
@@ -99,6 +103,20 @@ _ioproc(void *arg)
 			 */
 			mc->m = m;
 			break;
+		case ClientMessage:
+			if(xevent.xclient.message_type == _x.wmprotos){
+				a = xevent.xclient.data.l[0];
+				if(_wantfocuschanges && a == _x.takefocus){
+					_windowhasfocus = 1;
+					_x.newscreenr = _x.screenr;
+					nbsend(mc->resizec, &one);
+				}else if(_wantfocuschanges && a == _x.losefocus){
+					_windowhasfocus = 0;
+					_x.newscreenr = _x.screenr;
+					nbsend(mc->resizec, &one);
+				}
+			}
+			break;
 		}
 	}
 }
@@ -124,3 +142,25 @@ setcursor(Mousectl *mc, Cursor *c)
 	_xsetcursor(c);
 }
 
+void
+bouncemouse(Mouse *m)
+{
+	XButtonEvent e;
+
+	e.type = ButtonPress;
+	e.window = DefaultRootWindow(_x.display);
+	e.state = 0;
+	e.button = 0;
+	if(m->buttons&1)
+		e.button = 1;
+	else if(m->buttons&2)
+		e.button = 2;
+	else if(m->buttons&4)
+		e.button = 3;
+	e.x = m->xy.x;
+	e.y = m->xy.y;
+#undef time
+	e.time = CurrentTime;
+	XSendEvent(_x.display, e.window, True, ButtonPressMask, (XEvent*)&e);
+	XFlush(_x.display);
+}