X-Git-Url: https://git.xinqibao.xyz/dwm.git/blobdiff_plain/27b0595af72060d7cc406639b6c53a854f0a3590..86953bd68249662b5d7a9ae6741744ab8bf30aa1:/layout.c

diff --git a/layout.c b/layout.c
index 1e8f113..46e82c2 100644
--- a/layout.c
+++ b/layout.c
@@ -1,96 +1,55 @@
-/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
- * See LICENSE file for license details.
- */
+/* See LICENSE file for copyright and license details. */
 #include "dwm.h"
 #include <stdlib.h>
 
-unsigned int blw = 0;
-Layout *lt = NULL;
-
 /* static */
 
-static unsigned int nlayouts = 0;
-static unsigned int masterw = MASTERWIDTH;
-static unsigned int nmaster = NMASTER;
+typedef struct {
+	const char *symbol;
+	void (*arrange)(void);
+} Layout;
+
+unsigned int blw = 0;
+static Layout *lt = NULL;
 
 static void
-tile(void) {
-	unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th;
+floating(void) { /* default floating layout */
 	Client *c;
 
-	for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
-		n++;
-	/* window geoms */
-	mh = (n > nmaster) ? wah / nmaster : wah / (n > 0 ? n : 1);
-	mw = (n > nmaster) ? (waw * masterw) / 1000 : waw;
-	th = (n > nmaster) ? wah / (n - nmaster) : 0;
-	tw = waw - mw;
-
-	for(i = 0, c = clients; c; c = c->next)
-		if(isvisible(c)) {
-			if(c->isbanned)
-				XMoveWindow(dpy, c->win, c->x, c->y);
-			c->isbanned = False;
-			if(c->isversatile)
-				continue;
-			c->ismax = False;
-			nx = wax;
-			ny = way;
-			if(i < nmaster) {
-				ny += i * mh;
-				nw = mw - 2 * BORDERPX;
-				nh = mh - 2 * BORDERPX;
-			}
-			else {  /* tile window */
-				nx += mw;
-				nw = tw - 2 * BORDERPX;
-				if(th > 2 * BORDERPX) {
-					ny += (i - nmaster) * th;
-					nh = th - 2 * BORDERPX;
-				}
-				else /* fallback if th <= 2 * BORDERPX */
-					nh = wah - 2 * BORDERPX;
-			}
-			resize(c, nx, ny, nw, nh, False);
-			i++;
-		}
-		else {
-			c->isbanned = True;
-			XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
-		}
-	if(!sel || !isvisible(sel)) {
-		for(c = stack; c && !isvisible(c); c = c->snext);
-		focus(c);
-	}
-	restack();
+	for(c = clients; c; c = c->next)
+		if(isvisible(c))
+			resize(c, c->x, c->y, c->w, c->h, True);
 }
 
+static unsigned int nlayouts = 0;
+
 LAYOUTS
 
 /* extern */
 
 void
-focusclient(const char *arg) {
+arrange(void) {
 	Client *c;
-   
-	if(!sel || !arg)
-		return;
-	switch(atoi(arg)) {
-	default:
+
+	for(c = clients; c; c = c->next)
+		if(isvisible(c))
+			unban(c);
+		else
+			ban(c);
+	lt->arrange();
+	focus(NULL);
+	restack();
+}
+
+void
+focusnext(const char *arg) {
+	Client *c;
+
+	if(!sel)
 		return;
-	case 1:
-		for(c = sel->next; c && !isvisible(c); c = c->next);
-		if(!c)
-			for(c = clients; c && !isvisible(c); c = c->next);
-		break;
-	case -1:
-		for(c = sel->prev; c && !isvisible(c); c = c->prev);
-		if(!c) {
-			for(c = clients; c && c->next; c = c->next);
-			for(; c && !isvisible(c); c = c->prev);
-		}
-		break;
-	}
+	for(c = sel->next; c && !isvisible(c); c = c->next);
+	if(!c)
+		for(c = clients; c && !isvisible(c); c = c->next);
 	if(c) {
 		focus(c);
 		restack();
@@ -98,49 +57,47 @@ focusclient(const char *arg) {
 }
 
 void
-incmasterw(const char *arg) {
-	int i;
-	if(lt->arrange != tile)
+focusprev(const char *arg) {
+	Client *c;
+
+	if(!sel)
 		return;
-	if(!arg)
-		masterw = MASTERWIDTH;
-	else {
-		i = atoi(arg);
-		if(waw * (masterw + i) / 1000 >= waw - 2 * BORDERPX
-		|| waw * (masterw + i) / 1000 <= 2 * BORDERPX)
-			return;
-		masterw += i;
+	for(c = sel->prev; c && !isvisible(c); c = c->prev);
+	if(!c) {
+		for(c = clients; c && c->next; c = c->next);
+		for(; c && !isvisible(c); c = c->prev);
+	}
+	if(c) {
+		focus(c);
+		restack();
 	}
-	lt->arrange();
 }
 
-void
-incnmaster(const char *arg) {
-	int i;
+const char *
+getsymbol(void)
+{
+	return lt->symbol;
+}
 
-	if(!arg)
-		nmaster = NMASTER;
-	else {
-		i = atoi(arg);
-		if((lt->arrange != tile) || (nmaster + i < 1)
-		|| (wah / (nmaster + i) <= 2 * BORDERPX))
-			return;
-		nmaster += i;
-	}
-	if(sel)
-		lt->arrange();
-	else
-		drawstatus();
+Bool
+isfloating(void) {
+	return lt->arrange == floating;
+}
+
+Bool
+isarrange(void (*func)())
+{
+	return func == lt->arrange;
 }
 
 void
 initlayouts(void) {
 	unsigned int i, w;
 
-	lt = &layout[0];
-	nlayouts = sizeof layout / sizeof layout[0];
+	lt = &layouts[0];
+	nlayouts = sizeof layouts / sizeof layouts[0];
 	for(blw = i = 0; i < nlayouts; i++) {
-		w = textw(layout[i].symbol);
+		w = textw(layouts[i].symbol);
 		if(w > blw)
 			blw = w;
 	}
@@ -148,7 +105,7 @@ initlayouts(void) {
 
 Client *
 nexttiled(Client *c) {
-	for(; c && (c->isversatile || !isvisible(c)); c = c->next);
+	for(; c && (c->isfloating || !isvisible(c)); c = c->next);
 	return c;
 }
 
@@ -156,19 +113,25 @@ void
 restack(void) {
 	Client *c;
 	XEvent ev;
+	XWindowChanges wc;
 
 	drawstatus();
 	if(!sel)
 		return;
-	if(sel->isversatile || lt->arrange == versatile)
+	if(sel->isfloating || lt->arrange == floating)
 		XRaiseWindow(dpy, sel->win);
-	if(lt->arrange != versatile) {
-		if(!sel->isversatile)
-			XLowerWindow(dpy, sel->win);
+	if(lt->arrange != floating) {
+		wc.stack_mode = Below;
+		wc.sibling = barwin;
+		if(!sel->isfloating) {
+			XConfigureWindow(dpy, sel->win, CWSibling | CWStackMode, &wc);
+			wc.sibling = sel->win;
+		}
 		for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
 			if(c == sel)
 				continue;
-			XLowerWindow(dpy, c->win);
+			XConfigureWindow(dpy, c->win, CWSibling | CWStackMode, &wc);
+			wc.sibling = c->win;
 		}
 	}
 	XSync(dpy, False);
@@ -180,80 +143,47 @@ setlayout(const char *arg) {
 	int i;
 
 	if(!arg) {
-		for(i = 0; i < nlayouts && lt != &layout[i]; i++);
-		if(i == nlayouts - 1)
-			lt = &layout[0];
-		else
-			lt = &layout[++i];
+		lt++;
+		if(lt == layouts + nlayouts)
+			lt = layouts;
 	}
 	else {
 		i = atoi(arg);
 		if(i < 0 || i >= nlayouts)
 			return;
-		lt = &layout[i];
+		lt = &layouts[i];
 	}
 	if(sel)
-		lt->arrange();
+		arrange();
 	else
 		drawstatus();
 }
 
+void
+togglebar(const char *arg) {
+	if(bpos == BarOff)
+		bpos = (BARPOS == BarOff) ? BarTop : BARPOS;
+	else
+		bpos = BarOff;
+	updatebarpos();
+	arrange();
+}
+
 void
 togglemax(const char *arg) {
 	XEvent ev;
 
-	if(!sel || (lt->arrange != versatile && !sel->isversatile) || sel->isfixed)
+	if(!sel || (lt->arrange != floating && !sel->isfloating) || sel->isfixed)
 		return;
 	if((sel->ismax = !sel->ismax)) {
 		sel->rx = sel->x;
 		sel->ry = sel->y;
 		sel->rw = sel->w;
 		sel->rh = sel->h;
-		resize(sel, wax, way, waw - 2 * BORDERPX, wah - 2 * BORDERPX, True);
+		resize(sel, wax, way, waw - 2 * sel->border, wah - 2 * sel->border, True);
 	}
 	else
 		resize(sel, sel->rx, sel->ry, sel->rw, sel->rh, True);
 	drawstatus();
 	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
 }
-
-void
-versatile(void) {
-	Client *c;
-
-	for(c = clients; c; c = c->next) {
-		if(isvisible(c)) {
-			if(c->isbanned)
-				XMoveWindow(dpy, c->win, c->x, c->y);
-			c->isbanned = False;
-			resize(c, c->x, c->y, c->w, c->h, True);
-		}
-		else {
-			c->isbanned = True;
-			XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
-		}
-	}
-	if(!sel || !isvisible(sel)) {
-		for(c = stack; c && !isvisible(c); c = c->snext);
-		focus(c);
-	}
-	restack();
-}
-
-void
-zoom(const char *arg) {
-	unsigned int n;
-	Client *c;
-
-	if(!sel || lt->arrange != tile || sel->isversatile)
-		return;
-	for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
-		n++;
-	if((c = sel) == nexttiled(clients))
-		if(!(c = nexttiled(c->next)))
-			return;
-	detach(c);
-	attach(c);
-	focus(c);
-	lt->arrange();
-}