Browse Source

implemented restack behavior (floats are on top in tiled mode)

Anselm R.Garbe 19 years ago
parent
commit
d4b7a9a373
6 changed files with 81 additions and 34 deletions
  1. 8 18
      client.c
  2. 2 2
      dwm.1
  3. 2 1
      dwm.h
  4. 6 3
      event.c
  5. 54 10
      tag.c
  6. 9 0
      util.c

+ 8 - 18
client.c

@@ -59,8 +59,6 @@ focus(Client *c)
 		drawtitle(old);
 		drawtitle(old);
 	drawtitle(c);
 	drawtitle(c);
 	XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
 	XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
-	XSync(dpy, False);
-	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
 }
 }
 
 
 void
 void
@@ -77,8 +75,8 @@ focusnext(Arg *arg)
 	if(!(c = getnext(sel->next)))
 	if(!(c = getnext(sel->next)))
 		c = getnext(clients);
 		c = getnext(clients);
 	if(c) {
 	if(c) {
-		higher(c);
 		focus(c);
 		focus(c);
+		restack();
 	}
 	}
 }
 }
 
 
@@ -98,8 +96,8 @@ focusprev(Arg *arg)
 		c = getprev(c);
 		c = getprev(c);
 	}
 	}
 	if(c) {
 	if(c) {
-		higher(c);
 		focus(c);
 		focus(c);
+		restack();
 	}
 	}
 }
 }
 
 
@@ -180,13 +178,6 @@ gravitate(Client *c, Bool invert)
 	c->y += dy;
 	c->y += dy;
 }
 }
 
 
-void
-higher(Client *c)
-{
-	XRaiseWindow(dpy, c->win);
-	XRaiseWindow(dpy, c->title);
-}
-
 void
 void
 killclient(Arg *arg)
 killclient(Arg *arg)
 {
 {
@@ -271,13 +262,12 @@ manage(Window w, XWindowAttributes *wa)
 			|| (c->maxw && c->minw &&
 			|| (c->maxw && c->minw &&
 				c->maxw == c->minw && c->maxh == c->minh);
 				c->maxw == c->minw && c->maxh == c->minh);
 	settitle(c);
 	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))
 	if(isvisible(c))
 		focus(c);
 		focus(c);
+	arrange(NULL);
 }
 }
 
 
 void
 void
@@ -410,7 +400,7 @@ togglemax(Arg *arg)
 		sel->w = sw - 2;
 		sel->w = sw - 2;
 		sel->h = sh - 2 - bh;
 		sel->h = sh - 2 - bh;
 
 
-		higher(sel);
+		restack();
 		resize(sel, arrange == dofloat, TopLeft);
 		resize(sel, arrange == dofloat, TopLeft);
 
 
 		sel->x = ox;
 		sel->x = ox;
@@ -446,9 +436,9 @@ unmanage(Client *c)
 	XSync(dpy, False);
 	XSync(dpy, False);
 	XSetErrorHandler(xerror);
 	XSetErrorHandler(xerror);
 	XUngrabServer(dpy);
 	XUngrabServer(dpy);
-	arrange(NULL);
 	if(sel)
 	if(sel)
 		focus(sel);
 		focus(sel);
+	arrange(NULL);
 }
 }
 
 
 void
 void
@@ -474,6 +464,6 @@ zoom(Arg *arg)
 	clients->prev = sel;
 	clients->prev = sel;
 	sel->next = clients;
 	sel->next = clients;
 	clients = sel;
 	clients = sel;
-	arrange(NULL);
 	focus(sel);
 	focus(sel);
+	arrange(NULL);
 }
 }

+ 2 - 2
dwm.1

@@ -36,11 +36,11 @@ prints version information to standard output, then exits.
 .B Standard input
 .B Standard input
 is read and displayed in the status text area.
 is read and displayed in the status text area.
 .TP
 .TP
-.B Button[1,3]
+.B Button[1,2]
 click on a tag label focuses that
 click on a tag label focuses that
 .B tag.
 .B tag.
 .TP
 .TP
-.B Button2
+.B Button3
 click on a tag label toggles that
 click on a tag label toggles that
 .B tag.
 .B tag.
 .SS Keyboard commands
 .SS Keyboard commands

+ 2 - 1
dwm.h

@@ -89,7 +89,6 @@ extern void focusprev(Arg *arg);
 extern Client *getclient(Window w);
 extern Client *getclient(Window w);
 extern Client *getctitle(Window w);
 extern Client *getctitle(Window w);
 extern void gravitate(Client *c, Bool invert);
 extern void gravitate(Client *c, Bool invert);
-extern void higher(Client *c);
 extern void killclient(Arg *arg);
 extern void killclient(Arg *arg);
 extern void manage(Window w, XWindowAttributes *wa);
 extern void manage(Window w, XWindowAttributes *wa);
 extern void resize(Client *c, Bool sizehints, Corner sticky);
 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 *getnext(Client *c);
 extern Client *getprev(Client *c);
 extern Client *getprev(Client *c);
 extern void replacetag(Arg *arg);
 extern void replacetag(Arg *arg);
