[dwm] [patch] Stack columns patch for dwm-4.4.1

From: Chris Webb <chris_AT_arachsys.com>
Date: Sun, 9 Sep 2007 17:57:31 +0100

Below is a patch for the current release (4.4.1) of dwm which enables
multiple columns in the stacking area. It introduces variables nrows and
ncols with corresponding default values NROWS and NCOLS in
config.h.default, and corresponding setnrows() and setncols() for use in
keybindings.

If nrows == ncols == 0, tile() behaves in the normal manner. When nrows >
0, tile() creates an extra column if adding another window to the current
one would cause it to exceed nrows clients. If ncols > 0, the maximum
number of columns created cannot exceed ncols, overriding the nrows
setting. The patch also reintroduces nmaster in a similar way to the
existing nmaster patch, but allows it to be zero to simulate a grid mode.
Where there are not enough windows to fill all the columns evenly, the
extra space is used by the top-most client in the first column.

I'd be interested in any feedback. (I use this 'extended tiling' mode
myself, and so intend to maintain the patch going forward.)

Best wishes,

Chris.

diff -uNrd dwm-4.4.1.orig/config.default.h dwm-4.4.1/config.default.h
--- dwm-4.4.1.orig/config.default.h 2007-08-26 11:53:49.000000000 +0100
+++ dwm-4.4.1/config.default.h 2007-09-09 16:35:23.000000000 +0100
@@ -33,6 +33,9 @@
         { "><>", floating }, \
 };
 #define MWFACT 0.6 /* master width factor [0.1 .. 0.9] */
+#define NMASTER 1 /* clients in master area */
+#define NROWS 2 /* clients per column in stacking area */
+#define NCOLS 3 /* maximum number of stacking area columns */
 #define SNAP 32 /* snap pixel */
 
 /* key definitions */
@@ -48,6 +51,12 @@
         { MODKEY, XK_k, focusprev, NULL }, \
         { MODKEY, XK_h, setmwfact, "-0.05" }, \
         { MODKEY, XK_l, setmwfact, "+0.05" }, \
+ { MODKEY|ShiftMask, XK_j, setnrows, "-1" }, \
+ { MODKEY|ShiftMask, XK_k, setnrows, "+1" }, \
+ { MODKEY|ControlMask, XK_j, setncols, "-1" }, \
+ { MODKEY|ControlMask, XK_k, setncols, "+1" }, \
+ { MODKEY|ShiftMask, XK_h, setnmaster, "-1" }, \
+ { MODKEY|ShiftMask, XK_l, setnmaster, "+1" }, \
         { MODKEY, XK_m, togglemax, NULL }, \
         { MODKEY, XK_Return, zoom, NULL }, \
         { MODKEY|ShiftMask, XK_space, togglefloating, NULL }, \
diff -uNrd dwm-4.4.1.orig/tile.c dwm-4.4.1/tile.c
--- dwm-4.4.1.orig/tile.c 2007-08-26 11:53:49.000000000 +0100
+++ dwm-4.4.1/tile.c 2007-09-09 16:34:17.000000000 +0100
@@ -5,10 +5,82 @@
 /* static */
 
 static double mwfact = MWFACT;
+static unsigned int nmaster = NMASTER;
+static unsigned int nrows = NROWS;
+static unsigned int ncols = NCOLS;
 
 /* extern */
 
 void
