about summary refs log tree commit diff stats
path: root/layout.c
diff options
context:
space:
mode:
authorAnselm R. Garbe <arg@suckless.org>2007-02-20 10:49:53 +0100
committerAnselm R. Garbe <arg@suckless.org>2007-02-20 10:49:53 +0100
commit8012fcf3334148d2b39646fd372a7514cc74c250 (patch)
tree157855dd25044e50f7696eb57655c88c6069ac2e /layout.c
parent6bc4556ebd7f48f52f9a446e53d1705d8fd79b27 (diff)
downloaddwm-8012fcf3334148d2b39646fd372a7514cc74c250.tar.gz
split screen.c into layout.c and tag.c (because the view is an implicit mixture of both)
Diffstat (limited to 'layout.c')
-rw-r--r--layout.c185
1 files changed, 185 insertions, 0 deletions
diff --git a/layout.c b/layout.c
new file mode 100644
index 0000000..d754afb
--- /dev/null
+++ b/layout.c
@@ -0,0 +1,185 @@
+/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
+ * See LICENSE file for license details.
+ */
+#include "dwm.h"
+
+unsigned int master = MASTER;
+unsigned int nmaster = NMASTER;
+unsigned int blw = 0;
+Layout *lt = NULL;
+
+/* static */
+
+static unsigned int nlayouts = 0;
+
+static void
+tile(void) {
+	unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th;
+	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 * master) / 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();
+}
+
+LAYOUTS
+
+/* extern */
+
+void
+incnmaster(Arg *arg) {
+	if((lt->arrange != tile) || (nmaster + arg->i < 1)
+	|| (wah / (nmaster + arg->i) <= 2 * BORDERPX))
+		return;
+	nmaster += arg->i;
+	if(sel)
+		lt->arrange();
+	else
+		drawstatus();
+}
+
+void
+initlayouts(void) {
+	unsigned int i, w;
+
+	lt = &layout[0];
+	nlayouts = sizeof layout / sizeof layout[0];
+	for(blw = i = 0; i < nlayouts; i++) {
+		w = textw(layout[i].symbol);
+		if(w > blw)
+			blw = w;
+	}
+}
+
+void
+resizemaster(Arg *arg) {
+	if(lt->arrange != tile)
+		return;
+	if(arg->i == 0)
+		master = MASTER;
+	else {
+		if(waw * (master + arg->i) / 1000 >= waw - 2 * BORDERPX
+		|| waw * (master + arg->i) / 1000 <= 2 * BORDERPX)
+			return;
+		master += arg->i;
+	}
+	lt->arrange();
+}
+
+void
+restack(void) {
+	Client *c;
+	XEvent ev;
+
+	drawstatus();
+	if(!sel)
+		return;
+	if(sel->isversatile || lt->arrange == versatile)
+		XRaiseWindow(dpy, sel->win);
+	if(lt->arrange != versatile) {
+		if(!sel->isversatile)
+			XLowerWindow(dpy, sel->win);
+		for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
+			if(c == sel)
+				continue;
+			XLowerWindow(dpy, c->win);
+		}
+	}
+	XSync(dpy, False);
+	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
+}
+
+void
+setlayout(Arg *arg) {
+	unsigned int i;
+
+	if(arg->i == -1) {
+		for(i = 0; i < nlayouts && lt != &layout[i]; i++);
+		if(i == nlayouts - 1)
+			lt = &layout[0];
+		else
+			lt = &layout[++i];
+	}
+	else {
+		if(arg->i < 0 || arg->i >= nlayouts)
+			return;
+		lt = &layout[arg->i];
+	}
+	if(sel)
+		lt->arrange();
+	else
+		drawstatus();
+}
+
+void
+toggleversatile(Arg *arg) {
+	if(!sel || lt->arrange == versatile)
+		return;
+	sel->isversatile = !sel->isversatile;
+	lt->arrange();
+}
+
+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();
+}