Jason Ryan avatar Jason Ryan committed 9d79cb8

Archive of dwm patches

Comments (0)

Files changed (16)

Build/dwm-patches/bstack.6.0.diff

+@@ -2128,6 +2187,32 @@ zoom(const Arg *arg) {
+ 	pop(c);
+ }
+ 
++void
++bstack(Monitor *m) {
++	unsigned int i, n, w, mh, mx, tx;
++	Client *c;
++
++	for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
++	if(n == 0)
++		return;
++
++	if(n > m->nmaster)
++		mh = m->nmaster ? m->wh * m->mfact : 0;
++	else
++		mh = m->wh;
++	for(i = mx = tx = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
++		if(i < m->nmaster) {
++			w = (m->ww - mx) / (MIN(n, m->nmaster) - i);
++			resize(c, m->wx + mx, m->wy, w - (2*c->bw), mh - (2*c->bw), False);
++			mx += WIDTH(c);
++		}
++		else {
++			w = (m->ww - tx) / (n - i);
++			resize(c, m->wx + tx, m->wy + mh, w - (2*c->bw), m->wh - mh - (2*c->bw), False);
++			tx += WIDTH(c);
++		}
++}
++
+ int
+ main(int argc, char *argv[]) {
+ 	if(argc == 2 && !strcmp("-v", argv[1]))

Build/dwm-patches/bstack.c

+static void
+bstack(Monitor *m) {
+	int x, y, h, w, mh;
+	unsigned int i, n;
+	Client *c;
+
+	for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+	if(n == 0)
+		return;
+	/* master */
+	c = nexttiled(m->clients);
+	mh = m->mfact * m->wh;
+	resize(c, m->wx, m->wy, m->ww - 2 * c->bw, (n == 1 ? m->wh : mh) - 2 * c->bw, False);
+	if(--n == 0)
+		return;
+	/* tile stack */
+	x = m->wx;
+	y = (m->wy + mh > c->y + c->h) ? c->y + c->h + 2 * c->bw : m->wy + mh;
+	w = m->ww / n;
+	h = (m->wy + mh > c->y + c->h) ? m->wy + m->wh - y : m->wh - mh;
+	if(w < bh)
+		w = m->ww;
+	for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) {
+		resize(c, x, y, /* remainder */ ((i + 1 == n)
+		       ? m->wx + m->ww - x - 2 * c->bw : w - 2 * c->bw), h - 2 * c->bw, False);
+		if(w != m->ww)
+			x = c->x + WIDTH(c);
+	}
+}

Build/dwm-patches/cycle.diff

+--- a/dwm.c 2011-12-19 16:02:46.000000000 +0100
++++ b/dwm.c 2011-12-28 12:26:06.294936901 +0100
+@@ -251,6 +251,9 @@ static int xerror(Display *dpy, XErrorEv
+ static int xerrordummy(Display *dpy, XErrorEvent *ee);
+ static int xerrorstart(Display *dpy, XErrorEvent *ee);
+ static void zoom(const Arg *arg);
++static void cycle(const Arg *arg);
++static int shifttag(int dist);
++static void tagcycle(const Arg *arg);
+
+ /* variables */
+ static const char broken[] = "broken";
+@@ -2127,6 +2130,31 @@ zoom(const Arg *arg) {
+ }
+
+ int
++shifttag(int dist) {
++   int seltags = selmon->tagset[selmon->seltags] & TAGMASK;
++
++   if(dist > 0) // left circular shift
++       seltags = (seltags << dist) | (seltags >> (LENGTH(tags) - dist));
++   else // right circular shift
++       seltags = (seltags >> (- dist)) | (seltags << (LENGTH(tags) + dist));
++
++   return seltags;
++}
++
++void
++cycle(const Arg *arg) {
++   const Arg a = { .i = shifttag(arg->i) };
++   view(&a);
++}
++
++void
++tagcycle(const Arg *arg) {
++   const Arg a = { .i = shifttag(arg->i) };
++   tag(&a);
++   view(&a);
++}
++
++int
+ main(int argc, char *argv[]) {
+    if(argc == 2 && !strcmp("-v", argv[1]))
+        die("dwm-"VERSION", © 2006-2011 dwm engineers, see LICENSE for details\n");
+
+--- a/config.h  2011-12-19 16:02:46.000000000 +0100
++++ b/config.h  2011-12-28 12:29:47.037074371 +0100
+@@ -74,6 +74,10 @@ static Key keys[] = {
+    { MODKEY,                       XK_period, focusmon,       {.i = +1 } },
+    { MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } },
+    { MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } },
++   { MODKEY,                       XK_Left,   cycle,          {.i = -1 } },
++   { MODKEY,                       XK_Right,  cycle,          {.i = +1 } },
++   { MODKEY|ControlMask,           XK_Left,   tagcycle,       {.i = -1 } },
++   { MODKEY|ControlMask,           XK_Right,  tagcycle,       {.i = +1 } },
+    TAGKEYS(                        XK_1,                      0)
+    TAGKEYS(                        XK_2,                      1)
+    TAGKEYS(                        XK_3,                      2)
+
+

Build/dwm-patches/default-layout.diff

+diff --git a/dwm/config.h b/dwm/config.h
+index 126c864..a29f170 100644
+--- a/dwm/config.h
++++ b/dwm/config.h
+@@ -22,6 +22,7 @@ static const Bool topbar            = True;     /* False means bottom bar */
+ 
+ /* tagging */
+ static const char *tags[] = { "web", "media", "msg", "4", "5"};
++static const int taglayouts[] = {2, 2, 0, 0, 0};
+ 
+ static const Rule rules[] = {
+ 	/* class      instance    title       tags mask     isfloating   monitor */
+diff --git a/dwm/dwm.c b/dwm/dwm.c
+index ef8db79..3f2ac21 100644
+--- a/dwm/dwm.c
++++ b/dwm/dwm.c
+@@ -1645,6 +1645,21 @@ setup(void) {
+ 	XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa);
+ 	XSelectInput(dpy, root, wa.event_mask);
+ 	grabkeys();
++
++        /* set default tag layouts */
++        for (int i = 0; i < LENGTH(tags); i++)
++        {
++                if (taglayouts[i]!=0)
++                {
++                        Layout *l;
++                        view(&((Arg) { .ui = 1 << i }));
++                        l = (Layout *)layouts;
++                        for (int j = 0; j < taglayouts[i]; j++)
++                                l++;
++                        setlayout(&((Arg) { .v = l }));
++                }
++        }
++        view(&((Arg) { .ui = 1 << 0 }));
+ }
+ 
+ void
+

Build/dwm-patches/fibonacci-6.0.diff

+# HG changeset patch
+# Parent 07bce02526a24d7ee0048ad68a2975c65239e054
+
+diff -r 07bce02526a2 config.def.h
+--- a/config.def.h	Thu Sep 13 10:18:58 2012 +1200
++++ b/config.def.h	Mon Sep 17 14:50:13 2012 +1200
+@@ -56,6 +56,7 @@
+ 	{ "[F]",      NULL },    /* no layout function means floating behavior */
+ 	{ "[S]",      bstack},
+ 	{ "[M]",      monocle },
++	{ "[@]",      spiral },
+ };
+ 
+ /* key definitions */
+@@ -117,6 +118,7 @@
+ 	{ MODKEY,                       XK_f,      setlayout,      {.v = &layouts[1]} },
+ 	{ MODKEY,                       XK_s,      setlayout,      {.v = &layouts[2]} },
+ 	{ MODKEY,                       XK_m,      setlayout,      {.v = &layouts[3]} },
++	{ MODKEY,                       XK_g,      setlayout,      {.v = &layouts[4]} },
+ 	{ MODKEY,                       XK_space,  setlayout,      {0} },
+ 	{ MODKEY|ShiftMask,             XK_space,  togglefloating, {0} },
+ 	{ MODKEY,                       XK_0,      view,           {.ui = ~0 } },
+diff -r 07bce02526a2 dwm.c
+--- a/dwm.c	Thu Sep 13 10:18:58 2012 +1200
++++ b/dwm.c	Mon Sep 17 14:50:13 2012 +1200
+@@ -261,6 +261,7 @@
+ static void cycle(const Arg *arg);
+ static int shifttag(int dist);
+ static void tagcycle(const Arg *arg);
++static void spiral(Monitor *mon);
+ 
+ /* variables */
+ static const char broken[] = "broken";
+@@ -2322,6 +2323,70 @@
+    view(&a);
+ }
+ 
++void
++fibonacci(Monitor *mon, int s) {
++	unsigned int i, n, nx, ny, nw, nh;
++	Client *c;
++
++	for(n = 0, 
++	c = nexttiled(mon->clients); 
++	c; c = nexttiled(c->next), n++);
++	if(n == 0)
++		return;
++	
++	nx = mon->wx;
++	ny = 0;
++	nw = mon->ww;
++	nh = mon->wh;
++	
++	for(i = 0, c = nexttiled(mon->clients); c; c = nexttiled(c->next)) {
++		if((i % 2 && nh / 2 > 2 * c->bw)
++		   || (!(i % 2) && nw / 2 > 2 * c->bw)) {
++			if(i < n - 1) {
++				if(i % 2)
++					nh /= 2;
++				else
++					nw /= 2;
++				if((i % 4) == 2 && !s)
++					nx += nw;
++				else if((i % 4) == 3 && !s)
++					ny += nh;
++			}
++			if((i % 4) == 0) {
++				if(s)
++					ny += nh;
++				else
++					ny -= nh;
++			}
++			else if((i % 4) == 1)
++				nx += nw;
++			else if((i % 4) == 2)
++				ny += nh;
++			else if((i % 4) == 3) {
++				if(s)
++					nx += nw;
++				else
++					nx -= nw;
++			}
++			if(i == 0)
++			{
++				if(n != 1)
++					nw = mon->ww * mon->mfact;
++				ny = mon->wy;
++			}
++			else if(i == 1)
++				nw = mon->ww - nw;
++			i++;
++		}
++		resize(c, nx, ny, nw - 2 * c->bw, nh - 2 * c->bw, False);
++	}
++}
++
++void
++spiral(Monitor *mon) {
++	fibonacci(mon, 1);
++}
++
+ int
+ main(int argc, char *argv[]) {
+ 	if(argc == 2 && !strcmp("-v", argv[1]))

Build/dwm-patches/nmaster-sym.c

+enum {MaxMon = 8};
+static int nmasters[MaxMon];
+static int initnm = 0;
+
+static void
+initnmaster(void) {
+	int i;
+
+	if(initnm)
+		return;
+	for(i = 0; i < MaxMon; i++)
+		nmasters[i] = nmaster;
+	initnm = 1;
+}
+
+static void
+incnmaster(const Arg *arg) {
+	if(!arg || !selmon->lt[selmon->sellt]->arrange || selmon->num >= MaxMon)
+		return;
+	nmasters[selmon->num] += arg->i;
+	if(nmasters[selmon->num] < 0)
+		nmasters[selmon->num] = 0;
+	arrange(selmon);
+}
+
+static void
+setnmaster(const Arg *arg) {
+	if(!arg || !selmon->lt[selmon->sellt]->arrange || selmon->num >= MaxMon)
+		return;
+	nmasters[selmon->num] = arg->i > 0 ? arg->i : 0;
+	arrange(selmon);
+}
+
+static void
+ntile(Monitor *m) {
+	int x, y, h, w, mw, nm;
+	unsigned int i, n;
+	Client *c;
+
+	initnmaster();
+	/* override layout symbol */
+	snprintf(m->ltsymbol, sizeof m->ltsymbol, "%d]=", nmasters[m->num]);
+	for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+	c = nexttiled(m->clients);
+	nm = m->num < MaxMon ? nmasters[m->num] : nmaster;
+	if(nm > n)
+		nm = n;
+	/* master */
+	if(nm > 0) {
+		mw = m->mfact * m->ww;
+		h = m->wh / nm;
+		if(h < bh)
+			h = m->wh;
+		y = m->wy;
+		for(i = 0; i < nm; i++, c = nexttiled(c->next)) {
+			resize(c, m->wx, y, (n == nm ? m->ww : mw) - 2 * c->bw,
+			       ((i + 1 == nm) ? m->wy + m->wh - y : h) - 2 * c->bw, False);
+			if(h != m->wh)
+				y = c->y + HEIGHT(c);
+		}
+		n -= nm;
+	} else
+		mw = 0;
+	if(n == 0)
+		return;
+	/* tile stack */
+	x = m->wx + mw;
+	y = m->wy;
+	w = m->ww - mw;
+	h = m->wh / n;
+	if(h < bh)
+		h = m->wh;
+	for(i = 0; c; c = nexttiled(c->next), i++) {
+		resize(c, x, y, w - 2 * c->bw,
+		       ((i + 1 == n) ? m->wy + m->wh - y : h) - 2 * c->bw, False);
+		if(h != m->wh)
+			y = c->y + HEIGHT(c);
+	}
+}
+
+static void
+nbstack(Monitor *m) {
+	int x, y, h, w, mh, nm;
+	unsigned int i, n;
+	Client *c;
+
+	initnmaster();
+	/* override layout symbol */
+	snprintf(m->ltsymbol, sizeof m->ltsymbol, "T%dT", nmasters[m->num]);
+	for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+	c = nexttiled(m->clients);
+	nm = m->num < MaxMon ? nmasters[m->num] : nmaster;
+	if(nm > n)
+		nm = n;
+	/* master */
+	if(nm > 0) {
+		mh = m->mfact * m->wh;
+		w = m->ww / nm;
+		if(w < bh)
+			w = m->ww;
+		x = m->wx;
+		for(i = 0; i < nm; i++, c = nexttiled(c->next)) {
+			resize(c, x, m->wy, ((i + 1 == nm) ? m->wx + m->ww - x : w) - 2 * c->bw,
+			       (n == nm ? m->wh : mh) - 2 * c->bw, False);
+			if(w != m->ww)
+				x = c->x + WIDTH(c);
+		}
+		n -= nm;
+	} else
+		mh = 0;
+	if(n == 0)
+		return;
+	/* tile stack */
+	x = m->wx;
+	y = m->wy + mh;
+	w = m->ww / n;
+	h = m->wh - mh;
+	if(w < bh)
+		w = m->ww;
+	for(i = 0; c; c = nexttiled(c->next), i++) {
+		resize(c, x, y, ((i + 1 == n) ? m->wx + m->ww - x : w) - 2 * c->bw,
+		       h - 2 * c->bw, False);
+		if(w != m->ww)
+			x = c->x + WIDTH(c);
+	}
+}

Build/dwm-patches/pertag-6.0.diff

+diff --git a/dwm.c b/dwm.c
+--- a/dwm.c
++++ b/dwm.c
+@@ -122,27 +122,6 @@
+ 	void (*arrange)(Monitor *);
+ } Layout;
+ 
+-struct Monitor {
+-	char ltsymbol[16];
+-	float mfact;
+-	int nmaster;
+-	int num;
+-	int by;               /* bar geometry */
+-	int mx, my, mw, mh;   /* screen size */
+-	int wx, wy, ww, wh;   /* window area  */
+-	unsigned int seltags;
+-	unsigned int sellt;
+-	unsigned int tagset[2];
+-	Bool showbar;
+-	Bool topbar;
+-	Client *clients;
+-	Client *sel;
+-	Client *stack;
+-	Monitor *next;
+-	Window barwin;
+-	const Layout *lt[2];
+-};
+-
+ typedef struct {
+ 	const char *class;
+ 	const char *instance;
+@@ -281,6 +260,33 @@
+ /* configuration, allows nested code to access above variables */
+ #include "config.h"
+ 
++struct Monitor {
++	char ltsymbol[16];
++	float mfact;
++	int nmaster;
++	int num;
++	int by;               /* bar geometry */
++	int mx, my, mw, mh;   /* screen size */
++	int wx, wy, ww, wh;   /* window area  */
++	unsigned int seltags;
++	unsigned int sellt;
++	unsigned int tagset[2];
++	Bool showbar;
++	Bool topbar;
++	Client *clients;
++	Client *sel;
++	Client *stack;
++	Monitor *next;
++	Window barwin;
++	const Layout *lt[2];
++ 	int curtag;
++ 	int prevtag;
++ 	const Layout *lts[LENGTH(tags) + 1];
++ 	float mfacts[LENGTH(tags) + 1];
++ 	int nmasters[LENGTH(tags) + 1];
++ 	Bool showbars[LENGTH(tags) + 1];
++};
++
+ /* compile-time check if all tags fit into an unsigned int bit array. */
+ struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
+ 
+@@ -661,6 +667,7 @@
+ Monitor *
+ createmon(void) {
+ 	Monitor *m;
++	unsigned int i;
+ 
+ 	if(!(m = (Monitor *)calloc(1, sizeof(Monitor))))
+ 		die("fatal: could not malloc() %u bytes\n", sizeof(Monitor));
+@@ -672,6 +679,16 @@
+ 	m->lt[0] = &layouts[0];
+ 	m->lt[1] = &layouts[1 % LENGTH(layouts)];
+ 	strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
++
++ 	/* pertag init */
++ 	m->curtag = m->prevtag = 1;
++ 	for(i=0; i < LENGTH(tags) + 1 ; i++) {
++ 		m->mfacts[i] = mfact;
++ 		m->nmasters[i] = nmaster;
++ 		m->lts[i] = &layouts[0];
++ 		m->showbars[i] = m->showbar;
++ 	}
++
+ 	return m;
+ }
+ 
+@@ -1028,7 +1045,8 @@
+ 
+ void
+ incnmaster(const Arg *arg) {
+-	selmon->nmaster = MAX(selmon->nmaster + arg->i, 1);
++	selmon->nmasters[selmon->curtag] = MAX(selmon->nmaster + arg->i, 1);
++	selmon->nmaster = selmon->nmasters[selmon->curtag];
+ 	arrange(selmon);
+ }
+ 
+@@ -1515,7 +1533,7 @@
+ 	if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
+ 		selmon->sellt ^= 1;
+ 	if(arg && arg->v)
+-		selmon->lt[selmon->sellt] = (Layout *)arg->v;
++ 		selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag] = (Layout *)arg->v;
+ 	strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
+ 	if(selmon->sel)
+ 		arrange(selmon);
+@@ -1533,7 +1551,7 @@
+ 	f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
+ 	if(f < 0.1 || f > 0.9)
+ 		return;
+-	selmon->mfact = f;
++ 	selmon->mfact = selmon->mfacts[selmon->curtag] = f;
+ 	arrange(selmon);
+ }
+ 
+@@ -1680,7 +1698,7 @@
+ 
+ void
+ togglebar(const Arg *arg) {
+-	selmon->showbar = !selmon->showbar;
++ 	selmon->showbar = selmon->showbars[selmon->curtag] = !selmon->showbar;
+ 	updatebarpos(selmon);
+ 	XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
+ 	arrange(selmon);
+@@ -1699,13 +1717,28 @@
+ 
+ void
+ toggletag(const Arg *arg) {
+-	unsigned int newtags;
++	unsigned int i, newtags;
+ 
+ 	if(!selmon->sel)
+ 		return;
+ 	newtags = selmon->sel->tags ^ (arg->ui & TAGMASK);
+ 	if(newtags) {
+ 		selmon->sel->tags = newtags;
++ 		if(newtags == ~0) {
++ 			selmon->prevtag = selmon->curtag;
++ 			selmon->curtag = 0;
++ 		}
++ 		if(!(newtags & 1 << (selmon->curtag - 1))) {
++ 			selmon->prevtag = selmon->curtag;
++ 			for (i=0; !(newtags & 1 << i); i++);
++ 			selmon->curtag = i + 1;
++ 		}
++ 		selmon->sel->tags = newtags;
++ 		selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag];
++ 		selmon->mfact = selmon->mfacts[selmon->curtag];
++ 		selmon->nmaster = selmon->nmasters[selmon->curtag];
++ 		if (selmon->showbar != selmon->showbars[selmon->curtag])
++ 			togglebar(NULL);
+ 		focus(NULL);
+ 		arrange(selmon);
+ 	}
+@@ -1982,11 +2015,30 @@
+ 
+ void
+ view(const Arg *arg) {
++	unsigned int i;
++
+ 	if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
+ 		return;
+ 	selmon->seltags ^= 1; /* toggle sel tagset */
+-	if(arg->ui & TAGMASK)
++	if(arg->ui & TAGMASK) {
+ 		selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
++ 		selmon->prevtag = selmon->curtag;
++ 		if(arg->ui == ~0)
++ 			selmon->curtag = 0;
++ 		else {
++ 			for (i=0; !(arg->ui & 1 << i); i++);
++ 			selmon->curtag = i + 1;
++ 		}
++ 	} else {
++ 		selmon->prevtag= selmon->curtag ^ selmon->prevtag;
++ 		selmon->curtag^= selmon->prevtag;
++ 		selmon->prevtag= selmon->curtag ^ selmon->prevtag;
++ 	}
++ 	selmon->lt[selmon->sellt]= selmon->lts[selmon->curtag];
++ 	selmon->mfact = selmon->mfacts[selmon->curtag];
++ 	selmon->nmaster = selmon->nmasters[selmon->curtag];
++ 	if(selmon->showbar != selmon->showbars[selmon->curtag])
++ 		togglebar(NULL);
+ 	focus(NULL);
+ 	arrange(selmon);
+ }

Build/dwm-patches/pertag-init-5.7.2.diff

+diff -up dwm-5.7.2.orig//config.h dwm-5.7.2/config.h
+--- dwm-5.7.2.orig//config.h    2010-03-31 12:32:53.000000000 +0200
++++ dwm-5.7.2/config.h    2010-03-31 12:32:25.000000000 +0200
+@@ -14,7 +14,8 @@ static const Bool showbar           = Tr
+ static const Bool topbar            = True;     /* False means bottom bar */
+ 
+ /* tagging */
+-static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
++static const char *tags[]           = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
++static const int  initlayouts[] = { 0,   1,   0,   1,   1,   1,   2,   0,   2,   1  };
+ 
+ static const Rule rules[] = {
+     /* class      instance    title       tags mask     isfloating   monitor */
+diff -up dwm-5.7.2.orig//dwm.c dwm-5.7.2/dwm.c
+--- dwm-5.7.2.orig//dwm.c    2010-03-31 12:17:10.000000000 +0200
++++ dwm-5.7.2/dwm.c    2010-03-31 12:27:32.000000000 +0200
+@@ -120,26 +120,6 @@ typedef struct {
+     void (*arrange)(Monitor *);
+ } Layout;
+ 
+-struct Monitor {
+-    char ltsymbol[16];
+-    float mfact;
+-    int num;
+-    int by;               /* bar geometry */
+-    int mx, my, mw, mh;   /* screen size */
+-    int wx, wy, ww, wh;   /* window area  */
+-    unsigned int seltags;
+-    unsigned int sellt;
+-    unsigned int tagset[2];
+-    Bool showbar;
+-    Bool topbar;
+-    Client *clients;
+-    Client *sel;
+-    Client *stack;
+-    Monitor *next;
+-    Window barwin;
+-    const Layout *lt[2];
+-};
+-
+ typedef struct {
+     const char *class;
+     const char *instance;
+@@ -273,6 +253,31 @@ static Window root;
+ /* configuration, allows nested code to access above variables */
+ #include "config.h"
+ 
++struct Monitor {
++    char ltsymbol[16];
++    float mfact;
++    int num;
++    int by;               /* bar geometry */
++    int mx, my, mw, mh;   /* screen size */
++    int wx, wy, ww, wh;   /* window area  */
++    unsigned int seltags;
++    unsigned int sellt;
++    unsigned int tagset[2];
++    Bool showbar;
++    Bool topbar;
++    Client *clients;
++    Client *sel;
++    Client *stack;
++    Monitor *next;
++    Window barwin;
++    const Layout *lt[2];
++    int curtag;
++    int prevtag;
++    const Layout *lts[LENGTH(tags) + 1];
++    double mfacts[LENGTH(tags) + 1];
++    Bool showbars[LENGTH(tags) + 1];
++};
++
+ /* compile-time check if all tags fit into an unsigned int bit array. */
+ struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
+ 
+@@ -613,9 +618,9 @@ createmon(void) {
+     m->mfact = mfact;
+     m->showbar = showbar;
+     m->topbar = topbar;
+-    m->lt[0] = &layouts[0];
++    m->lt[0] = &layouts[initlayouts[1]] && initlayouts[1] <  LENGTH(layouts) ? &layouts[initlayouts[1]] : &layouts[0];
+     m->lt[1] = &layouts[1 % LENGTH(layouts)];
+-    strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
++    strncpy(m->ltsymbol, initlayouts[1] && initlayouts[1] < LENGTH(layouts) ? layouts[initlayouts[1]].symbol : layouts[0].symbol, sizeof m->ltsymbol);
+     return m;
+ }
+ 
+@@ -1450,7 +1455,7 @@ setlayout(const Arg *arg) {
+     if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
+         selmon->sellt ^= 1;
+     if(arg && arg->v)
+-        selmon->lt[selmon->sellt] = (Layout *)arg->v;
++        selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag] = (Layout *)arg->v;
+     strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
+     if(selmon->sel)
+         arrange(selmon);
+@@ -1468,13 +1473,15 @@ setmfact(const Arg *arg) {
+     f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
+     if(f < 0.1 || f > 0.9)
+         return;
+-    selmon->mfact = f;
++    selmon->mfact = selmon->mfacts[selmon->curtag] = f;
+     arrange(selmon);
+ }
+ 
+ void
+ setup(void) {
+     XSetWindowAttributes wa;
++    Monitor *m;
++    unsigned int i;
+ 
+     /* clean up any zombies immediately */
+     sigchld(0);
+@@ -1509,7 +1516,27 @@ setup(void) {
+     XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
+     if(!dc.font.set)
+         XSetFont(dpy, dc.gc, dc.font.xfont->fid);
++    /* init tags */
++    for(m = mons; m; m = m->next)
++        m->curtag = m->prevtag = 1;
++    /* init mfacts */
++    for(m = mons; m; m = m->next) {
++        for(i=0; i < LENGTH(tags) + 1 ; i++) {
++            m->mfacts[i] = m->mfact;
++        }
++    }
++    /* init layouts */
++    for(m = mons; m; m = m->next) {
++        for(i=0; i < LENGTH(tags) + 1; i++) {
++            m->lts[i] = initlayouts[i] && initlayouts[i] < LENGTH(layouts) ? &layouts[initlayouts[i]] : &layouts[0];
++        }
++    }
+     /* init bars */
++    for(m = mons; m; m = m->next) {
++        for(i=0; i < LENGTH(tags) + 1; i++) {
++            m->showbars[i] = m->showbar;
++        }
++    }
+     updatebars();
+     updatestatus();
+     /* EWMH support per view */
+@@ -1620,7 +1647,7 @@ tile(Monitor *m) {
+ 
+ void
+ togglebar(const Arg *arg) {
+-    selmon->showbar = !selmon->showbar;
++    selmon->showbar = selmon->showbars[selmon->curtag] = !selmon->showbar;
+     updatebarpos(selmon);
+     XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
+     arrange(selmon);
+@@ -1640,12 +1667,27 @@ togglefloating(const Arg *arg) {
+ void
+ toggletag(const Arg *arg) {
+     unsigned int newtags;
++    unsigned int i;
+ 
+     if(!selmon->sel)
+         return;
+     newtags = selmon->sel->tags ^ (arg->ui & TAGMASK);
+     if(newtags) {
+         selmon->sel->tags = newtags;
++        if(newtags == ~0) {
++            selmon->prevtag = selmon->curtag;
++            selmon->curtag = 0;
++        }
++        if(!(newtags & 1 << (selmon->curtag - 1))) {
++            selmon->prevtag = selmon->curtag;
++            for (i=0; !(newtags & 1 << i); i++);
++            selmon->curtag = i + 1;
++        }
++        selmon->sel->tags = newtags;
++        selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag];
++        selmon->mfact = selmon->mfacts[selmon->curtag];
++        if (selmon->showbar != selmon->showbars[selmon->curtag])
++            togglebar(NULL);
+         arrange(selmon);
+     }
+ }
+@@ -1912,11 +1954,29 @@ updatewmhints(Client *c) {
+ 
+ void
+ view(const Arg *arg) {
++    unsigned int i;
++
+     if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
+         return;
+     selmon->seltags ^= 1; /* toggle sel tagset */
+-    if(arg->ui & TAGMASK)
++    if(arg->ui & TAGMASK) {
+         selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
++        selmon->prevtag = selmon->curtag;
++        if(arg->ui == ~0)
++            selmon->curtag = 0;
++        else {
++            for (i=0; !(arg->ui & 1 << i); i++);
++            selmon->curtag = i + 1;
++        }
++    } else {
++        selmon->prevtag= selmon->curtag ^ selmon->prevtag;
++        selmon->curtag^= selmon->prevtag;
++        selmon->prevtag= selmon->curtag ^ selmon->prevtag;
++    }
++    selmon->lt[selmon->sellt]= selmon->lts[selmon->curtag];
++    selmon->mfact = selmon->mfacts[selmon->curtag];
++    if(selmon->showbar != selmon->showbars[selmon->curtag])
++        togglebar(NULL);
+     arrange(selmon);
+ }

Build/dwm-patches/pertag-init-5.8.2.diff

+diff -up dwm-5.7.2.orig//config.h dwm-5.7.2/config.h
+--- dwm-5.7.2.orig//config.h    2010-03-31 12:32:53.000000000 +0200
++++ dwm-5.7.2/config.h    2010-03-31 12:32:25.000000000 +0200
+@@ -14,7 +14,8 @@ static const Bool showbar           = Tr
+ static const Bool topbar            = True;     /* False means bottom bar */
+ 
+ /* tagging */
+-static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
++static const char *tags[]           = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
++static const int  initlayouts[] = { 0,   1,   0,   1,   1,   1,   2,   0,   2,   1  };
+ 
+ static const Rule rules[] = {
+     /* class      instance    title       tags mask     isfloating   monitor */
+diff -up dwm-5.7.2.orig//dwm.c dwm-5.7.2/dwm.c
+--- dwm-5.7.2.orig//dwm.c    2010-03-31 12:17:10.000000000 +0200
++++ dwm-5.7.2/dwm.c    2010-03-31 12:27:32.000000000 +0200
+@@ -120,26 +120,6 @@ typedef struct {
+     void (*arrange)(Monitor *);
+ } Layout;
+ 
+-struct Monitor {
+-    char ltsymbol[16];
+-    float mfact;
+-    int num;
+-    int by;               /* bar geometry */
+-    int mx, my, mw, mh;   /* screen size */
+-    int wx, wy, ww, wh;   /* window area  */
+-    unsigned int seltags;
+-    unsigned int sellt;
+-    unsigned int tagset[2];
+-    Bool showbar;
+-    Bool topbar;
+-    Client *clients;
+-    Client *sel;
+-    Client *stack;
+-    Monitor *next;
+-    Window barwin;
+-    const Layout *lt[2];
+-};
+-
+ typedef struct {
+     const char *class;
+     const char *instance;
+@@ -273,6 +253,31 @@ static Window root;
+ /* configuration, allows nested code to access above variables */
+ #include "config.h"
+ 
++struct Monitor {
++    char ltsymbol[16];
++    float mfact;
++    int num;
++    int by;               /* bar geometry */
++    int mx, my, mw, mh;   /* screen size */
++    int wx, wy, ww, wh;   /* window area  */
++    unsigned int seltags;
++    unsigned int sellt;
++    unsigned int tagset[2];
++    Bool showbar;
++    Bool topbar;
++    Client *clients;
++    Client *sel;
++    Client *stack;
++    Monitor *next;
++    Window barwin;
++    const Layout *lt[2];
++    int curtag;
++    int prevtag;
++    const Layout *lts[LENGTH(tags) + 1];
++    double mfacts[LENGTH(tags) + 1];
++    Bool showbars[LENGTH(tags) + 1];
++};
++
+ /* compile-time check if all tags fit into an unsigned int bit array. */
+ struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
+ 
+@@ -613,9 +618,9 @@ createmon(void) {
+     m->mfact = mfact;
+     m->showbar = showbar;
+     m->topbar = topbar;
+-    m->lt[0] = &layouts[0];
++    m->lt[0] = &layouts[initlayouts[1]] && initlayouts[1] <  LENGTH(layouts) ? &layouts[initlayouts[1]] : &layouts[0];
+     m->lt[1] = &layouts[1 % LENGTH(layouts)];
+-    strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
++    strncpy(m->ltsymbol, initlayouts[1] && initlayouts[1] < LENGTH(layouts) ? layouts[initlayouts[1]].symbol : layouts[0].symbol, sizeof m->ltsymbol);
+     return m;
+ }
+ 
+@@ -1450,7 +1455,7 @@ setlayout(const Arg *arg) {
+     if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
+         selmon->sellt ^= 1;
+     if(arg && arg->v)
+-        selmon->lt[selmon->sellt] = (Layout *)arg->v;
++        selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag] = (Layout *)arg->v;
+     strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
+     if(selmon->sel)
+         arrange(selmon);
+@@ -1468,13 +1473,15 @@ setmfact(const Arg *arg) {
+     f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
+     if(f < 0.1 || f > 0.9)
+         return;
+-    selmon->mfact = f;
++    selmon->mfact = selmon->mfacts[selmon->curtag] = f;
+     arrange(selmon);
+ }
+ 
+ void
+ setup(void) {
+     XSetWindowAttributes wa;
++    Monitor *m;
++    unsigned int i;
+ 
+     /* clean up any zombies immediately */
+     sigchld(0);
+@@ -1509,7 +1516,27 @@ setup(void) {
+     XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
+     if(!dc.font.set)
+         XSetFont(dpy, dc.gc, dc.font.xfont->fid);
++    /* init tags */
++    for(m = mons; m; m = m->next)
++        m->curtag = m->prevtag = 1;
++    /* init mfacts */
++    for(m = mons; m; m = m->next) {
++        for(i=0; i < LENGTH(tags) + 1 ; i++) {
++            m->mfacts[i] = m->mfact;
++        }
++    }
++    /* init layouts */
++    for(m = mons; m; m = m->next) {
++        for(i=0; i < LENGTH(tags) + 1; i++) {
++            m->lts[i] = initlayouts[i] && initlayouts[i] < LENGTH(layouts) ? &layouts[initlayouts[i]] : &layouts[0];
++        }
++    }
+     /* init bars */
++    for(m = mons; m; m = m->next) {
++        for(i=0; i < LENGTH(tags) + 1; i++) {
++            m->showbars[i] = m->showbar;
++        }
++    }
+     updatebars();
+     updatestatus();
+     /* EWMH support per view */
+@@ -1620,7 +1647,7 @@ tile(Monitor *m) {
+ 
+ void
+ togglebar(const Arg *arg) {
+-    selmon->showbar = !selmon->showbar;
++    selmon->showbar = selmon->showbars[selmon->curtag] = !selmon->showbar;
+     updatebarpos(selmon);
+     XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
+     arrange(selmon);
+@@ -1640,12 +1667,27 @@ togglefloating(const Arg *arg) {
+ void
+ toggletag(const Arg *arg) {
+     unsigned int newtags;
++    unsigned int i;
+ 
+     if(!selmon->sel)
+         return;
+     newtags = selmon->sel->tags ^ (arg->ui & TAGMASK);
+     if(newtags) {
+         selmon->sel->tags = newtags;
++        if(newtags == ~0) {
++            selmon->prevtag = selmon->curtag;
++            selmon->curtag = 0;
++        }
++        if(!(newtags & 1 << (selmon->curtag - 1))) {
++            selmon->prevtag = selmon->curtag;
++            for (i=0; !(newtags & 1 << i); i++);
++            selmon->curtag = i + 1;
++        }
++        selmon->sel->tags = newtags;
++        selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag];
++        selmon->mfact = selmon->mfacts[selmon->curtag];
++        if (selmon->showbar != selmon->showbars[selmon->curtag])
++            togglebar(NULL);
+         arrange(selmon);
+     }
+ }
+@@ -1912,11 +1954,29 @@ updatewmhints(Client *c) {
+ 
+ void
+ view(const Arg *arg) {
++    unsigned int i;
++
+     if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
+         return;
+     selmon->seltags ^= 1; /* toggle sel tagset */
+-    if(arg->ui & TAGMASK)
++    if(arg->ui & TAGMASK) {
+         selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
++        selmon->prevtag = selmon->curtag;
++        if(arg->ui == ~0)
++            selmon->curtag = 0;
++        else {
++            for (i=0; !(arg->ui & 1 << i); i++);
++            selmon->curtag = i + 1;
++        }
++    } else {
++        selmon->prevtag= selmon->curtag ^ selmon->prevtag;
++        selmon->curtag^= selmon->prevtag;
++        selmon->prevtag= selmon->curtag ^ selmon->prevtag;
++    }
++    selmon->lt[selmon->sellt]= selmon->lts[selmon->curtag];
++    selmon->mfact = selmon->mfacts[selmon->curtag];
++    if(selmon->showbar != selmon->showbars[selmon->curtag])
++        togglebar(NULL);
+     arrange(selmon);
+ }

Build/dwm-patches/push.c

+static Client *
+prevtiled(Client *c) {
+	Client *p, *r;
+
+	for(p = selmon->clients, r = NULL; p && p != c; p = p->next)
+		if(!p->isfloating && ISVISIBLE(p))
+			r = p;
+	return r;
+}
+
+static void
+pushup(const Arg *arg) {
+	Client *sel = selmon->sel;
+	Client *c;
+
+	if(!sel || sel->isfloating)
+		return;
+	if((c = prevtiled(sel))) {
+		/* attach before c */
+		detach(sel);
+		sel->next = c;
+		if(selmon->clients == c)
+			selmon->clients = sel;
+		else {
+			for(c = selmon->clients; c->next != sel->next; c = c->next);
+			c->next = sel;
+		}
+	} else {
+		/* move to the end */
+		for(c = sel; c->next; c = c->next);
+		detach(sel);
+		sel->next = NULL;
+		c->next = sel;
+	}
+	focus(sel);
+	arrange(selmon);
+}
+
+static void
+pushdown(const Arg *arg) {
+	Client *sel = selmon->sel;
+	Client *c;
+
+	if(!sel || sel->isfloating)
+		return;
+	if((c = nexttiled(sel->next))) {
+		/* attach after c */
+		detach(sel);
+		sel->next = c->next;
+		c->next = sel;
+	} else {
+		/* move to the front */
+		detach(sel);
+		attach(sel);
+	}
+	focus(sel);
+	arrange(selmon);
+}

Build/dwm-patches/statuscolors-5.8.2.diff

+--- a/config.def.h
++++ b/config.def.h
+@@ -2,12 +2,13 @@
+
+ /* appearance */
+ static const char font[] =
+"-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*";
+-static const char normbordercolor[] = "#cccccc";
+-static const char normbgcolor[] = "#cccccc";
+-static const char normfgcolor[] = "#000000";
+-static const char selbordercolor[] = "#0066ff";
+-static const char selbgcolor[] = "#0066ff";
+-static const char selfgcolor[] = "#ffffff";
++#define NUMCOLORS 3 // need at least 3
++static const char colors[NUMCOLORS][ColLast][8] = {
++ // border foreground background
++ { "#cccccc", "#888888", "#000000" }, // 0 = normal
++ { "#cc0000", "#ffff00", "#000000" }, // 1 = selected
++ { "#ff6600", "#000000", "#ff6600" }, // 2 = urgent/warning
++};
+ static const unsigned int borderpx = 1; /* border pixel of windows */
+ static const unsigned int snap = 32; /* snap pixel */
+ static const Bool showbar = True; /* False means no bar */
+@@ -45,7 +46,7 @@ static const Layout layouts[] = {
+ #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
+
+ /* commands */
+-static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb",
+normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor,
+NULL };
++static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb",
+colors[0][ColBG], "-nf", colors[0][ColFG], "-sb", colors[1][ColBG],
+"-sf", colors[1][ColFG], NULL };
+ static const char *termcmd[] = { "uxterm", NULL };
+
+ static Key keys[] = {
+diff --git a/dwm.c b/dwm.c
+index 670afbe..fd2f394 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -48,6 +48,7 @@
+ #define LENGTH(X) (sizeof X / sizeof X[0])
+ #define MAX(A, B) ((A) > (B) ? (A) : (B))
+ #define MIN(A, B) ((A) < (B) ? (A) : (B))
++#define MAXCOLORS 8 // avoid circular reference to NUMCOLORS
+ #define MOUSEMASK (BUTTONMASK|PointerMotionMask)
+ #define WIDTH(X) ((X)->w + 2 * (X)->bw)
+ #define HEIGHT(X) ((X)->h + 2 * (X)->bw)
+@@ -97,8 +98,7 @@ struct Client {
+
+ typedef struct {
+       int x, y, w, h;
+- unsigned long norm[ColLast];
+- unsigned long sel[ColLast];
++ unsigned long colors[MAXCOLORS][ColLast];
+       Drawable drawable;
+       GC gc;
+       struct {
+@@ -175,8 +175,9 @@ static void die(const char *errstr, ...);
+ static Monitor *dirtomon(int dir);
+ static void drawbar(Monitor *m);
+ static void drawbars(void);
+-static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned
+long col[ColLast]);
+-static void drawtext(const char *text, unsigned long col[ColLast],
+Bool invert);
++static void drawcoloredtext(char *text);
++static void drawsquare(Bool filled, Bool empty, unsigned long col[ColLast]);
++static void drawtext(const char *text, unsigned long col[ColLast], Bool pad);
+ static void enternotify(XEvent *e);
+ static void expose(XEvent *e);
+ static void focus(Client *c);
+@@ -696,36 +697,37 @@ drawbar(Monitor *m) {
+       dc.x = 0;
+       for(i = 0; i < LENGTH(tags); i++) {
+               dc.w = TEXTW(tags[i]);
+- col = m->tagset[m->seltags] & 1 << i ? dc.sel : dc.norm;
+- drawtext(tags[i], col, urg & 1 << i);
++ col = dc.colors[ (m->tagset[m->seltags] & 1 << i) ?
++ 1 : (urg & 1 << i ? 2:0) ];
++ drawtext(tags[i], col, True);
+               drawsquare(m == selmon && selmon->sel &&
+selmon->sel->tags & 1 << i,
+- occ & 1 << i, urg & 1 << i, col);
++ occ & 1 << i, col);
+               dc.x += dc.w;
+       }
+       dc.w = blw = TEXTW(m->ltsymbol);
+- drawtext(m->ltsymbol, dc.norm, False);
++ drawtext(m->ltsymbol, dc.colors[0], False);
+       dc.x += dc.w;
+       x = dc.x;
+       if(m == selmon) { /* status is only drawn on selected monitor */
+- dc.w = TEXTW(stext);
++ dc.w = textnw(stext, strlen(stext)); // no padding
+               dc.x = m->ww - dc.w;
+               if(dc.x < x) {
+                       dc.x = x;
+                       dc.w = m->ww - x;
+               }
+- drawtext(stext, dc.norm, False);
++ drawcoloredtext(stext);
+       }
+       else
+               dc.x = m->ww;
+       if((dc.w = dc.x - x) > bh) {
+               dc.x = x;
+               if(m->sel) {
+- col = m == selmon ? dc.sel : dc.norm;
+- drawtext(m->sel->name, col, False);
+- drawsquare(m->sel->isfixed,
+m->sel->isfloating, False, col);
++ col = dc.colors[ m == selmon ? 1 : 0 ];
++ drawtext(m->sel->name, col, True);
++ drawsquare(m->sel->isfixed, m->sel->isfloating, col);
+               }
+               else
+- drawtext(NULL, dc.norm, False);
++ drawtext(NULL, dc.colors[0], False);
+       }
+       XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0, m->ww, bh, 0, 0);
+       XSync(dpy, False);
+@@ -740,12 +742,36 @@ drawbars(void) {
+ }
+
+ void
+-drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) {
++drawcoloredtext(char *text) {
++ char *buf = text, *ptr = buf, c = 1;
++ unsigned long *col = dc.colors[0];
++ int i, ox = dc.x;
++
++ while( *ptr ) {
++ for( i = 0; *ptr < 0 || *ptr > NUMCOLORS; i++, ptr++);
++ if( !*ptr ) break;
++ c=*ptr;
++ *ptr=0;
++ if( i ) {
++ dc.w = selmon->ww - dc.x;
++ drawtext(buf, col, False);
++ dc.x += textnw(buf, i);
++ }
++ *ptr = c;
++ col = dc.colors[ c-1 ];
++ buf = ++ptr;
++ }
++ drawtext(buf, col, False);
++ dc.x = ox;
++}
++
++void
++drawsquare(Bool filled, Bool empty, unsigned long col[ColLast]) {
+       int x;
+       XGCValues gcv;
+       XRectangle r = { dc.x, dc.y, dc.w, dc.h };
+
+- gcv.foreground = col[invert ? ColBG : ColFG];
++ gcv.foreground = col[ColFG];
+       XChangeGC(dpy, dc.gc, GCForeground, &gcv);
+       x = (dc.font.ascent + dc.font.descent + 2) / 4;
+       r.x = dc.x + 1;
+@@ -761,18 +787,18 @@ drawsquare(Bool filled, Bool empty, Bool invert,
+unsigned long col[ColLast]) {
+ }
+
+ void
+-drawtext(const char *text, unsigned long col[ColLast], Bool invert) {
++drawtext(const char *text, unsigned long col[ColLast], Bool pad) {
+       char buf[256];
+       int i, x, y, h, len, olen;
+       XRectangle r = { dc.x, dc.y, dc.w, dc.h };
+
+- XSetForeground(dpy, dc.gc, col[invert ? ColFG : ColBG]);
++ XSetForeground(dpy, dc.gc, col[ColBG]);
+       XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
+       if(!text)
+               return;
+       olen = strlen(text);
+- h = dc.font.ascent + dc.font.descent;
+- y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
++ h = pad ? (dc.font.ascent + dc.font.descent) : 0;
++ y = dc.y + ((dc.h + dc.font.ascent - dc.font.descent) / 2);
+       x = dc.x + (h / 2);
+       /* shorten text if necessary */
+       for(len = MIN(olen, sizeof buf); len && textnw(text, len) >
+dc.w - h; len--);
+@@ -781,7 +807,7 @@ drawtext(const char *text, unsigned long
+col[ColLast], Bool invert) {
+       memcpy(buf, text, len);
+       if(len < olen)
+               for(i = len; i && i > len - 3; buf[--i] = '.');
+- XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]);
++ XSetForeground(dpy, dc.gc, col[ColFG]);
+       if(dc.font.set)
+               XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x,
+y, buf, len);
+       else
+@@ -830,7 +856,7 @@ focus(Client *c) {
+               detachstack(c);
+               attachstack(c);
+               grabbuttons(c, True);
+- XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]);
++ XSetWindowBorder(dpy, c->win, dc.colors[1][ColBorder]);
+               XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
+       }
+       else
+@@ -1139,7 +1165,7 @@ manage(Window w, XWindowAttributes *wa) {
+       }
+       wc.border_width = c->bw;
+       XConfigureWindow(dpy, w, CWBorderWidth, &wc);
+- XSetWindowBorder(dpy, w, dc.norm[ColBorder]);
++ XSetWindowBorder(dpy, w, dc.colors[0][ColBorder]);
+       configure(c); /* propagates border_width, if size doesn't change */
+       updatesizehints(c);
+       XSelectInput(dpy, w,
+EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
+@@ -1544,12 +1570,11 @@ setup(void) {
+       cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
+       cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
+       /* init appearance */
+- dc.norm[ColBorder] = getcolor(normbordercolor);
+- dc.norm[ColBG] = getcolor(normbgcolor);
+- dc.norm[ColFG] = getcolor(normfgcolor);
+- dc.sel[ColBorder] = getcolor(selbordercolor);
+- dc.sel[ColBG] = getcolor(selbgcolor);
+- dc.sel[ColFG] = getcolor(selfgcolor);
++ for(int i=0; i<NUMCOLORS; i++) {
++ dc.colors[i][ColBorder] = getcolor( colors[i][ColBorder] );
++ dc.colors[i][ColFG] = getcolor( colors[i][ColFG] );
++ dc.colors[i][ColBG] = getcolor( colors[i][ColBG] );
++ }
+       dc.drawable = XCreatePixmap(dpy, root, DisplayWidth(dpy, screen),
+bh, DefaultDepth(dpy, screen));
+       dc.gc = XCreateGC(dpy, root, 0, NULL);
+       XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
+@@ -1625,13 +1650,27 @@ tagmon(const Arg *arg) {
+
+ int
+ textnw(const char *text, unsigned int len) {
++ // remove non-printing color codes before calculating width
++ char *ptr = (char *) text;
++ unsigned int i, ibuf, lenbuf=len;
++ char buf[len+1];
+       XRectangle r;
+
++ for(i=0, ibuf=0; *ptr && i<len; i++, ptr++) {
++ if(*ptr <= NUMCOLORS && *ptr > 0) {
++ if (i < len) { lenbuf--; }
++ } else {
++ buf[ibuf]=*ptr;
++ ibuf++;
++ }
++ }
++ buf[ibuf]=0;
++
+       if(dc.font.set) {
+- XmbTextExtents(dc.font.set, text, len, NULL, &r);
++ XmbTextExtents(dc.font.set, buf, lenbuf, NULL, &r);
+                return r.width;
+        }
+- return XTextWidth(dc.font.xfont, text, len);
++ return XTextWidth(dc.font.xfont, buf, lenbuf);
+ }
+
+ void
+@@ -1711,7 +1754,7 @@ unfocus(Client *c, Bool setfocus) {
+       if(!c)
+               return;
+       grabbuttons(c, False);
+- XSetWindowBorder(dpy, c->win, dc.norm[ColBorder]);
++ XSetWindowBorder(dpy, c->win, dc.colors[0][ColBorder]);
+       if(setfocus)
+               XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
+ } 

Build/dwm-patches/statuscolors-5.9.diff

+diff -up dwm-5.9/config.def.h dwm-5.9-colors/config.def.h
+--- dwm-5.9/config.def.h	2011-07-10 16:24:25.000000000 -0400
++++ dwm-5.9-colors/config.def.h	2011-08-18 02:02:47.033830823 -0400
+@@ -1,13 +1,16 @@
+ /* See LICENSE file for copyright and license details. */
+ 
+ /* appearance */
++#define NUMCOLORS         4             // need at least 3
++static const char colors[NUMCOLORS][ColLast][8] = {
++   // border   foreground  background
++   { "#cccccc", "#000000", "#cccccc" },  // 0 = normal
++   { "#0066ff", "#ffffff", "#0066ff" },  // 1 = selected
++   { "#0066ff", "#0066ff", "#ffffff" },  // 2 = urgent/warning
++   { "#ff0000", "#ffffff", "#ff0000" },  // 3 = error
++   // add more here
++};
+ static const char font[]            = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*";
+-static const char normbordercolor[] = "#cccccc";
+-static const char normbgcolor[]     = "#cccccc";
+-static const char normfgcolor[]     = "#000000";
+-static const char selbordercolor[]  = "#0066ff";
+-static const char selbgcolor[]      = "#0066ff";
+-static const char selfgcolor[]      = "#ffffff";
+ static const unsigned int borderpx  = 1;        /* border pixel of windows */
+ static const unsigned int snap      = 32;       /* snap pixel */
+ static const Bool showbar           = True;     /* False means no bar */
+@@ -45,7 +48,7 @@ static const Layout layouts[] = {
+ #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
+ 
+ /* commands */
+-static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL };
++static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", colors[0][ColBG], "-nf", colors[0][ColFG],"-sb", colors[1][ColBG], "-sf", colors[1][ColFG], NULL };
+ static const char *termcmd[]  = { "uxterm", NULL };
+ 
+ static Key keys[] = {
+Only in dwm-5.9: config.h
+Only in dwm-5.9: dwm
+diff -up dwm-5.9/dwm.c dwm-5.9-colors/dwm.c
+--- dwm-5.9/dwm.c	2011-07-10 16:24:25.000000000 -0400
++++ dwm-5.9-colors/dwm.c	2011-08-18 02:07:20.788935100 -0400
+@@ -48,6 +48,7 @@
+ #define LENGTH(X)               (sizeof X / sizeof X[0])
+ #define MAX(A, B)               ((A) > (B) ? (A) : (B))
+ #define MIN(A, B)               ((A) < (B) ? (A) : (B))
++#define MAXCOLORS               8
+ #define MOUSEMASK               (BUTTONMASK|PointerMotionMask)
+ #define WIDTH(X)                ((X)->w + 2 * (X)->bw)
+ #define HEIGHT(X)               ((X)->h + 2 * (X)->bw)
+@@ -97,9 +98,8 @@ struct Client {
+ 
+ typedef struct {
+ 	int x, y, w, h;
+-	unsigned long norm[ColLast];
+-	unsigned long sel[ColLast];
+-	Drawable drawable;
++	unsigned long colors[MAXCOLORS][ColLast];
++ 	Drawable drawable;
+ 	GC gc;
+ 	struct {
+ 		int ascent;
+@@ -175,8 +175,9 @@ static void die(const char *errstr, ...)
+ static Monitor *dirtomon(int dir);
+ static void drawbar(Monitor *m);
+ static void drawbars(void);
+-static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]);
+-static void drawtext(const char *text, unsigned long col[ColLast], Bool invert);
++static void drawcoloredtext(char *text);
++static void drawsquare(Bool filled, Bool empty, unsigned long col[ColLast]);
++static void drawtext(const char *text, unsigned long col[ColLast], Bool pad);
+ static void enternotify(XEvent *e);
+ static void expose(XEvent *e);
+ static void focus(Client *c);
+@@ -736,14 +737,13 @@ drawbar(Monitor *m) {
+ 	dc.x = 0;
+ 	for(i = 0; i < LENGTH(tags); i++) {
+ 		dc.w = TEXTW(tags[i]);
+-		col = m->tagset[m->seltags] & 1 << i ? dc.sel : dc.norm;
+-		drawtext(tags[i], col, urg & 1 << i);
+-		drawsquare(m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
+-		           occ & 1 << i, urg & 1 << i, col);
++		col = dc.colors[ (m->tagset[m->seltags] & 1 << i ? 1:(urg & 1 << i ? 2:0))];
++		drawtext(tags[i], col, True);
++		drawsquare(m == selmon && selmon->sel && selmon->sel->tags & 1 << i, occ & 1 << i, col);
+ 		dc.x += dc.w;
+ 	}
+ 	dc.w = blw = TEXTW(m->ltsymbol);
+-	drawtext(m->ltsymbol, dc.norm, False);
++	drawtext(m->ltsymbol, dc.colors[0], True);
+ 	dc.x += dc.w;
+ 	x = dc.x;
+ 	if(m == selmon) { /* status is only drawn on selected monitor */
+@@ -753,19 +753,19 @@ drawbar(Monitor *m) {
+ 			dc.x = x;
+ 			dc.w = m->ww - x;
+ 		}
+-		drawtext(stext, dc.norm, False);
++		drawcoloredtext(stext);
+ 	}
+ 	else
+ 		dc.x = m->ww;
+ 	if((dc.w = dc.x - x) > bh) {
+ 		dc.x = x;
+ 		if(m->sel) {
+-			col = m == selmon ? dc.sel : dc.norm;
+-			drawtext(m->sel->name, col, False);
+-			drawsquare(m->sel->isfixed, m->sel->isfloating, False, col);
++			col = m == selmon ? dc.colors[1] : dc.colors[0];
++			drawtext(m->sel->name, col, True);
++			drawsquare(m->sel->isfixed, m->sel->isfloating, col);
+ 		}
+ 		else
+-			drawtext(NULL, dc.norm, False);
++			drawtext(NULL, dc.colors[0], False);
+ 	}
+ 	XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0, m->ww, bh, 0, 0);
+ 	XSync(dpy, False);
+@@ -780,10 +780,39 @@ drawbars(void) {
+ }
+ 
+ void
+-drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) {
+-	int x;
++drawcoloredtext(char *text) {
++	Bool first=True;
++	char *buf = text, *ptr = buf, c = 1;
++	unsigned long *col = dc.colors[0];
++	int i, ox = dc.x;
++
++	while( *ptr ) {
++		for( i = 0; *ptr < 0 || *ptr > NUMCOLORS; i++, ptr++);
++		if( !*ptr ) break;
++		c=*ptr;
++		*ptr=0;
++		if( i ) {
++			dc.w = selmon->ww - dc.x;
++			drawtext(buf, col, first);
++			dc.x += textnw(buf, i) + textnw(&c,1);
++			if( first ) dc.x += ( dc.font.ascent + dc.font.descent ) / 2;
++			first = False;
++		} else if( first ) {
++			ox = dc.x += textnw(&c,1);
++		}
++		*ptr = c;
++		col = dc.colors[ c-1 ];
++		buf = ++ptr;
++	}
++	if( !first ) dc.x-=(dc.font.ascent+dc.font.descent)/2;
++	drawtext(buf, col, True);
++	dc.x = ox;
++}
+ 
+-	XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]);
++void
++drawsquare(Bool filled, Bool empty, unsigned long col[ColLast]) {
++	int x;
++	XSetForeground(dpy, dc.gc, col[ ColFG ]);
+ 	x = (dc.font.ascent + dc.font.descent + 2) / 4;
+ 	if(filled)
+ 		XFillRectangle(dpy, dc.drawable, dc.gc, dc.x+1, dc.y+1, x+1, x+1);
+@@ -792,17 +821,17 @@ drawsquare(Bool filled, Bool empty, Bool
+ }
+ 
+ void
+-drawtext(const char *text, unsigned long col[ColLast], Bool invert) {
++drawtext(const char *text, unsigned long col[ColLast], Bool pad) {
+ 	char buf[256];
+ 	int i, x, y, h, len, olen;
+ 
+-	XSetForeground(dpy, dc.gc, col[invert ? ColFG : ColBG]);
++	XSetForeground(dpy, dc.gc, col[ ColBG ]);
+ 	XFillRectangle(dpy, dc.drawable, dc.gc, dc.x, dc.y, dc.w, dc.h);
+ 	if(!text)
+ 		return;
+ 	olen = strlen(text);
+-	h = dc.font.ascent + dc.font.descent;
+-	y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
++	h = pad ? (dc.font.ascent + dc.font.descent) : 0;
++	y = dc.y + ((dc.h + dc.font.ascent - dc.font.descent) / 2);
+ 	x = dc.x + (h / 2);
+ 	/* shorten text if necessary */
+ 	for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--);
+@@ -811,7 +840,7 @@ drawtext(const char *text, unsigned long
+ 	memcpy(buf, text, len);
+ 	if(len < olen)
+ 		for(i = len; i && i > len - 3; buf[--i] = '.');
+-	XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]);
++	XSetForeground(dpy, dc.gc, col[ ColFG ]);
+ 	if(dc.font.set)
+ 		XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len);
+ 	else
+@@ -861,7 +890,7 @@ focus(Client *c) {
+ 		detachstack(c);
+ 		attachstack(c);
+ 		grabbuttons(c, True);
+-		XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]);
++		XSetWindowBorder(dpy, c->win, dc.colors[1][ColBorder]);
+ 		setfocus(c);
+ 	}
+ 	else
+@@ -1137,7 +1166,7 @@ manage(Window w, XWindowAttributes *wa)
+ 	}
+ 	wc.border_width = c->bw;
+ 	XConfigureWindow(dpy, w, CWBorderWidth, &wc);
+-	XSetWindowBorder(dpy, w, dc.norm[ColBorder]);
++	XSetWindowBorder(dpy, w, dc.colors[0][ColBorder]);
+ 	configure(c); /* propagates border_width, if size doesn't change */
+ 	updatesizehints(c);
+ 	updatewmhints(c);
+@@ -1550,12 +1579,11 @@ setup(void) {
+ 	cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
+ 	cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
+ 	/* init appearance */
+-	dc.norm[ColBorder] = getcolor(normbordercolor);
+-	dc.norm[ColBG] = getcolor(normbgcolor);
+-	dc.norm[ColFG] = getcolor(normfgcolor);
+-	dc.sel[ColBorder] = getcolor(selbordercolor);
+-	dc.sel[ColBG] = getcolor(selbgcolor);
+-	dc.sel[ColFG] = getcolor(selfgcolor);
++	for(int i=0; i<NUMCOLORS; i++) {
++		dc.colors[i][ColBorder] = getcolor( colors[i][ColBorder] );
++		dc.colors[i][ColFG] = getcolor( colors[i][ColFG] );
++		dc.colors[i][ColBG] = getcolor( colors[i][ColBG] );
++	}
+ 	dc.drawable = XCreatePixmap(dpy, root, DisplayWidth(dpy, screen), bh, DefaultDepth(dpy, screen));
+ 	dc.gc = XCreateGC(dpy, root, 0, NULL);
+ 	XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
+@@ -1716,7 +1744,7 @@ unfocus(Client *c, Bool setfocus) {
+ 	if(!c)
+ 		return;
+ 	grabbuttons(c, False);
+-	XSetWindowBorder(dpy, c->win, dc.norm[ColBorder]);
++	XSetWindowBorder(dpy, c->win, dc.colors[0][ColBorder]);
+ 	if(setfocus)
+ 		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
+ }
+Only in dwm-5.9: dwm.o

Build/dwm-patches/statuscolors-6.0.diff

+diff -u a/config.h b/config.h
+--- a/config.h	2011-12-27 09:47:40.000000000 +1300
++++ b/config.h	2011-12-27 09:46:23.000000000 +1300
+@@ -2,12 +2,19 @@
+ 
+ /* appearance */
+ static const char font[]            = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*";
+-static const char normbordercolor[] = "#444444";
+-static const char normbgcolor[]     = "#222222";
+-static const char normfgcolor[]     = "#bbbbbb";
+-static const char selbordercolor[]  = "#005577";
+-static const char selbgcolor[]      = "#005577";
+-static const char selfgcolor[]      = "#eeeeee";
++#define NUMCOLORS 9 
++static const char colors[NUMCOLORS][ColLast][9] = {
++// border foreground background
++{ "#212121", "#696969", "#121212" }, // 0 = normal
++{ "#696969", "#E0E0E0", "#121212" }, // 1 = selected
++{ "#212121", "#CF4F88", "#121212" }, // 2 = red
++{ "#212121", "#53A6A6", "#121212" }, // 3 = green
++{ "#212121", "#914E89", "#121212" }, // 4 = yellow
++{ "#212121", "#4779B3", "#121212" }, // 5 = blue
++{ "#212121", "#47959E", "#121212" }, // 6 = cyan
++{ "#212121", "#7E62B3", "#121212" }, // 7 = magenta
++{ "#212121", "#899CA1", "#121212" }, // 8 = grey
++};
+ static const unsigned int borderpx  = 1;        /* border pixel of windows */
+ static const unsigned int snap      = 32;       /* snap pixel */
+ static const Bool showbar           = True;     /* False means no bar */
+@@ -46,7 +53,7 @@
+ #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
+ 
+ /* commands */
+-static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL };
++static const char  *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", colors[0][ColBG], "-nf", colors[0][ColFG], "-sb", colors[1][ColBG], "-sf", colors[1][ColFG], NULL };
+ static const char *termcmd[]  = { "uxterm", NULL };
+ 
+ static Key keys[] = {
+diff -u a/dwm.c b/dwm.c
+--- a/dwm.c	2011-12-27 09:47:17.000000000 +1300
++++ b/dwm.c	2011-12-27 09:46:52.000000000 +1300
+@@ -49,6 +49,7 @@
+ #define LENGTH(X)               (sizeof X / sizeof X[0])
+ #define MAX(A, B)               ((A) > (B) ? (A) : (B))
+ #define MIN(A, B)               ((A) < (B) ? (A) : (B))
++#define MAXCOLORS 9             // avoid circular reference to NUMCOLORS
+ #define MOUSEMASK               (BUTTONMASK|PointerMotionMask)
+ #define WIDTH(X)                ((X)->w + 2 * (X)->bw)
+ #define HEIGHT(X)               ((X)->h + 2 * (X)->bw)
+@@ -99,8 +100,7 @@
+ 
+ typedef struct {
+ 	int x, y, w, h;
+-	unsigned long norm[ColLast];
+-	unsigned long sel[ColLast];
++    unsigned long colors[MAXCOLORS][ColLast];
+ 	Drawable drawable;
+ 	GC gc;
+ 	struct {
+@@ -178,8 +178,9 @@
+ static Monitor *dirtomon(int dir);
+ static void drawbar(Monitor *m);
+ static void drawbars(void);
+-static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]);
+-static void drawtext(const char *text, unsigned long col[ColLast], Bool invert);
++static void drawcoloredtext(char *text);
++static void drawsquare(Bool filled, Bool empty, unsigned long col[ColLast]);
++static void drawtext(const char *text, unsigned long col[ColLast], Bool pad);
+ static void enternotify(XEvent *e);
+ static void expose(XEvent *e);
+ static void focus(Client *c);
+@@ -730,36 +731,37 @@
+ 	dc.x = 0;
+ 	for(i = 0; i < LENGTH(tags); i++) {
+ 		dc.w = TEXTW(tags[i]);
+-		col = m->tagset[m->seltags] & 1 << i ? dc.sel : dc.norm;
+-		drawtext(tags[i], col, urg & 1 << i);
++        col = dc.colors[ (m->tagset[m->seltags] & 1 << i) ?
++        1 : (urg & 1 << i ? 2:0) ];
++        drawtext(tags[i], col, True);
+ 		drawsquare(m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
+-		           occ & 1 << i, urg & 1 << i, col);
++		           occ & 1 << i, col);
+ 		dc.x += dc.w;
+ 	}
+ 	dc.w = blw = TEXTW(m->ltsymbol);
+-	drawtext(m->ltsymbol, dc.norm, False);
++	drawtext(m->ltsymbol, dc.colors[0], False);
+ 	dc.x += dc.w;
+ 	x = dc.x;
+ 	if(m == selmon) { /* status is only drawn on selected monitor */
+-		dc.w = TEXTW(stext);
++        dc.w = textnw(stext, strlen(stext)); // no padding
+ 		dc.x = m->ww - dc.w;
+ 		if(dc.x < x) {
+ 			dc.x = x;
+ 			dc.w = m->ww - x;
+ 		}
+-		drawtext(stext, dc.norm, False);
++        drawcoloredtext(stext);
+ 	}
+ 	else
+ 		dc.x = m->ww;
+ 	if((dc.w = dc.x - x) > bh) {
+ 		dc.x = x;
+ 		if(m->sel) {
+-			col = m == selmon ? dc.sel : dc.norm;
+-			drawtext(m->sel->name, col, False);
+-			drawsquare(m->sel->isfixed, m->sel->isfloating, False, col);
++        col = dc.colors[ m == selmon ? 1 : 0 ];
++        drawtext(m->sel->name, col, True);
++        drawsquare(m->sel->isfixed, m->sel->isfloating, col);
+ 		}
+ 		else
+-			drawtext(NULL, dc.norm, False);
++			drawtext(NULL, dc.colors[0], False);
+ 	}
+ 	XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0, m->ww, bh, 0, 0);
+ 	XSync(dpy, False);
+@@ -774,10 +776,35 @@
+ }
+ 
+ void
+-drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) {
++drawcoloredtext(char *text) {
++    char *buf = text, *ptr = buf, c = 1;
++    unsigned long *col = dc.colors[0];
++    int i, ox = dc.x;
++
++    while( *ptr ) {
++    for( i = 0; *ptr < 0 || *ptr > NUMCOLORS; i++, ptr++);
++        if( !*ptr ) break;
++        c=*ptr;
++        *ptr=0;
++            if( i ) {
++            dc.w = selmon->ww - dc.x;
++            drawtext(buf, col, False);
++            dc.x += textnw(buf, i);
++            }
++        *ptr = c;
++        col = dc.colors[ c-1 ];
++        buf = ++ptr;
++        }
++    drawtext(buf, col, False);
++    dc.x = ox;
++}
++
++void
++drawsquare(Bool filled, Bool empty, unsigned long col[ColLast]) {
++
+ 	int x;
+ 
+-	XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]);
++	XSetForeground(dpy, dc.gc, col[ColFG]);
+ 	x = (dc.font.ascent + dc.font.descent + 2) / 4;
+ 	if(filled)
+ 		XFillRectangle(dpy, dc.drawable, dc.gc, dc.x+1, dc.y+1, x+1, x+1);
+@@ -786,17 +813,17 @@
+ }
+ 
+ void
+-drawtext(const char *text, unsigned long col[ColLast], Bool invert) {
++drawtext(const char *text, unsigned long col[ColLast], Bool pad) {
+ 	char buf[256];
+ 	int i, x, y, h, len, olen;
+ 
+-	XSetForeground(dpy, dc.gc, col[invert ? ColFG : ColBG]);
++	XSetForeground(dpy, dc.gc, col[ColBG]);
+ 	XFillRectangle(dpy, dc.drawable, dc.gc, dc.x, dc.y, dc.w, dc.h);
+ 	if(!text)
+ 		return;
+ 	olen = strlen(text);
+-	h = dc.font.ascent + dc.font.descent;
+-	y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
++    h = pad ? (dc.font.ascent + dc.font.descent) : 0;
++    y = dc.y + ((dc.h + dc.font.ascent - dc.font.descent) / 2);
+ 	x = dc.x + (h / 2);
+ 	/* shorten text if necessary */
+ 	for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--);
+@@ -805,7 +832,7 @@
+ 	memcpy(buf, text, len);
+ 	if(len < olen)
+ 		for(i = len; i && i > len - 3; buf[--i] = '.');
+-	XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]);
++	XSetForeground(dpy, dc.gc, col[ColFG]);
+ 	if(dc.font.set)
+ 		XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len);
+ 	else
+@@ -855,7 +882,7 @@
+ 		detachstack(c);
+ 		attachstack(c);
+ 		grabbuttons(c, True);
+-		XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]);
++		XSetWindowBorder(dpy, c->win, dc.colors[1][ColBorder]);
+ 		setfocus(c);
+ 	}
+ 	else
+@@ -1144,7 +1171,7 @@
+ 
+ 	wc.border_width = c->bw;
+ 	XConfigureWindow(dpy, w, CWBorderWidth, &wc);
+-	XSetWindowBorder(dpy, w, dc.norm[ColBorder]);
++    XSetWindowBorder(dpy, w, dc.colors[0][ColBorder]);
+ 	configure(c); /* propagates border_width, if size doesn't change */
+ 	updatewindowtype(c);
+ 	updatesizehints(c);
+@@ -1612,12 +1639,11 @@
+ 	cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
+ 	cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
+ 	/* init appearance */
+-	dc.norm[ColBorder] = getcolor(normbordercolor);
+-	dc.norm[ColBG] = getcolor(normbgcolor);
+-	dc.norm[ColFG] = getcolor(normfgcolor);
+-	dc.sel[ColBorder] = getcolor(selbordercolor);
+-	dc.sel[ColBG] = getcolor(selbgcolor);
+-	dc.sel[ColFG] = getcolor(selfgcolor);
++    for(int i=0; i<NUMCOLORS; i++) {
++    dc.colors[i][ColBorder] = getcolor( colors[i][ColBorder] );
++    dc.colors[i][ColFG] = getcolor( colors[i][ColFG] );
++    dc.colors[i][ColBG] = getcolor( colors[i][ColBG] );
++    }
+ 	dc.drawable = XCreatePixmap(dpy, root, DisplayWidth(dpy, screen), bh, DefaultDepth(dpy, screen));
+ 	dc.gc = XCreateGC(dpy, root, 0, NULL);
+ 	XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
+@@ -1692,13 +1718,27 @@
+ 
+ int
+ textnw(const char *text, unsigned int len) {
++    // remove non-printing color codes before calculating width
++    char *ptr = (char *) text;
++    unsigned int i, ibuf, lenbuf=len;
++    char buf[len+1];
+ 	XRectangle r;
+ 
++     for(i=0, ibuf=0; *ptr && i<len; i++, ptr++) {
++    if(*ptr <= NUMCOLORS && *ptr > 0) {
++        if (i < len) { lenbuf--; }
++        } else {
++        buf[ibuf]=*ptr;
++        ibuf++;
++        }
++    }
++ buf[ibuf]=0;
++
+ 	if(dc.font.set) {
+-		XmbTextExtents(dc.font.set, text, len, NULL, &r);
++    XmbTextExtents(dc.font.set, buf, lenbuf, NULL, &r);
+ 		return r.width;
+ 	}
+-	return XTextWidth(dc.font.xfont, text, len);
++	return XTextWidth(dc.font.xfont, buf, lenbuf);
+ }
+ 
+ void
+@@ -1776,7 +1816,7 @@
+ 	if(!c)
+ 		return;
+ 	grabbuttons(c, False);
+-	XSetWindowBorder(dpy, c->win, dc.norm[ColBorder]);
++	XSetWindowBorder(dpy, c->win, dc.colors[0][ColBorder]);
+ 	if(setfocus)
+ 		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
+ }

Build/dwm-patches/statuscolors-6.1.diff

+--- a/dwm.c	2012-11-08 17:13:57.878644037 +1300
++++ b/dwm.c	2012-11-08 17:14:39.475091103 +1300
+@@ -52,6 +52,7 @@
+ #define LENGTH(X)               (sizeof X / sizeof X[0])
+ #define MAX(A, B)               ((A) > (B) ? (A) : (B))
+ #define MIN(A, B)               ((A) < (B) ? (A) : (B))
++#define MAXCOLORS				9
+ #define MOUSEMASK               (BUTTONMASK|PointerMotionMask)
+ #define WIDTH(X)                ((X)->w + 2 * (X)->bw)
+ #define HEIGHT(X)               ((X)->h + 2 * (X)->bw)
+@@ -102,8 +103,7 @@
+ 
+ typedef struct {
+ 	int x, y, w, h;
+-	XftColor norm[ColLast];
+-	XftColor sel[ColLast];
++	XftColor colors[MAXCOLORS][ColLast];
+ 	Drawable drawable;
+ 	GC gc;
+ 	struct {
+@@ -180,8 +180,9 @@
+ static Monitor *dirtomon(int dir);
+ static void drawbar(Monitor *m);
+ static void drawbars(void);
+-static void drawsquare(Bool filled, Bool empty, Bool invert, XftColor col[ColLast]);
+-static void drawtext(const char *text, XftColor col[ColLast], Bool invert);
++static void drawcoloredtext(char *text);
++static void drawsquare(Bool filled, Bool empty, XftColor col[ColLast]);
++static void drawtext(const char *text, XftColor col[ColLast], Bool pad);
+ static void enternotify(XEvent *e);
+ static void expose(XEvent *e);
+ static void focus(Client *c);
+@@ -731,36 +732,36 @@
+ 	dc.x = 0;
+ 	for(i = 0; i < LENGTH(tags); i++) {
+ 		dc.w = TEXTW(tags[i]);
+-		col = m->tagset[m->seltags] & 1 << i ? dc.sel : dc.norm;
+-		drawtext(tags[i], col, urg & 1 << i);
+-		drawsquare(m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
+-		           occ & 1 << i, urg & 1 << i, col);
++		col = dc.colors[ (m->tagset[m->seltags] & 1 << i) ? 1 : (urg & 1 << i ? 2:0) ];
++        drawtext(tags[i], col, True);
++		drawsquare(m == selmon && selmon->sel && selmon->sel->tags & 1 << i, 
++                occ & 1 << i, col);
+ 		dc.x += dc.w;
+ 	}
+ 	dc.w = blw = TEXTW(m->ltsymbol);
+-	drawtext(m->ltsymbol, dc.norm, False);
++	drawtext(m->ltsymbol, dc.colors[0], False);
+ 	dc.x += dc.w;
+ 	x = dc.x;
+ 	if(m == selmon) { /* status is only drawn on selected monitor */
+-		dc.w = TEXTW(stext);
++		dc.w = textnw(stext, strlen(stext)); // no padding
+ 		dc.x = m->ww - dc.w;
+ 		if(dc.x < x) {
+ 			dc.x = x;
+ 			dc.w = m->ww - x;
+ 		}
+-		drawtext(stext, dc.norm, False);
++		drawcoloredtext(stext);
+ 	}
+ 	else
+ 		dc.x = m->ww;
+ 	if((dc.w = dc.x - x) > bh) {
+ 		dc.x = x;
+ 		if(m->sel) {
+-			col = m == selmon ? dc.sel : dc.norm;
+-			drawtext(m->sel->name, col, False);
+-			drawsquare(m->sel->isfixed, m->sel->isfloating, False, col);
++			col = dc.colors[ m == selmon ? 1 : 0 ];
++			drawtext(m->sel->name, col, True);
++			drawsquare(m->sel->isfixed, m->sel->isfloating, col);
+ 		}
+ 		else
+-			drawtext(NULL, dc.norm, False);
++			drawtext(NULL, dc.colors[0], False);
+ 	}
+ 	XCopyArea(dpy, dc.drawable, m->barwin, dc.gc, 0, 0, m->ww, bh, 0, 0);
+ 	XSync(dpy, False);
+@@ -775,10 +776,34 @@
+ }
+ 
+ void
+-drawsquare(Bool filled, Bool empty, Bool invert, XftColor col[ColLast]) {
++drawcoloredtext(char *text) {
++    char *buf = text, *ptr = buf, c = 1;
++    XftColor *col = dc.colors[0];
++    int i, ox = dc.x;
++
++	while( *ptr ) {
++    for( i = 0; *ptr < 0 || *ptr > NUMCOLORS; i++, ptr++);
++        if( !*ptr ) break;
++        c=*ptr;
++        *ptr=0;
++            if( i ) {
++            dc.w = selmon->ww - dc.x;
++            drawtext(buf, col, False);
++            dc.x += textnw(buf, i);
++            }
++        *ptr = c;
++        col = dc.colors[ c-1 ];
++        buf = ++ptr;
++        }
++    drawtext(buf, col, False);
++    dc.x = ox;
++}
++
++void
++drawsquare(Bool filled, Bool empty, XftColor col[ColLast]) {
+ 	int x;
+ 
+-	XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG].pixel);
++	XSetForeground(dpy, dc.gc, col[ColFG].pixel);
+ 	x = (dc.font.ascent + dc.font.descent + 2) / 4;
+ 	if(filled)
+ 		XFillRectangle(dpy, dc.drawable, dc.gc, dc.x+1, dc.y+1, x+1, x+1);
+@@ -787,18 +812,18 @@
+ }
+ 
+ void
+-drawtext(const char *text, XftColor col[ColLast], Bool invert) {
++drawtext(const char *text, XftColor col[ColLast], Bool pad) {
+ 	char buf[256];
+ 	int i, x, y, h, len, olen;
+ 	XftDraw *d;
+ 
+-	XSetForeground(dpy, dc.gc, col[invert ? ColFG : ColBG].pixel);
++	XSetForeground(dpy, dc.gc, col[ColBG].pixel);
+ 	XFillRectangle(dpy, dc.drawable, dc.gc, dc.x, dc.y, dc.w, dc.h);
+ 	if(!text)
+ 		return;
+ 	olen = strlen(text);
+-	h = dc.font.ascent + dc.font.descent;
+-	y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
++	h = pad ? (dc.font.ascent + dc.font.descent) : 0;
++	y = dc.y + ((dc.h + dc.font.ascent - dc.font.descent) / 2);
+ 	x = dc.x + (h / 2);
+ 	/* shorten text if necessary */
+ 	for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--);
+@@ -810,7 +835,7 @@
+ 
+ 	d = XftDrawCreate(dpy, dc.drawable, DefaultVisual(dpy, screen), DefaultColormap(dpy,screen));
+ 
+-	XftDrawStringUtf8(d, &col[invert ? ColBG : ColFG], dc.font.xfont, x, y, (XftChar8 *) buf, len);
++	XftDrawStringUtf8(d, (XftColor *) &col[ColFG].pixel, dc.font.xfont, x, y, (XftChar8 *) buf, len);
+ 	XftDrawDestroy(d);
+ }
+ 
+@@ -857,7 +882,7 @@
+ 		detachstack(c);
+ 		attachstack(c);
+ 		grabbuttons(c, True);
+-		XSetWindowBorder(dpy, c->win, dc.sel[ColBorder].pixel);
++		XSetWindowBorder(dpy, c->win, dc.colors[1][ColBorder].pixel);
+ 		setfocus(c);
+ 	}
+ 	else {
+@@ -1127,7 +1152,7 @@
+ 
+ 	wc.border_width = c->bw;
+ 	XConfigureWindow(dpy, w, CWBorderWidth, &wc);
+-	XSetWindowBorder(dpy, w, dc.norm[ColBorder].pixel);
++	XSetWindowBorder(dpy, w, dc.colors[0][ColBorder].pixel);
+ 	configure(c); /* propagates border_width, if size doesn't change */
+ 	updatewindowtype(c);
+ 	updatesizehints(c);
+@@ -1607,12 +1632,11 @@
+ 	cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
+ 	cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
+ 	/* init appearance */
+-	dc.norm[ColBorder] = getcolor(normbordercolor);
+-	dc.norm[ColBG] = getcolor(normbgcolor);
+-	dc.norm[ColFG] = getcolor(normfgcolor);
+-	dc.sel[ColBorder] = getcolor(selbordercolor);
+-	dc.sel[ColBG] = getcolor(selbgcolor);
+-	dc.sel[ColFG] = getcolor(selfgcolor);
++	for(int i=0; i<NUMCOLORS; i++) {
++		dc.colors[i][ColBorder] = getcolor( colors[i][ColBorder] );
++		dc.colors[i][ColFG] = getcolor( colors[i][ColFG] );
++		dc.colors[i][ColBG] = getcolor( colors[i][ColBG] );
++	}
+ 	dc.drawable = XCreatePixmap(dpy, root, DisplayWidth(dpy, screen), bh, DefaultDepth(dpy, screen));
+ 	dc.gc = XCreateGC(dpy, root, 0, NULL);
+ 	XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
+@@ -1686,8 +1710,23 @@
+ 
+ int
+ textnw(const char *text, unsigned int len) {
++	// remove non-printing color codes before calculating width
++	char *ptr = (char *) text;
++	unsigned int i, ibuf, lenbuf=len;
++	char buf[len+1];
++
++	for(i=0, ibuf=0; *ptr && i<len; i++, ptr++) {
++		if(*ptr <= NUMCOLORS && *ptr > 0) {
++			if (i < len) { lenbuf--; }
++		} else {
++			buf[ibuf]=*ptr;
++			ibuf++;
++		}
++	}
++	buf[ibuf]=0;
++
+ 	XGlyphInfo ext;
+-	XftTextExtentsUtf8(dpy, dc.font.xfont, (XftChar8 *) text, len, &ext);
++	XftTextExtentsUtf8(dpy, dc.font.xfont, (XftChar8 *) buf, lenbuf, &ext);
+ 	return ext.xOff;
+ }
+ 
+@@ -1768,7 +1807,7 @@
+ 	if(!c)
+ 		return;
+ 	grabbuttons(c, False);
+-	XSetWindowBorder(dpy, c->win, dc.norm[ColBorder].pixel);
++	XSetWindowBorder(dpy, c->win, dc.colors[0][ColBorder].pixel);
+ 	if(setfocus) {
+ 		XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
+ 		XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
+@@ -2040,8 +2079,11 @@
+ 			wmh->flags &= ~XUrgencyHint;
+ 			XSetWMHints(dpy, c->win, wmh);
+ 		}
+-		else
++		else {
+ 			c->isurgent = (wmh->flags & XUrgencyHint) ? True : False;
++			if(c->isurgent)
++				XSetWindowBorder(dpy, c->win, dc.colors[2][ColBorder].pixel);
++		}
+ 		if(wmh->flags & InputHint)
+ 			c->neverfocus = !wmh->input;
+ 		else

Build/dwm-patches/useless-gaps-5.7.2.diff

+--- a/dwm.c	2009-09-28 03:20:23.000000000 +0800
++++ b/dwm.c	2010-03-10 01:55:42.507801441 +0800
+@@ -200,6 +200,7 @@
+ static void propertynotify(XEvent *e);
+ static void quit(const Arg *arg);
+ static void resize(Client *c, int x, int y, int w, int h, Bool interact);
++static void resize_orig_gapless(Client *c, int x, int y, int w, int h, Bool interact);
+ static void resizemouse(const Arg *arg);
+ static void restack(Monitor *m);
+ static void run(void);
+@@ -1189,7 +1234,7 @@
+ 	if(n > 0) /* override layout symbol */
+ 		snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);