+setnmaster(const char *arg) {
+ int i;
+
+ if(!isarrange(tile))
+ return;
+ if(!arg)
+ i = NMASTER;
+ else if(arg[0] != '+' && arg[0] != '-')
+ i = atoi(arg);
+ else
+ i = nmaster + atoi(arg);
+
+ if(i < 0 || wah <= 2 * BORDERPX * i)
+ return;
+
+ nmaster = i;
+ if(sel)
+ arrange();
+ else
+ drawstatus();
+}
+
+void
+setnrows(const char *arg) {
+ int i;
+
+ if(!isarrange(tile))
+ return;
+ if(!arg)
+ i = NROWS;
+ else if(arg[0] != '+' && arg[0] != '-')
+ i = atoi(arg);
+ else
+ i = nrows + atoi(arg);
+
+ if(i < 0 || wah <= 2 * BORDERPX * i)
+ return;
+ nrows = i;
+
+ if(sel)
+ arrange();
+ else
+ drawstatus();
+}
+
+void
+setncols(const char *arg) {
+ int i;
+
+ if(!isarrange(tile))
+ return;
+ if(!arg)
+ i = NCOLS;
+ else if(arg[0] != '+' && arg[0] != '-')
+ i = atoi(arg);
+ else
+ i = ncols + atoi(arg);
+
+ if((i < 0) || (i >= 1 && waw / i <= 2 * BORDERPX))
+ return;
+ ncols = i;
+
+ if(sel)
+ arrange();
+ else
+ drawstatus();
+}
+
+void
 setmwfact(const char *arg) {
         double delta;
 
@@ -32,40 +104,79 @@
 
 void
 tile(void) {
- unsigned int i, n, nx, ny, nw, nh, mw, th;
+ unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th, tw1, cols, rows, rows1;
         Client *c;
 
         for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
                 n++;
 
+ /* calculate correct number of rows */
+ if(ncols > 0 && n - nmaster > nrows * ncols)
+ rows = (n - nmaster) / ncols + ((n - nmaster) % ncols ? 1 : 0);
+ else
+ rows = nrows;
+
         /* window geoms */
- mw = (n == 1) ? waw : mwfact * waw;
- th = (n > 1) ? wah / (n - 1) : 0;
- if(n > 1 && th < bh)
- th = wah;
+ if (nmaster == 0) {
+ mh = mw = 0;
+ }
+ else if (n <= nmaster) {
+ mh = wah / (n > 0 ? n : 1);
+ mw = waw;
+ }
+ else {
+ mh = wah / nmaster;
+ mw = mwfact * waw;
+ }
+
+ if(rows == 0 || n <= nmaster + rows) {
+ rows1 = n > nmaster ? n - nmaster : 1;
+ tw = tw1 = waw - mw;
+ th = wah / rows1;
+ }
+ else {
+ rows1 = 1 + (n - nmaster - 1) % rows;
+ cols = (n - nmaster) / rows + ((n - nmaster) % rows ? 1 : 0);
+ tw = (waw - mw) / cols;
+ tw1 = waw - mw - (cols - 1) * tw;
+ th = wah / rows;
+ }
 
         nx = wax;
         ny = way;
+
         for(i = 0, c = nexttiled(clients); c; c = nexttiled(c->next), i++) {
                 c->ismax = False;
- if(i == 0) { /* master */
+ if(i < nmaster) { /* master column */
                         nw = mw - 2 * c->border;
- nh = wah - 2 * c->border;
+ nh = mh - 2 * c->border;
+ if(i == 0)
+ nh += wah - mh * (n < nmaster ? n : nmaster);
                 }
- else { /* tile window */
- if(i == 1) {
+ else if(i < nmaster + rows1) { /* first stack column */
+ if(i == nmaster) { /* initialise */
                                 ny = way;
                                 nx += mw;
+ nh = wah - 2*c->border - (rows1 - 1) * th;
                         }
- nw = waw - mw - 2 * c->border;
- if(i + 1 == n) /* remainder */
- nh = (way + wah) - ny - 2 * c->border;
- else
+ else {
                                 nh = th - 2 * c->border;
+ }
+ nw = tw1 - 2 * c->border;
+ }
+ else { /* successive stack columns - rows > 0 if we reach here */
+ if((i - nmaster - rows1) % rows == 0) { /* reinitialise */
+ ny = way;
+ nx += nw + 2 * c-> border;
+ nh = wah - 2*c->border - (rows - 1) * th;
+ }
+ else {
+ nh = th - 2 * c->border;
+ }
+ nw = tw - 2 * c->border;
                 }
                 resize(c, nx, ny, nw, nh, False);
- if(n > 1 && th != wah)
- ny += nh + 2 * c->border;
+ ny += nh + 2 * c->border;
         }
 }
 
diff -uNrd dwm-4.4.1.orig/tile.h dwm-4.4.1/tile.h
--- dwm-4.4.1.orig/tile.h 2007-08-26 11:53:49.000000000 +0100
+++ dwm-4.4.1/tile.h 2007-09-09 15:29:52.000000000 +0100
@@ -1,6 +1,9 @@
 /* See LICENSE file for copyright and license details. */
 
 /* tile.c */
+void setnmaster(const char *arg); /* sets nmaster value */
+void setnrows(const char *arg); /* sets nrows value */
+void setncols(const char *arg); /* sets ncols value */
 void setmwfact(const char *arg); /* sets master width factor */
 void tile(void); /* arranges all windows tiled */
 void zoom(const char *arg); /* zooms the focused client to master area, arg is ignored */
Received on Sun Sep 09 2007 - 18:57:33 UTC

This archive was generated by hypermail 2.2.0 : Sun Jul 13 2008 - 14:52:34 UTC