This is a patch I find very useful. It is a pitty it adds lines of
code. This is what it does:

1. If you move a tiled window more than the SPAN value it becomes
floating. i. e. you can move tiled windows.
2. With MOD+Button2 over a floating window it becomes tiled and zoomed.
3. When a window is being moved, the pointer is wrapped to the nearest corner.
4. Offscreen windows are moved to be fully viewed when the pointer
enters in the window, they come back to their offscreen position when
the pointer goes out of them.

I find 1 and 2 very convenient, and if somebody is interested I could
release a patch with only those features. 4 needs some polishment, but
I like the idea and find it very useful. 3 is a help to move windows
offscreen, so I quickly move them to the screen border where only one
of their borders is viewed, and is also very easy to move them to the
screen corners, where they are more accesible. Now floating windows
doesn't get in my way, but they are there when I need them.
Do you have any comments/suggestions? I think this feature would be
much more usable with different colors for offscreen windows, but...
is it the needed complexity well worth?

Have a nice weekend,


-- 


- yiyus || JGL .
diff -up dwm-4.4/client.c dwm-4.4-offscreen/client.c
--- dwm-4.4/client.c	2007-08-23 18:11:41.000000000 +0200
+++ dwm-4.4-offscreen/client.c	2007-08-24 14:22:53.000000000 +0200
@@ -290,6 +290,8 @@ resize(Client *c, int x, int y, int w, i
 		c->h = wc.height = h;
 		wc.border_width = c->border;
 		XConfigureWindow(dpy, c->win, CWX | CWY | CWWidth | CWHeight | CWBorderWidth, &wc);
+		c->offx = c->x;
+		c->offy = c->y;
 		configure(c);
 		XSync(dpy, False);
 	}
diff -up dwm-4.4/dwm.h dwm-4.4-offscreen/dwm.h
--- dwm-4.4/dwm.h	2007-08-23 18:11:41.000000000 +0200
+++ dwm-4.4-offscreen/dwm.h	2007-08-24 13:30:37.000000000 +0200
@@ -46,6 +46,7 @@ struct Client {
 	char name[256];
 	int x, y, w, h;
 	int rx, ry, rw, rh; /* revert geometry */
+	int offx, offy;
 	int basew, baseh, incw, inch, maxw, maxh, minw, minh;
 	int minax, maxax, minay, maxay;
 	long flags; 
diff -up dwm-4.4/event.c dwm-4.4-offscreen/event.c
--- dwm-4.4/event.c	2007-08-23 18:11:41.000000000 +0200
+++ dwm-4.4-offscreen/event.c	2007-08-24 15:30:31.000000000 +0200
@@ -7,6 +7,8 @@
 
 /* static */
 
+static Client *osc;	/* offscreen client */
+
 typedef struct {
 	unsigned long mod;
 	KeySym keysym;
@@ -27,7 +29,7 @@ getclient(Window w) {
 
 static void
 movemouse(Client *c) {
-	int x1, y1, ocx, ocy, di, nx, ny;
+	int x1, y1, ocx, ocy, di, nx, ny, px, py;
 	unsigned int dui;
 	Window dummy;
 	XEvent ev;
@@ -39,6 +41,10 @@ movemouse(Client *c) {
 		return;
 	c->ismax = False;
 	XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui);
+	px = x1 - c->x > c->w / 2 ? c->w : -1;
+	py = y1 - c->y > c->h / 2 ? c->h : -1;
+	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, px, py);
+	XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui);
 	for(;;) {
 		XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev);
 		switch (ev.type) {
@@ -62,7 +68,12 @@ movemouse(Client *c) {
 				ny = way;
 			else if(abs((way + wah) - (ny + c->h + 2 * c->border)) < SNAP)
 				ny = way + wah - c->h - 2 * c->border;
-			resize(c, nx, ny, c->w, c->h, False);
+			if(!isfloating() && (abs(nx - c->x) > SNAP || abs(ny -c->y) > SNAP)) {
+				c->isfloating = True;
+				arrange();
+			}
+			if(isfloating() || c->isfloating)
+				resize(c, nx, ny, c->w, c->h, False);
 			break;
 		}
 	}
@@ -70,8 +81,7 @@ movemouse(Client *c) {
 
 static void
 resizemouse(Client *c) {
-	int ocx, ocy;
-	int nw, nh;
+	int ocx, ocy, nw, nh;
 	XEvent ev;
 
 	ocx = c->x;
@@ -140,12 +150,15 @@ buttonpress(XEvent *e) {
 		focus(c);
 		if(CLEANMASK(ev->state) != MODKEY)
 			return;
-		if(ev->button == Button1 && (isfloating() || c->isfloating)) {
+		if(ev->button == Button1) {
 			restack();
 			movemouse(c);
 		}
-		else if(ev->button == Button2)
+		else if(ev->button == Button2) {
+			if(sel->isfloating)
+				sel->isfloating = False;
 			zoom(NULL);
+		}
 		else if(ev->button == Button3
 		&& (isfloating() || c->isfloating) && !c->isfixed)
 		{
@@ -231,8 +244,21 @@ enternotify(XEvent *e) {
 
 	if(ev->mode != NotifyNormal || ev->detail == NotifyInferior)
 		return;
-	if((c = getclient(ev->window)))
+	if(c = getclient(ev->window)) {
 		focus(c);
+		if(osc && c != osc) {
+			osc->x = osc->offx;
+			osc->y = osc->offy;
+			XMoveWindow(dpy, osc->win, osc->x, osc->y);
+			osc = NULL;
+		}
+		if(c->x < 0 || c->y < 0 || c->x + c->w > sw || c->y + c->h > sh) {
+			c->x = c->x < 0 ? 0 : (c->x + c->w > sw ? sw - c->w - 2 * c->border : c->x);
+			c->y = c->y < 0 ? 0 : (c->y + c->h > sh ? sh - c->h - 2 * c->border : c->y);
+			XMoveWindow(dpy, c->win, c->x, c->y);
+			osc = c;
+		}
+	}	
 	else if(ev->window == root) {
 		selscreen = True;
 		focus(NULL);
@@ -270,6 +296,7 @@ keypress(XEvent *e) {
 static void
 leavenotify(XEvent *e) {
 	XCrossingEvent *ev = &e->xcrossing;
+	Client *c;
 
 	if((ev->window == root) && !ev->same_screen) {
 		selscreen = False;

Reply via email to