"Anselm R. Garbe" <[EMAIL PROTECTED]> writes:

> I keep in mind testing the togglemax-patch, but please let me
> know any issues in hg tip.

Working nicely here. I haven't been able to crash it nor persuade it to
behave strangely. The single dwm.c without any header files is indeed
easier to work with.

I ported both of my patches over to hg tip dwm (attached), removing the
ncols = 0 and nrows = 0 cases in the process (as suggested by pancake),
which simplified the code a bit.

For my own use, I've also ported the fibonacci and monocle layouts which
I use from time to time, and attached the combined patch which applies on
top of my 'pertag' tree, in case it's of use to anybody. The code is
slightly briefer in my copy of fibonacci but functionally identical.

Cheers,

Chris.
diff -uNrp dwm.orig/config.h dwm.colstack/config.h
--- dwm.orig/config.h   2007-09-19 12:42:52.000000000 +0100
+++ dwm.colstack/config.h       2007-09-19 13:07:55.000000000 +0100
@@ -29,6 +29,9 @@ Layout layouts[] = {
 };
 #define RESIZEHINTS            True    /* False - respect size hints in tiled 
resizals */
 #define MWFACT                 0.6     /* master width factor [0.1 .. 0.9] */
+#define NMASTER                        1       /* clients in master area */
+#define NROWS                  3       /* clients per column in stacking area 
*/
+#define NCOLS                  1       /* number of stacking area columns */
 #define SNAP                   32      /* snap pixel */
 
 /* key definitions */
@@ -47,6 +50,12 @@ Key keys[] = { \
        { 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 -uNrp dwm.orig/dwm.c dwm.colstack/dwm.c
--- dwm.orig/dwm.c      2007-09-19 12:42:53.000000000 +0100
+++ dwm.colstack/dwm.c  2007-09-19 13:35:50.000000000 +0100
@@ -166,6 +166,9 @@ void scan(void);
 void setclientstate(Client *c, long state);
 void setlayout(const char *arg);
 void setmwfact(const char *arg);
+void setncols(const char *arg);
+void setnmaster(const char *arg);
+void setnrows(const char *arg);
 void setup(void);
 void spawn(const char *arg);
 void tag(const char *arg);
@@ -192,6 +195,7 @@ void zoom(const char *arg);
 /* variables */
 char stext[256];
 double mwfact;
+unsigned int nmaster, nrows, ncols;
 int screen, sx, sy, sw, sh, wax, way, waw, wah;
 int (*xerrorxlib)(Display *, XErrorEvent *);
 unsigned int bh, bpos, ntags;
@@ -1417,6 +1421,66 @@ setmwfact(const char *arg) {
 }
 
 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 < 1 || waw * mwfact <= 2 * BORDERPX * i)
+               return;
+       ncols = i;
+       if(sel)
+               arrange();
+       else
+               drawbar();
+}
+
+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
+               drawbar();
+}
+
+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 < 1 || wah <= 2 * BORDERPX * i)
+               return;
+       nrows = i;
+       if(sel)
+               arrange();
+       else
+               drawbar();
+}
+
+void
 setup(void) {
        unsigned int i, j, mask;
        Window w;
@@ -1481,6 +1545,9 @@ setup(void) {
 
        /* init layouts */
        mwfact = MWFACT;
+       nmaster = NMASTER;
+       nrows = NROWS;
+       ncols = NCOLS;
        nlayouts = sizeof layouts / sizeof layouts[0];
        for(blw = i = 0; i < nlayouts; i++) {
                j = textw(layouts[i].symbol);
@@ -1566,40 +1633,78 @@ textw(const char *text) {
 
 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++;
 
-       /* window geoms */
-       mw = (n == 1) ? waw : mwfact * waw;
-       th = (n > 1) ? wah / (n - 1) : 0;
-       if(n > 1 && th < bh)
-               th = wah;
+       /* calculate correct number of stack rows */
+       if(n - nmaster > nrows * ncols)
+               rows = (n - nmaster) / ncols + ((n - nmaster) % ncols ? 1 : 0);
+       else
+               rows = nrows;
+
+       /* master area geoms */
+       if(nmaster == 0) {
+               mh = mw = 0;
+       }
+       else if(n <= nmaster) {
+               mh = wah / (n > 0 ? n : 1);
+               mw = waw;
+       }
+       else {
+               mh = wah / (nmaster > 0 ? nmaster : 1);
+               mw = waw * mwfact;
+       }
+
+       /* stacking area geoms */
+       if(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;
+                       }
+                       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;
                        }
-                       nw = waw - mw - 2 * c->border;
-                       if(i + 1 == n) /* remainder */
-                               nh = (way + wah) - ny - 2 * c->border;
                        else
                                nh = th - 2 * c->border;
+                       nw = tw - 2 * c->border;
                }
                resize(c, nx, ny, nw, nh, RESIZEHINTS);
-               if(n > 1 && th != wah)
-                       ny += nh + 2 * c->border;
+               ny += nh + 2 * c->border;
        }
 }
 
