about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--client.c26
-rw-r--r--dwm.14
-rw-r--r--dwm.h3
-rw-r--r--event.c9
-rw-r--r--tag.c64
-rw-r--r--util.c9
6 files changed, 81 insertions, 34 deletions
diff --git a/client.c b/client.c
index 5be438e..ecfd8f0 100644
--- a/client.c
+++ b/client.c
@@ -59,8 +59,6 @@ focus(Client *c)
 		drawtitle(old);
 	drawtitle(c);
 	XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
-	XSync(dpy, False);
-	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
 }
 
 void
@@ -77,8 +75,8 @@ focusnext(Arg *arg)
 	if(!(c = getnext(sel->next)))
 		c = getnext(clients);
 	if(c) {
-		higher(c);
 		focus(c);
+		restack();
 	}
 }
 
@@ -98,8 +96,8 @@ focusprev(Arg *arg)
 		c = getprev(c);
 	}
 	if(c) {
-		higher(c);
 		focus(c);
+		restack();
 	}
 }
 
@@ -181,13 +179,6 @@ gravitate(Client *c, Bool invert)
 }
 
 void
-higher(Client *c)
-{
-	XRaiseWindow(dpy, c->win);
-	XRaiseWindow(dpy, c->title);
-}
-
-void
 killclient(Arg *arg)
 {
 	if(!sel)
@@ -271,13 +262,12 @@ manage(Window w, XWindowAttributes *wa)
 			|| (c->maxw && c->minw &&
 				c->maxw == c->minw && c->maxh == c->minh);
 	settitle(c);
-	arrange(NULL);
 
-	/* mapping the window now prevents flicker */
-	XMapRaised(dpy, c->win);
-	XMapRaised(dpy, c->title);
+	XMapWindow(dpy, c->win);
+	XMapWindow(dpy, c->title);
 	if(isvisible(c))
 		focus(c);
+	arrange(NULL);
 }
 
 void
@@ -410,7 +400,7 @@ togglemax(Arg *arg)
 		sel->w = sw - 2;
 		sel->h = sh - 2 - bh;
 
-		higher(sel);
+		restack();
 		resize(sel, arrange == dofloat, TopLeft);
 
 		sel->x = ox;
@@ -446,9 +436,9 @@ unmanage(Client *c)
 	XSync(dpy, False);
 	XSetErrorHandler(xerror);
 	XUngrabServer(dpy);
-	arrange(NULL);
 	if(sel)
 		focus(sel);
+	arrange(NULL);
 }
 
 void
@@ -474,6 +464,6 @@ zoom(Arg *arg)
 	clients->prev = sel;
 	sel->next = clients;
 	clients = sel;
-	arrange(NULL);
 	focus(sel);
+	arrange(NULL);
 }
diff --git a/dwm.1 b/dwm.1
index 38c50b5..9f0705b 100644
--- a/dwm.1
+++ b/dwm.1
@@ -36,11 +36,11 @@ prints version information to standard output, then exits.
 .B Standard input
 is read and displayed in the status text area.
 .TP
-.B Button[1,3]
+.B Button[1,2]
 click on a tag label focuses that
 .B tag.
 .TP
-.B Button2
+.B Button3
 click on a tag label toggles that
 .B tag.
 .SS Keyboard commands
diff --git a/dwm.h b/dwm.h
index f9b06d2..c13179f 100644
--- a/dwm.h
+++ b/dwm.h
@@ -89,7 +89,6 @@ extern void focusprev(Arg *arg);
 extern Client *getclient(Window w);
 extern Client *getctitle(Window w);
 extern void gravitate(Client *c, Bool invert);
-extern void higher(Client *c);
 extern void killclient(Arg *arg);
 extern void manage(Window w, XWindowAttributes *wa);
 extern void resize(Client *c, Bool sizehints, Corner sticky);
@@ -125,6 +124,7 @@ extern Bool isvisible(Client *c);
 extern Client *getnext(Client *c);
 extern Client *getprev(Client *c);
 extern void replacetag(Arg *arg);
+extern void restack();
 extern void settags(Client *c);
 extern void togglemode(Arg *arg);
 extern void view(Arg *arg);
@@ -133,4 +133,5 @@ extern void toggleview(Arg *arg);
 /* util.c */
 extern void *emallocz(unsigned int size);
 extern void eprint(const char *errstr, ...);
+extern void *erealloc(void *ptr, unsigned int size);
 extern void spawn(Arg *arg);
