Commit Diff


commit - f73497bbafecbedd367eaab16aaf37c701672be0
commit + ad8d54238b4bafc0306bc4204cdd09e1bfa1fcb7
blob - 5d1f014869800cbc75226e1c25e44dc949374378
blob + 3c31b6169fd5cfc808d55faf9be8238bee687e6a
--- man/man1/rio.1
+++ man/man1/rio.1
@@ -29,6 +29,12 @@ rio \- rio-like Window Manager for X
 |
 .B restart
 ]
+.PP
+.B xshove
+[
+.I name
+.I rectangle
+]
 .SH DESCRIPTION
 .if t .ds 85 8\(12
 .if n .ds 85 8-1/2
@@ -187,6 +193,34 @@ option,
 clicking button 2 brings up a menu to select a virtual screen to view.
 Scrolling the mouse wheel while the cursor points at the background
 will cycle through the virtual screens.
+.PP
+.I Xshove
+moves or resizes every window whose X11 class or instance strings contain
+.IR name .
+The 
+.I rectangle
+argument can be
+\fIwidth\^\^\fLx\fI\^\^height\fR,
+\fIwidth\^\^\fLx\fI\^\^height\^\^\fL@\fI\^\^xmin\fL,\fIxmax\fR,
+\fL'\fIxmin ymin xmax ymax\fL'\fR,
+\fRor
+\fIxmin\fL,\fIymin\fL,\fIxmax\fL,\fIymax\fR.
+A leading 
+.B +
+or
+.B -
+causes the rectangle to be interpreted as a delta:
+.L +10,0
+nudges a window to the right, while
+.L +100x100
+grows a window.
+With no arguments,
+.I xshove
+lists all the current X windows.
+.I Xshove
+is not specific to 
+.I rio
+and can be used with other window managers.
 .SH BUGS
 In
 Plan 9's
blob - 1b1c7fa5c87b75bfeabe8632cfa4a448b7324189
blob + 180eada41b49468bcc8407a6d09e97678fa07321
--- src/cmd/rio/xshove.c
+++ src/cmd/rio/xshove.c
@@ -41,16 +41,13 @@ int nw;
 
 void getinfo(void);
 void listwindows(void);
-int parsewinsize(char*, Rectangle*, int*);
+int parsewinsize(char*, Rectangle*, int*, int*, int*);
 void shove(char*, char*);
 
 void
 usage(void)
 {
-	fprint(2, "usage: xshove window rectangle\n"
-	          "   or  xshove\n"
-	          "window can be a window ID or a program name\n"
-	          "rectangle is a p9p window spec (see intro(1))\n");
+	fprint(2, "usage: xshove [window rectangle]\n");
 	exits("usage");
 }
 
@@ -183,12 +180,19 @@ void
 shove(char *name, char *geom)
 {
 	int i;
-	int havemin;
+	int isdelta, havemin, havesize;
+	int old, new;
 	Rectangle r;
 
-	if(parsewinsize(geom, &r, &havemin) < 0)
+	if(parsewinsize(geom, &r, &isdelta, &havemin, &havesize) < 0)
 		sysfatal("bad window spec: %s", name);
 
+	old = 0;
+	new = 1;
+	if(isdelta){
+		old = 1;
+		new = isdelta;
+	}
 	for(i=0; i<nw; i++){
 		Win *ww = &w[i];
 		if(ww->instance && strstr(ww->instance, name)
@@ -197,14 +201,21 @@ shove(char *name, char *geom)
 			XWindowChanges e;
 
 			memset(&e, 0, sizeof e);
-			e.width = Dx(r);
-			e.height = Dy(r);
-			value_mask = CWWidth | CWHeight;
 			if(havemin){
-				e.x = r.min.x;
-				e.y = r.min.y;
-				value_mask |= CWX | CWY;
+				e.x = old*ww->x + new*r.min.x;
+				e.y = old*ww->y + new*r.min.y;
+			}else{
+				e.x = ww->x;
+				e.y = ww->y;
 			}
+			if(havesize){
+				e.width = old*ww->dx + new*Dx(r);
+				e.height = old*ww->dy + new*Dy(r);
+			}else{
+				e.width = ww->dx;
+				e.height = ww->dy;
+			}
+			value_mask = CWX | CWY | CWWidth | CWHeight;
 			XConfigureWindow(dpy, ww->xw, value_mask, &e);
 			XFlush(dpy);
 		}
@@ -212,13 +223,22 @@ shove(char *name, char *geom)
 }
 
 int
-parsewinsize(char *s, Rectangle *r, int *havemin)
+parsewinsize(char *s, Rectangle *r, int *isdelta, int *havemin, int *havesize)
 {
 	char c, *os;
 	int i, j, k, l;
 
 	os = s;
+	if(*s == '-'){
+		s++;
+		*isdelta = -1;
+	}else if(*s == '+'){
+		s++;
+		*isdelta = 1;
+	}else
+		*isdelta = 0;
 	*havemin = 0;
+	*havesize = 0;
 	memset(r, 0, sizeof *r);
 	if(!isdigit((uchar)*s))
 		goto oops;
@@ -230,6 +250,7 @@ parsewinsize(char *s, Rectangle *r, int *havemin)
 		j = strtol(s, &s, 0);
 		r->max.x = i;
 		r->max.y = j;
+		*havesize = 1;
 		if(*s == 0)
 			return 0;
 		if(*s != '@')
@@ -251,6 +272,7 @@ parsewinsize(char *s, Rectangle *r, int *havemin)
 		r->max.x += i;
 		r->min.y += j;
 		r->max.y += j;
+		*havesize = 1;
 		*havemin = 1;
 		return 0;
 	}
@@ -262,6 +284,12 @@ parsewinsize(char *s, Rectangle *r, int *havemin)
 	if(!isdigit((uchar)*s))
 		goto oops;
 	j = strtol(s, &s, 0);
+	if(*s == 0){
+		r->min.x = i;
+		r->min.y = j;
+		*havemin = 1;
+		return 0;
+	}
 	if(*s != c)
 		goto oops;
 	s++;
@@ -281,6 +309,7 @@ parsewinsize(char *s, Rectangle *r, int *havemin)
 	r->max.x = k;
 	r->max.y = l;
 	*havemin = 1;
+	*havesize = 1;
 	return 0;
 
 oops: