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(); }