+extern void restack();
 extern void settags(Client *c);
 extern void settags(Client *c);
 extern void togglemode(Arg *arg);
 extern void togglemode(Arg *arg);
 extern void view(Arg *arg);
 extern void view(Arg *arg);
@@ -133,4 +133,5 @@ extern void toggleview(Arg *arg);
 /* util.c */
 /* util.c */
 extern void *emallocz(unsigned int size);
 extern void *emallocz(unsigned int size);
 extern void eprint(const char *errstr, ...);
 extern void eprint(const char *errstr, ...);
+extern void *erealloc(void *ptr, unsigned int size);
 extern void spawn(Arg *arg);
 extern void spawn(Arg *arg);

+ 6 - 3
event.c

@@ -118,21 +118,24 @@ buttonpress(XEvent *e)
 		}
 		}
 	}
 	}
 	else if((c = getclient(ev->window))) {
 	else if((c = getclient(ev->window))) {
-		higher(c);
 		focus(c);
 		focus(c);
 		switch(ev->button) {
 		switch(ev->button) {
 		default:
 		default:
 			break;
 			break;
 		case Button1:
 		case Button1:
-			if(!c->ismax && (arrange == dofloat || c->isfloat))
+			if(!c->ismax && (arrange == dofloat || c->isfloat)) {
+				restack(c);
 				movemouse(c);
 				movemouse(c);
+			}
 			break;
 			break;
 		case Button2:
 		case Button2:
 			zoom(NULL);
 			zoom(NULL);
 			break;
 			break;
 		case Button3:
 		case Button3:
-			if(!c->ismax && (arrange == dofloat || c->isfloat))
+			if(!c->ismax && (arrange == dofloat || c->isfloat)) {
+				restack(c);
 				resizemouse(c);
 				resizemouse(c);
+			}
 			break;
 			break;
 		}
 		}
 	}
 	}

+ 54 - 10
tag.c

@@ -58,18 +58,17 @@ dofloat(Arg *arg)
 			ban(c);
 			ban(c);
 	}
 	}
 	if((sel = getnext(clients))) {
 	if((sel = getnext(clients))) {
-		higher(sel);
 		focus(sel);
 		focus(sel);
+		restack();
 	}
 	}
 	else
 	else
 		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
 		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
-	drawall();
 }
 }
 
 
 void
 void
 dotile(Arg *arg)
 dotile(Arg *arg)
 {
 {
-	int n, i, w, h;
+	int h, i, n, w;
 	Client *c;
 	Client *c;
 
 
 	w = sw - mw;
 	w = sw - mw;
@@ -86,7 +85,6 @@ dotile(Arg *arg)
 		c->ismax = False;
 		c->ismax = False;
 		if(isvisible(c)) {
 		if(isvisible(c)) {
 			if(c->isfloat) {
 			if(c->isfloat) {
-				higher(c);
 				resize(c, True, TopLeft);
 				resize(c, True, TopLeft);
 				continue;
 				continue;
 			}
 			}
@@ -123,13 +121,11 @@ dotile(Arg *arg)
 		else
 		else
 			ban(c);
 			ban(c);
 	}
 	}
-	if((sel = getnext(clients))) {
-		higher(sel);
+	if((sel = getnext(clients)))
 		focus(sel);
 		focus(sel);
-	}
 	else
 	else
 		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
 		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
-	drawall();
+	restack();
 }
 }
 
 
 Client *
 Client *
@@ -199,6 +195,56 @@ replacetag(Arg *arg)
 	appendtag(arg);
 	appendtag(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
 void
 settags(Client *c)
 settags(Client *c)
 {
 {
@@ -248,7 +294,6 @@ view(Arg *arg)
 		seltag[i] = False;
 		seltag[i] = False;
 	seltag[arg->i] = True;
 	seltag[arg->i] = True;
 	arrange(NULL);
 	arrange(NULL);
-	drawall();
 }
 }
 
 
 void
 void
@@ -261,5 +306,4 @@ toggleview(Arg *arg)
 	if(i == ntags)
 	if(i == ntags)
 		seltag[arg->i] = True; /* cannot toggle last view */
 		seltag[arg->i] = True; /* cannot toggle last view */
 	arrange(NULL);
 	arrange(NULL);
-	drawall();
 }
 }

+ 9 - 0
util.c

@@ -40,6 +40,15 @@ eprint(const char *errstr, ...)
 	exit(EXIT_FAILURE);
 	exit(EXIT_FAILURE);
 }
 }
 
 
+void *
+erealloc(void *ptr, unsigned int size)
+{
+	void *res = realloc(ptr, size);
+	if(!res)
+		bad_malloc(size);
+	return res;
+}
+
 void
 void
 spawn(Arg *arg)
 spawn(Arg *arg)
 {
 {