Hey,

I've been thinking about this patch for a while, and I've knocked
together a patch which takes an alternative approach, which seems to
result in a simpler diff.

In my patch each layout has three arrangement functions, one for the
master, one the slave, and one a 'meta-layout' which defines how the
master and slave "booths" are laid out. So dwm's tile() is achieved
with an htile() meta-layout and vtile() master and slave.

The patch is +12 lines over dwm tip.

Thanks,
cls
diff -r 183cedbebe52 config.def.h
--- a/config.def.h	Fri Nov 04 20:02:35 2011 +0100
+++ b/config.def.h	Sun Nov 06 20:23:26 2011 +0100
@@ -29,9 +29,9 @@
 
 static const Layout layouts[] = {
 	/* symbol     arrange function */
-	{ "[]=",      tile },    /* first entry is default */
-	{ "><>",      NULL },    /* no layout function means floating behavior */
-	{ "[M]",      monocle },
+	{ "[]=",      tileh,   tilev,   tilev },   /* first entry is default */
+	{ "><>",      NULL,    NULL,    NULL },    /* no layout function means floating behavior */
+	{ "[M]",      monocle, monocle, monocle },
 };
 
 /* key definitions */
diff -r 183cedbebe52 dwm.c
--- a/dwm.c	Fri Nov 04 20:02:35 2011 +0100
+++ b/dwm.c	Sun Nov 06 20:23:26 2011 +0100
@@ -120,7 +120,9 @@
 
 typedef struct {
 	const char *symbol;
-	void (*arrange)(Monitor *);
+	void (*arrange)(Client *, float, XRectangle *, XRectangle *);
+	void (*master)(Client *, float, XRectangle *, XRectangle *);
+	void (*slave)(Client *, float, XRectangle *, XRectangle *);
 } Layout;
 
 struct Monitor {
@@ -198,7 +200,7 @@
 static void manage(Window w, XWindowAttributes *wa);
 static void mappingnotify(XEvent *e);
 static void maprequest(XEvent *e);
-static void monocle(Monitor *m);
+static void monocle(Client *c, float fact, XRectangle *r, XRectangle *rp);
 static void movemouse(const Arg *arg);
 static Client *nexttiled(Client *c);
 static void pop(Client *);
@@ -224,7 +226,8 @@
 static void tag(const Arg *arg);
 static void tagmon(const Arg *arg);
 static int textnw(const char *text, unsigned int len);
-static void tile(Monitor *);
+static void tileh(Client *c, float fact, XRectangle *r, XRectangle *rp);
+static void tilev(Client *c, float fact, XRectangle *r, XRectangle *rp);
 static void togglebar(const Arg *arg);
 static void togglefloating(const Arg *arg);
 static void toggletag(const Arg *arg);
@@ -401,9 +404,22 @@
 
 void
 arrangemon(Monitor *m) {
+	XRectangle r, rm, rt = { m->wx, m->wy, m->ww, m->wh };
+	Client *c;
+	int i, n;
+
 	strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol);
-	if(m->lt[m->sellt]->arrange)
-		m->lt[m->sellt]->arrange(m);
+	if(m->lt[m->sellt]->arrange) {
+		for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+		if(n > 0) {
+			m->lt[m->sellt]->arrange(NULL, (n > m->nmaster) ? m->mfact : 1, &rt, &rm);
+			for(i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
+				if(i < m->nmaster)
+					m->lt[m->sellt]->master(c, 1.0 / (MIN(n, m->nmaster) - i), &rm, &r);
+				else
+					m->lt[m->sellt]->slave(c, 1.0 / (n - i), &rt, &r);
+		}
+	}
 	restack(m);
 }
 
@@ -1198,17 +1214,13 @@
 }
 
 void
-monocle(Monitor *m) {
-	unsigned int n = 0;
-	Client *c;
-
-	for(c = m->clients; c; c = c->next)
-		if(ISVISIBLE(c))
-			n++;
-	if(n > 0) /* override layout symbol */
-		snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
-	for(c = nexttiled(m->clients); c; c = nexttiled(c->next))
-		resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, False);
+monocle(Client *c, float fact, XRectangle *r, XRectangle *rp) {
+	rp->x      = r->x;
+	rp->y      = r->y;
+	rp->width  = r->width;
+	rp->height = r->height;
+	if(c)
+		resize(c, r->x, r->y, r->width - (2*c->bw), r->height - (2*c->bw), False);
 }
 
 void
@@ -1665,29 +1677,29 @@
 }
 
 void
-tile(Monitor *m) {
-	unsigned int i, n, h, mw, my, ty;
-	Client *c;
+tileh(Client *c, float fact, XRectangle *r, XRectangle *rp)
+{
+	rp->x      = r->x;
+	rp->y      = r->y;
+	rp->width  = r->width * fact;
+	rp->height = r->height;
+	if(c)
+		resize(c, rp->x, rp->y, rp->width - (2*c->bw), rp->height - (2*c->bw), False);
+	r->x      += c ? WIDTH(c) : rp->width;
+	r->width  -= c ? WIDTH(c) : rp->width;
+}
 
-	for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
-	if(n == 0)
-		return;
-
-	if(n > m->nmaster)
-		mw = m->nmaster ? m->ww * m->mfact : 0;
-	else
-		mw = m->ww;
-	for(i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
-		if(i < m->nmaster) {
-			h = (m->wh - my) / (MIN(n, m->nmaster) - i);
-			resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), False);
-			my += HEIGHT(c);
-		}
-		else {
-			h = (m->wh - ty) / (n - i);
-			resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), False);
-			ty += HEIGHT(c);
-		}
+void
+tilev(Client *c, float fact, XRectangle *r, XRectangle *rp)
+{
+	rp->x      = r->x;
+	rp->y      = r->y;
+	rp->width  = r->width;
+	rp->height = r->height * fact;
+	if(c)
+		resize(c, rp->x, rp->y, rp->width - (2*c->bw), rp->height - (2*c->bw), False);
+	r->y      += c ? HEIGHT(c) : rp->height;
+	r->height -= c ? HEIGHT(c) : rp->height;
 }
 
 void

Reply via email to