diff --git a/event.c b/event.c
index 1a8de56..e5ca166 100644
--- a/event.c
+++ b/event.c
@@ -118,21 +118,24 @@ buttonpress(XEvent *e)
 		}
 	}
 	else if((c = getclient(ev->window))) {
-		higher(c);
 		focus(c);
 		switch(ev->button) {
 		default:
 			break;
 		case Button1:
-			if(!c->ismax && (arrange == dofloat || c->isfloat))
+			if(!c->ismax && (arrange == dofloat || c->isfloat)) {
+				restack(c);
 				movemouse(c);
+			}
 			break;
 		case Button2:
 			zoom(NULL);
 			break;
 		case Button3:
-			if(!c->ismax && (arrange == dofloat || c->isfloat))
+			if(!c->ismax && (arrange == dofloat || c->isfloat)) {
+				restack(c);
 				resizemouse(c);
+			}
 			break;
 		}
 	}
diff --git a/tag.c b/tag.c
index d27d91a..01979d5 100644
--- a/tag.c
+++ b/tag.c
@@ -58,18 +58,17 @@ dofloat(Arg *arg)
 			ban(c);
 	}
 	if((sel = getnext(clients))) {
-		higher(sel);
 		focus(sel);
+		restack();
 	}
 	else
 		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
-	drawall();
 }
 
 void
 dotile(Arg *arg)
 {
-	int n, i, w, h;
+	int h, i, n, w;
 	Client *c;
 
 	w = sw - mw;
@@ -86,7 +85,6 @@ dotile(Arg *arg)
 		c->ismax = False;
 		if(isvisible(c)) {
 			if(c->isfloat) {
-				higher(c);
 				resize(c, True, TopLeft);
 				continue;
 			}
@@ -123,13 +121,11 @@ dotile(Arg *arg)
 		else
 			ban(c);
 	}
-	if((sel = getnext(clients))) {
-		higher(sel);
+	if((sel = getnext(clients)))
 		focus(sel);
-	}
 	else
 		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
-	drawall();
+	restack();
 }
 
 Client *
@@ -200,6 +196,56 @@ replacetag(Arg *arg)
 }
 
 void
+restack()
+{
+	static unsigned int nwins = 0;
+	static Window *wins = NULL;
+	unsigned int f, fi, m, mi, n;
+	Client *c;
+	XEvent ev;
+
+	for(f = 0, m = 0, c = clients; c; c = c->next)
+		if(isvisible(c)) {
+			if(c->isfloat || arrange == dofloat)
+				f++;
+			else
+				m++;
+		}
+
+	n = 2 * (f + m);
+	if(nwins < n) {
+		nwins = n;
+		wins = erealloc(wins, nwins * sizeof(Window));
+	}
+
+	fi = 0;
+	mi = 2 * f;
+	if(sel->isfloat || arrange == dofloat) {
+		wins[fi++] = sel->title;
+		wins[fi++] = sel->win;
+	}
+	else {
+		wins[mi++] = sel->title;
+		wins[mi++] = sel->win;
+	}
+	for(c = clients; c; c = c->next)
+		if(isvisible(c) && c != sel) {
+			if(c->isfloat || arrange == dofloat) {
+				wins[fi++] = c->title;
+				wins[fi++] = c->win;
+			}
+			else {
+				wins[mi++] = c->title;
+				wins[mi++] = c->win;
+			}
+		}
+	XRestackWindows(dpy, wins, n);
+	drawall();
+	XSync(dpy, False);
+	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
+}
+
+void
 settags(Client *c)
 {
 	char classinst[256];
@@ -248,7 +294,6 @@ view(Arg *arg)
 		seltag[i] = False;
 	seltag[arg->i] = True;
 	arrange(NULL);
-	drawall();
 }
 
 void
@@ -261,5 +306,4 @@ toggleview(Arg *arg)
 	if(i == ntags)
 		seltag[arg->i] = True; /* cannot toggle last view */
 	arrange(NULL);
-	drawall();
 }
diff --git a/util.c b/util.c
index 4cc748f..2414b39 100644
--- a/util.c
+++ b/util.c
@@ -40,6 +40,15 @@ eprint(const char *errstr, ...)
 	exit(EXIT_FAILURE);
 }
 
+void *
+erealloc(void *ptr, unsigned int size)
+{
+	void *res = realloc(ptr, size);
+	if(!res)
+		bad_malloc(size);
+	return res;
+}
+
 void
 spawn(Arg *arg)
 {