diff -uNrp dwm.colstack/dwm.c dwm.pertag/dwm.c
--- dwm.colstack/dwm.c  2007-09-19 13:35:50.000000000 +0100
+++ dwm.pertag/dwm.c    2007-09-20 11:22:32.000000000 +0100
@@ -194,13 +194,14 @@ void zoom(const char *arg);
 
 /* variables */
 char stext[256];
-double mwfact;
-unsigned int nmaster, nrows, ncols;
+double *mwfact;
+unsigned int *nmaster, *nrows, *ncols;
 int screen, sx, sy, sw, sh, wax, way, waw, wah;
 int (*xerrorxlib)(Display *, XErrorEvent *);
 unsigned int bh, bpos, ntags;
+unsigned int seltag = 0;
 unsigned int blw = 0;
-unsigned int ltidx = 0; /* default */
+unsigned int *ltidx;
 unsigned int nlayouts = 0;
 unsigned int nrules = 0;
 unsigned int numlockmask = 0;
@@ -277,7 +278,7 @@ arrange(void) {
                        unban(c);
                else
                        ban(c);
-       layouts[ltidx].arrange();
+       layouts[ltidx[seltag]].arrange();
        focus(NULL);
        restack();
 }
@@ -397,6 +398,11 @@ cleanup(void) {
        XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
        XSync(dpy, False);
        free(seltags);
+        free(ltidx);
+        free(mwfact);
+        free(nmaster);
+        free(nrows);
+        free(ncols);
 }
 
 void
@@ -550,7 +556,7 @@ drawbar(void) {
                dc.x += dc.w;
        }
        dc.w = blw;
-       drawtext(layouts[ltidx].symbol, dc.norm);
+       drawtext(layouts[ltidx[seltag]].symbol, dc.norm);
        x = dc.x + dc.w;
        dc.w = textw(stext);
        dc.x = sw - dc.w;
@@ -898,7 +904,7 @@ initfont(const char *fontstr) {
 Bool
 isarrange(void (*func)())
 {
-       return func == layouts[ltidx].arrange;
+       return func == layouts[ltidx[seltag]].arrange;
 }
 
 Bool
@@ -1381,8 +1387,8 @@ setlayout(const char *arg) {
        unsigned int i;
 
        if(!arg) {
-               if(++ltidx == nlayouts)
-                       ltidx = 0;;
+               if(++ltidx[seltag] == nlayouts)
+                       ltidx[seltag] = 0;;
        }
        else {
                for(i = 0; i < nlayouts; i++)
@@ -1390,7 +1396,7 @@ setlayout(const char *arg) {
                                break;
                if(i == nlayouts)
                        return;
-               ltidx = i;
+               ltidx[seltag] = i;
        }
        if(sel)
                arrange();
@@ -1406,16 +1412,16 @@ setmwfact(const char *arg) {
                return;
        /* arg handling, manipulate mwfact */
        if(arg == NULL)
-               mwfact = MWFACT;
+               mwfact[seltag] = MWFACT;
        else if(1 == sscanf(arg, "%lf", &delta)) {
                if(arg[0] != '+' && arg[0] != '-')
-                       mwfact = delta;
+                       mwfact[seltag] = delta;
                else
-                       mwfact += delta;
-               if(mwfact < 0.1)
-                       mwfact = 0.1;
-               else if(mwfact > 0.9)
-                       mwfact = 0.9;
+                       mwfact[seltag] += delta;
+               if(mwfact[seltag] < 0.1)
+                       mwfact[seltag] = 0.1;
+               else if(mwfact[seltag] > 0.9)
+                       mwfact[seltag] = 0.9;
        }
        arrange();
 }
@@ -1430,10 +1436,10 @@ setncols(const char *arg) {
        else if(arg[0] != '+' && arg[0] != '-')
                i = atoi(arg);
        else
-               i = ncols + atoi(arg);
-       if(i < 1 || waw * mwfact <= 2 * BORDERPX * i)
+               i = ncols[seltag] + atoi(arg);
+       if(i < 1 || waw * mwfact[seltag] <= 2 * BORDERPX * i)
                return;
-       ncols = i;
+       ncols[seltag] = i;
        if(sel)
                arrange();
        else
@@ -1450,10 +1456,10 @@ setnmaster(const char *arg) {
        else if(arg[0] != '+' && arg[0] != '-')
                i = atoi(arg);
        else
-               i = nmaster + atoi(arg);
+               i = nmaster[seltag] + atoi(arg);
        if(i < 0 || wah <= 2 * BORDERPX * i)
                return;
-       nmaster = i;
+       nmaster[seltag] = i;
        if(sel)
                arrange();
        else
@@ -1470,10 +1476,10 @@ setnrows(const char *arg) {
        else if(arg[0] != '+' && arg[0] != '-')
                i = atoi(arg);
        else
-               i = nrows + atoi(arg);
+               i = nrows[seltag] + atoi(arg);
        if(i < 1 || wah <= 2 * BORDERPX * i)
                return;
-       nrows = i;
+       nrows[seltag] = i;
        if(sel)
                arrange();
        else
@@ -1544,10 +1550,18 @@ setup(void) {
        dc.h = bh = dc.font.height + 2;
 
        /* init layouts */
-       mwfact = MWFACT;
-       nmaster = NMASTER;
-       nrows = NROWS;
-       ncols = NCOLS;
+       ltidx = (unsigned int *) emallocz(ntags * sizeof(unsigned int));
+        mwfact = (double *) emallocz(ntags * sizeof(double));
+        nmaster = (unsigned int *) emallocz(ntags * sizeof(unsigned int));
+        nrows = (unsigned int *) emallocz(ntags * sizeof(unsigned int));
+        ncols = (unsigned int *) emallocz(ntags * sizeof(unsigned int));
+        for(i = 0; i < ntags; i++) {
+               ltidx[i] = 0; /* default */
+                mwfact[i] = MWFACT;
+                nmaster[i] = NMASTER;
+                nrows[i] = NROWS;
+                ncols[i] = NCOLS;
+       }
        nlayouts = sizeof layouts / sizeof layouts[0];
        for(blw = i = 0; i < nlayouts; i++) {
                j = textw(layouts[i].symbol);
@@ -1640,33 +1654,34 @@ tile(void) {
                n++;
 
        /* calculate correct number of stack rows */
-       if(n - nmaster > nrows * ncols)
-               rows = (n - nmaster) / ncols + ((n - nmaster) % ncols ? 1 : 0);
+       if(n - nmaster[seltag] > nrows[seltag] * ncols[seltag])
+               rows = (n - nmaster[seltag]) / ncols[seltag]
+                         + ((n - nmaster[seltag]) % ncols[seltag] ? 1 : 0);
        else
-               rows = nrows;
+               rows = nrows[seltag];
 
        /* master area geoms */
-       if(nmaster == 0) {
+       if(nmaster[seltag] == 0) {
                mh = mw = 0;
        }
-       else if(n <= nmaster) {
+       else if(n <= nmaster[seltag]) {
                mh = wah / (n > 0 ? n : 1);
                mw = waw;
        }
        else {
-               mh = wah / (nmaster > 0 ? nmaster : 1);
-               mw = waw * mwfact;
+               mh = wah / (nmaster[seltag] > 0 ? nmaster[seltag] : 1);
+               mw = waw * mwfact[seltag];
        }
 
        /* stacking area geoms */
-       if(n <= nmaster + rows) {
-               rows1 = n > nmaster ? n - nmaster : 1;
+       if(n <= nmaster[seltag] + rows) {
+               rows1 = n > nmaster[seltag] ? n - nmaster[seltag] : 1;
                tw = tw1 = waw - mw;
                th = wah / rows1;
        }
        else {
-               rows1 = 1 + (n - nmaster - 1) % rows;
-               cols = (n - nmaster) / rows + ((n - nmaster) % rows ? 1 : 0);
+               rows1 = 1 + (n - nmaster[seltag] - 1) % rows;
+               cols = (n - nmaster[seltag]) / rows + ((n - nmaster[seltag]) % 
rows ? 1 : 0);
                tw = (waw - mw) / cols;
                tw1 = waw - mw - (cols - 1) * tw;
                th = wah / rows;
@@ -1677,14 +1692,14 @@ tile(void) {
 
        for(i = 0, c = nexttiled(clients); c; c = nexttiled(c->next), i++) {
                c->ismax = False;
-               if(i < nmaster) { /* master column */
+               if(i < nmaster[seltag]) { /* master column */
                        nw = mw - 2 * c->border;
                        nh = mh - 2 * c->border;
                        if(i == 0)
-                               nh += wah - mh * (n < nmaster ? n : nmaster);
+                               nh += wah - mh * (n < nmaster[seltag] ? n : 
nmaster[seltag]);
                }
-               else if(i < nmaster + rows1) { /* first stack column */
-                       if(i == nmaster) { /* initialise */
+               else if(i < nmaster[seltag] + rows1) { /* first stack column */
+                       if(i == nmaster[seltag]) { /* initialise */
                                ny = way;
                                nx += mw;
                                nh = wah - 2*c->border - (rows1 - 1) * th;
@@ -1694,7 +1709,7 @@ tile(void) {
                        nw = tw1 - 2 * c->border;
                }
                else { /* successive stack columns - rows > 0 if we reach here 
*/
-                       if((i - nmaster - rows1) % rows == 0) { /* reinitialise 
*/
+                       if((i - nmaster[seltag] - rows1) % rows == 0) { /* 
reinitialise */
                                ny = way;
                                nx += nw + 2 * c-> border;
                                nh = wah - 2*c->border - (rows - 1) * th;
@@ -1777,8 +1792,12 @@ toggleview(const char *arg) {
        i = idxoftag(arg);
        seltags[i] = !seltags[i];
        for(j = 0; j < ntags && !seltags[j]; j++);
-       if(j == ntags)
+       if(j == ntags) {
                seltags[i] = True; /* cannot toggle last view */
+               j = i;
+       }
+       if (seltag == i)
+               seltag = j;
        arrange();
 }
 
@@ -1944,9 +1963,10 @@ view(const char *arg) {
 
        for(i = 0; i < ntags; i++)
                seltags[i] = arg == NULL;
-       i = idxoftag(arg);
-       if(i >= 0 && i < ntags)
-               seltags[i] = True;
+       if(arg) {
+               seltag = idxoftag(arg);
+               seltags[seltag] = True;
+        }
        arrange();
 }
 
diff -uNrp dwm.orig/config.h dwm.pertag/config.h
--- dwm.orig/config.h   2007-09-19 12:42:52.000000000 +0100
+++ dwm.pertag/config.h 2007-09-19 13:08:52.000000000 +0100
@@ -29,6 +29,9 @@ Layout layouts[] = {
 };
 #define RESIZEHINTS            True    /* False - respect size hints in tiled 
resizals */
 #define MWFACT                 0.6     /* master width factor [0.1 .. 0.9] */
+#define NMASTER                        1       /* clients in master area */
+#define NROWS                  3       /* clients per column in stacking area 
*/
+#define NCOLS                  1       /* number of stacking area columns */
 #define SNAP                   32      /* snap pixel */
 
 /* key definitions */
@@ -47,6 +50,12 @@ Key keys[] = { \
        { 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 -uNrp dwm.orig/dwm.c dwm.pertag/dwm.c
--- dwm.orig/dwm.c      2007-09-19 12:42:53.000000000 +0100
+++ dwm.pertag/dwm.c    2007-09-20 11:22:32.000000000 +0100
@@ -166,6 +166,9 @@ void scan(void);
 void setclientstate(Client *c, long state);
 void setlayout(const char *arg);
 void setmwfact(const char *arg);
+void setncols(const char *arg);
+void setnmaster(const char *arg);
+void setnrows(const char *arg);
 void setup(void);
 void spawn(const char *arg);
 void tag(const char *arg);
@@ -191,12 +194,14 @@ void zoom(const char *arg);
 
 /* variables */
 char stext[256];
-double mwfact;
+double *mwfact;
+unsigned int *nmaster, *nrows, *ncols;
 int screen, sx, sy, sw, sh, wax, way, waw, wah;
 int (*xerrorxlib)(Display *, XErrorEvent *);
 unsigned int bh, bpos, ntags;
+unsigned int seltag = 0;
 unsigned int blw = 0;
-unsigned int ltidx = 0; /* default */
+unsigned int *ltidx;
 unsigned int nlayouts = 0;
 unsigned int nrules = 0;
 unsigned int numlockmask = 0;
@@ -273,7 +278,7 @@ arrange(void) {
                        unban(c);
                else
                        ban(c);
-       layouts[ltidx].arrange();
+       layouts[ltidx[seltag]].arrange();
        focus(NULL);
        restack();
 }
@@ -393,6 +398,11 @@ cleanup(void) {
        XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
        XSync(dpy, False);
        free(seltags);
+        free(ltidx);
+        free(mwfact);
+        free(nmaster);
+        free(nrows);
+        free(ncols);
 }
 
 void
@@ -546,7 +556,7 @@ drawbar(void) {
                dc.x += dc.w;
        }
        dc.w = blw;
-       drawtext(layouts[ltidx].symbol, dc.norm);
+       drawtext(layouts[ltidx[seltag]].symbol, dc.norm);
        x = dc.x + dc.w;
        dc.w = textw(stext);
        dc.x = sw - dc.w;
@@ -894,7 +904,7 @@ initfont(const char *fontstr) {
 Bool
 isarrange(void (*func)())
 {
-       return func == layouts[ltidx].arrange;
+       return func == layouts[ltidx[seltag]].arrange;
 }
 
 Bool
@@ -1377,8 +1387,8 @@ setlayout(const char *arg) {
        unsigned int i;
 
        if(!arg) {
-               if(++ltidx == nlayouts)
-                       ltidx = 0;;
+               if(++ltidx[seltag] == nlayouts)
+                       ltidx[seltag] = 0;;
        }
        else {
                for(i = 0; i < nlayouts; i++)
@@ -1386,7 +1396,7 @@ setlayout(const char *arg) {
                                break;
                if(i == nlayouts)
                        return;
-               ltidx = i;
+               ltidx[seltag] = i;
        }
        if(sel)
                arrange();
@@ -1402,21 +1412,81 @@ setmwfact(const char *arg) {
                return;
        /* arg handling, manipulate mwfact */
        if(arg == NULL)
-               mwfact = MWFACT;
+               mwfact[seltag] = MWFACT;
        else if(1 == sscanf(arg, "%lf", &delta)) {
                if(arg[0] != '+' && arg[0] != '-')
-                       mwfact = delta;
+                       mwfact[seltag] = delta;
                else
-                       mwfact += delta;
-               if(mwfact < 0.1)
-                       mwfact = 0.1;
-               else if(mwfact > 0.9)
-                       mwfact = 0.9;
+                       mwfact[seltag] += delta;
+               if(mwfact[seltag] < 0.1)
+                       mwfact[seltag] = 0.1;
+               else if(mwfact[seltag] > 0.9)
+                       mwfact[seltag] = 0.9;
        }
        arrange();
 }
 
 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[seltag] + atoi(arg);
+       if(i < 1 || waw * mwfact[seltag] <= 2 * BORDERPX * i)
+               return;
+       ncols[seltag] = i;
+       if(sel)
+               arrange();
+       else
+               drawbar();
+}
+
+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[seltag] + atoi(arg);
+       if(i < 0 || wah <= 2 * BORDERPX * i)
+               return;
+       nmaster[seltag] = i;
+       if(sel)
+               arrange();
+       else
+               drawbar();
+}
+
+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[seltag] + atoi(arg);
+       if(i < 1 || wah <= 2 * BORDERPX * i)
+               return;
+       nrows[seltag] = i;
+       if(sel)
+               arrange();
+       else
+               drawbar();
+}
+
+void
 setup(void) {
        unsigned int i, j, mask;
        Window w;
@@ -1480,7 +1550,18 @@ setup(void) {
        dc.h = bh = dc.font.height + 2;
 
        /* init layouts */
-       mwfact = MWFACT;
+       ltidx = (unsigned int *) emallocz(ntags * sizeof(unsigned int));
+        mwfact = (double *) emallocz(ntags * sizeof(double));
+        nmaster = (unsigned int *) emallocz(ntags * sizeof(unsigned int));
+        nrows = (unsigned int *) emallocz(ntags * sizeof(unsigned int));
+        ncols = (unsigned int *) emallocz(ntags * sizeof(unsigned int));
+        for(i = 0; i < ntags; i++) {
+               ltidx[i] = 0; /* default */
+                mwfact[i] = MWFACT;
+                nmaster[i] = NMASTER;
+                nrows[i] = NROWS;
+                ncols[i] = NCOLS;
+       }
        nlayouts = sizeof layouts / sizeof layouts[0];
        for(blw = i = 0; i < nlayouts; i++) {
                j = textw(layouts[i].symbol);
@@ -1566,40 +1647,79 @@ textw(const char *text) {
 
 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++;
 
-       /* window geoms */
-       mw = (n == 1) ? waw : mwfact * waw;
-       th = (n > 1) ? wah / (n - 1) : 0;
-       if(n > 1 && th < bh)
-               th = wah;
+       /* calculate correct number of stack rows */
+       if(n - nmaster[seltag] > nrows[seltag] * ncols[seltag])
+               rows = (n - nmaster[seltag]) / ncols[seltag]
+                         + ((n - nmaster[seltag]) % ncols[seltag] ? 1 : 0);
+       else
+               rows = nrows[seltag];
+
+       /* master area geoms */
+       if(nmaster[seltag] == 0) {
+               mh = mw = 0;
+       }
+       else if(n <= nmaster[seltag]) {
+               mh = wah / (n > 0 ? n : 1);
+               mw = waw;
+       }
+       else {
+               mh = wah / (nmaster[seltag] > 0 ? nmaster[seltag] : 1);
+               mw = waw * mwfact[seltag];
+       }
+
+       /* stacking area geoms */
+       if(n <= nmaster[seltag] + rows) {
+               rows1 = n > nmaster[seltag] ? n - nmaster[seltag] : 1;
+               tw = tw1 = waw - mw;
+               th = wah / rows1;
+       }
+       else {
+               rows1 = 1 + (n - nmaster[seltag] - 1) % rows;
+               cols = (n - nmaster[seltag]) / rows + ((n - nmaster[seltag]) % 
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[seltag]) { /* 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[seltag] ? n : 
nmaster[seltag]);
                }
-               else {  /* tile window */
-                       if(i == 1) {
+               else if(i < nmaster[seltag] + rows1) { /* first stack column */
+                       if(i == nmaster[seltag]) { /* initialise */
                                ny = way;
                                nx += mw;
+                               nh = wah - 2*c->border - (rows1 - 1) * th;
+                       }
+                       else
+                               nh = th - 2 * c->border;
+                       nw = tw1 - 2 * c->border;
+               }
+               else { /* successive stack columns - rows > 0 if we reach here 
*/
+                       if((i - nmaster[seltag] - rows1) % rows == 0) { /* 
reinitialise */
+                               ny = way;
+                               nx += nw + 2 * c-> border;
+                               nh = wah - 2*c->border - (rows - 1) * th;
                        }
-                       nw = waw - mw - 2 * c->border;
-                       if(i + 1 == n) /* remainder */
-                               nh = (way + wah) - ny - 2 * c->border;
                        else
                                nh = th - 2 * c->border;
+                       nw = tw - 2 * c->border;
                }
                resize(c, nx, ny, nw, nh, RESIZEHINTS);
-               if(n > 1 && th != wah)
-                       ny += nh + 2 * c->border;
+               ny += nh + 2 * c->border;
        }
 }
 
@@ -1672,8 +1792,12 @@ toggleview(const char *arg) {
        i = idxoftag(arg);
        seltags[i] = !seltags[i];
        for(j = 0; j < ntags && !seltags[j]; j++);
-       if(j == ntags)
+       if(j == ntags) {
                seltags[i] = True; /* cannot toggle last view */
+               j = i;
+       }
+       if (seltag == i)
+               seltag = j;
        arrange();
 }
 
@@ -1839,9 +1963,10 @@ view(const char *arg) {
 
        for(i = 0; i < ntags; i++)
                seltags[i] = arg == NULL;
-       i = idxoftag(arg);
-       if(i >= 0 && i < ntags)
-               seltags[i] = True;
+       if(arg) {
+               seltag = idxoftag(arg);
+               seltags[seltag] = True;
+        }
        arrange();
 }
 
diff -uNrp dwm.pertag/config.h dwm.full/config.h
--- dwm.pertag/config.h 2007-09-19 13:08:52.000000000 +0100
+++ dwm.full/config.h   2007-09-20 11:26:45.000000000 +0100
@@ -25,6 +25,9 @@ Rule rules[] = {
 Layout layouts[] = {
        /* symbol               function */
        { "[]=",                tile }, /* first entry is default */
+       { "[=]",                monocle },
+       { "(@)",                spiral },
+       { "[\\]",               dwindle },
        { "><>",                floating },
 };
 #define RESIZEHINTS            True    /* False - respect size hints in tiled 
resizals */
diff -uNrp dwm.pertag/dwm.c dwm.full/dwm.c
--- dwm.pertag/dwm.c    2007-09-20 11:22:32.000000000 +0100
+++ dwm.full/dwm.c      2007-09-20 11:58:52.000000000 +0100
@@ -129,10 +129,12 @@ void detachstack(Client *c);
 void drawbar(void);
 void drawsquare(Bool filled, Bool empty, unsigned long col[ColLast]);
 void drawtext(const char *text, unsigned long col[ColLast]);
+void dwindle(void);
 void *emallocz(unsigned int size);
 void enternotify(XEvent *e);
 void eprint(const char *errstr, ...);
 void expose(XEvent *e);
+void fibonacci(int shape);
 void floating(void); /* default floating layout */
 void focus(Client *c);
 void focusnext(const char *arg);
@@ -154,6 +156,7 @@ void leavenotify(XEvent *e);
 void manage(Window w, XWindowAttributes *wa);
 void mappingnotify(XEvent *e);
 void maprequest(XEvent *e);
+void monocle(void);
 void movemouse(Client *c);
 Client *nexttiled(Client *c);
 void propertynotify(XEvent *e);
@@ -171,6 +174,7 @@ void setnmaster(const char *arg);
 void setnrows(const char *arg);
 void setup(void);
 void spawn(const char *arg);
+void spiral(void);
 void tag(const char *arg);
 unsigned int textnw(const char *text, unsigned int len);
 unsigned int textw(const char *text);
@@ -346,7 +350,7 @@ buttonpress(XEvent *e) {
                        movemouse(c);
                }
                else if(ev->button == Button2) {
-                       if(isarrange(tile) && !c->isfixed && c->isfloating)
+                       if(!isarrange(floating) && !c->isfixed && c->isfloating)
                                togglefloating(NULL);
                        else
                                zoom(NULL);
@@ -639,6 +643,11 @@ drawtext(const char *text, unsigned long
                XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len);
 }
 
+void
+dwindle(void) {
+       fibonacci(1);
+}
+
 void *
 emallocz(unsigned int size) {
        void *res = calloc(1, size);
@@ -684,6 +693,44 @@ expose(XEvent *e) {
 }
 
 void
+fibonacci(int shape) {
+       unsigned int i, n, nx, ny, nw, nh;
+       Client *c;
+
+       nx = wax;
+       ny = way + (shape ? -wah : wah);
+       nw = waw;
+       nh = wah;
+       for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
+               n++;
+       for(i = 0, c = nexttiled(clients); c; c = nexttiled(c->next), i++) {
+               c->ismax = False;
+               if((i % 2 ? nh : nw) > 4 * c->border)
+               {
+                       if(i < n - 1) {
+                               if(i % 2)
+                                       nh /= 2;
+                               else
+                                       nw /= 2;
+                               if((i % 4) == 2 && !shape)
+                                       nx += nw;
+                               else if((i % 4) == 3 && !shape)
+                                       ny += nh;
+                       }
+                       if((i % 4) == 0)
+                               ny += shape ? nh : -nh;
+                       else if((i % 4) == 1)
+                               nx += nw;
+                       else if((i % 4) == 2)
+                               ny += nh;
+                       else if((i % 4) == 3)
+                               nx += shape ? nw : -nw;
+               }
+               resize(c, nx, ny, nw - 2 * c->border, nh - 2 * c->border, 
RESIZEHINTS);
+       }
+}
+
+void
 floating(void) { /* default floating layout */
        Client *c;
 
@@ -1087,6 +1134,14 @@ maprequest(XEvent *e) {
 }
 
 void
+monocle(void) {
+       Client *c;
+       
+       for(c = nexttiled(clients); c; c = nexttiled(c->next))
+               resize(c, wax, way, waw - 2*c->border, wah -2*c->border, 
RESIZEHINTS);
+}
+
+void
 movemouse(Client *c) {
        int x1, y1, ocx, ocy, di, nx, ny;
        unsigned int dui;
@@ -1616,6 +1671,11 @@ spawn(const char *arg) {
 }
 
 void
+spiral(void) {
+       fibonacci(0);
+}
+
+void
 tag(const char *arg) {
        unsigned int i;
 
@@ -1974,7 +2034,8 @@ void
 zoom(const char *arg) {
        Client *c;
 
-       if(!sel || !isarrange(tile) || sel->isfloating)
+       if(!sel || sel->isfloating
+               || !(isarrange(tile) || isarrange(dwindle) || 
isarrange(spiral))) 
                return;
        if((c = sel) == nexttiled(clients))
                if(!(c = nexttiled(c->next)))

Reply via email to