#if 0 TITLE ----- descrp: ntile/tilecols layouts with clientspertag for dwm-4.7 author: pancake update: 2007-12-01 CONFIGURATION ------------- You should modify your config.h to include "nmaster.c" AFTER setting the NMASTER, NCOLS, NROWS, BORDERPX, and RESIZEHINTS macro definitions and BEFORE the layouts definition. A sample configuration with ntile will be: #define NMASTER 1 #define NCOLS 1 #define NROWS 1 #define CPTH 32 #include "nmaster-4.7.c" Layout layouts[] = { { "-|=" , ntile }, // ... }; // keys { MODKEY|ShiftMask , XK_j , setnmaster , "+1" } , \ { MODKEY|ShiftMask , XK_k , setnmaster , "-1" } , \ { MODKEY , XK_q , clientspertag ,"^1" } , \ { MODKEY , XK_w , clientspertag , "2" } , \ { MODKEY , XK_e , clientspertag , "3" } , \ { MODKEY , XK_n , setcpth , "+32" } , \ { MODKEY|ShiftMask , XK_n , setcpth , "-32" } , \ clientspertag: both of them features the new cpt patch (clients per tag) which enables to define the maximum number of clients you want to focus, the rest are stacked at the bottom of the screen. This area has CPTH height and this value can be changed on the fly using the setcpth function. +------+----+ | | | Valid values are: | |----| -1 - show all clients | | | 0 - show all clients in the bottom stack area +---+--^+---+ >0 - show N clients +---+---+---+ #define CPTH 32 // num of pixels of the height of the stacked cpt area { MODKEY , XK_q , clientspertag ,"^1" } , \ { MODKEY , XK_w , clientspertag , "2" } , \ { MODKEY , XK_e , clientspertag , "3" } , \ { MODKEY , XK_r , clientspertag , "4" } , \ { MODKEY , XK_t , clientspertag , "5" } , \ { MODKEY , XK_n , setcpth , "+32" } , \ { MODKEY|ShiftMask , XK_n , setcpth , "-32" } , \ This source adds two new layouts: ntile: +-----+--+ |_____|--| | |--| +-----+--+ #define NMASTER 1 { "-|=" , ntile } , \ { MODKEY|ShiftMask , XK_j , setnmaster , "+1" } , \ { MODKEY|ShiftMask , XK_k , setnmaster , "-1" } , \ tilecols: +--+--+--+ |__| |__| | | | | +--+--+--+ #define NCOLS 2 #define NROWS 1 { "E|]" , tilecols } , \ { MODKEY|ShiftMask , XK_j , setnrows , "+1" } , \ { MODKEY|ShiftMask , XK_k , setnrows , "-1" } , \ { MODKEY|ShiftMask , XK_h , setncols , "+1" } , \ { MODKEY|ShiftMask , XK_l , setncols , "-1" } , #endif /* height for bottom stacked clients */ #ifndef CPTH #define CPTH 32 #endif /* initial value for clients per tag */ #ifndef CPT #define CPT -1 #endif void maxzoom(const char *arg) { if (sel->isfloating) togglemax(NULL); else zoom(NULL); } int cpt = CPT; int Cpth = CPTH; void clientspertag(const char *arg) { if (*arg=='+' || *arg=='-') { cpt += atoi(arg); } else if (arg[0]=='^') { if (cpt==-1) cpt = atoi(arg+1); else cpt = -1; } else cpt = atoi(arg); arrange(); } void setcpth(const char *arg) { int i; if(!arg) Cpth = CPTH; else { Cpth += atoi(arg); if (Cpth-CPTH<=0) Cpth = CPTH; if (Cpth+CPTH>=wah) Cpth = wah - CPTH; } if(sel) arrange(); } #ifdef NMASTER int nmaster = NMASTER; void ntile(void) { unsigned int i, n, t, nx, ny, nw, nh, mw, mh, th; int cptn = 0, cpth = 0; Client *c; domwfact = dozoom = True; for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) { //if (cpt!=-1 && n>=cpt && sel == c) { n=cpt; zoom(NULL); break; } n++; } t = n; if (cpt!=-1&&n>cpt) { n = cpt; cpth = Cpth; wah -= cpth; } /* window geoms */ mh = (n <= nmaster) ? wah / (n > 0 ? n : 1) : wah / nmaster; mw = (n <= nmaster) ? waw : mwfact * waw; th = (n > nmaster) ? wah / (n - nmaster) : 0; if(n > nmaster && th < bh) th = wah; nx = wax; ny = way; for(i = 0, c = nexttiled(clients); c; c = nexttiled(c->next), i++) { if (cpt!=-1 && i>=cpt) { nw = waw/(t-n) - c->border*2; nx = (nw+c->border*2)*cptn; cptn++; ny = wah + way; nh = cpth-(c->border*2); if (nhborder) nh = cpth; resize(c, nx, ny, nw, nh, RESIZEHINTS); continue; } c->ismax = False; if(i < nmaster) { /* master */ ny = way + i * mh; nw = mw - 2 * c->border; nh = mh; if(i + 1 == (n < nmaster ? n : nmaster)) /* remainder */ nh = wah - mh * i; nh -= 2 * c->border; } else { /* tile window */ if(i == nmaster) { ny = way; nx += mw; } nw = waw - mw - 2 * c->border; if(i + 1 == n) /* remainder */ nh = (way + wah) - ny - 2 * c->border; else nh = th - 2 * c->border; } resize(c, nx, ny, nw, nh, RESIZEHINTS); if(n > nmaster && th != wah) ny += nh + 2 * c->border; } wah += cpth; } void setnmaster(const char *arg) { int i; if(!arg) nmaster = NMASTER; else { i = atoi(arg); if((nmaster + i) < 1 || wah / (nmaster + i) <= 2 * BORDERPX) return; nmaster += i; } if(sel) arrange(); } #endif #ifdef NCOLS #ifdef NROWS unsigned int ncols = NCOLS; unsigned int nrows = NROWS; void setncols(const char *arg) { int i; if(!arg) i = NCOLS; else if(arg[0] != '+' && arg[0] != '-') i = atoi(arg); else i = ncols + atoi(arg); if((i < 1) || (i >= 1 && waw / i <= 2 * BORDERPX)) return; ncols = i; if(sel) arrange(); } void setnrows(const char *arg) { int i; 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(); } void tilecols(void) { unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th, tw1, cols, rows, rows1, t; int cpth = 0, cptn = 0; Client *c; domwfact = dozoom = True; for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) { // if (cpt!=-1 && n>=cpt && sel == c) { n=cpt; zoom(NULL); break; } 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; t = n; if (cpt!=-1&&n>cpt) { n = cpt; cpth = Cpth; wah -= cpth; } /* window geoms */ mh = (n <= nmaster) ? wah / (n > 0 ? n : 1) : wah / nmaster; 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++) { #if 0 if (cpt!=-1 && i>=cpt) { ban(c); continue; } #endif if (cpt!=-1 && i>=cpt) { nw = waw/(t-n) - c->border*2; nx = (nw+c->border*2)*cptn; cptn++; ny = wah + way; nh = cpth-(c->border*2); if (nhborder) nh = cpth; resize(c, nx, ny, nw, nh, RESIZEHINTS); continue; } c->ismax = False; if(i < nmaster) { /* master column */ ny = way + i * mh; nw = mw - 2 * c->border; nh = mh - 2 * c->border; if(i == 0) nh += wah - mh * (n < nmaster ? n : nmaster); nh = mh; if(i + 1 == (n < nmaster ? n : nmaster)) /* remainder */ nh = wah - mh * i; nh -= 2 * c->border; } 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; } else { nh = th - 2 * c->border; } nw = tw - 2 * c->border; } resize(c, nx, ny, nw, nh, RESIZEHINTS); ny += nh + 2 * c->border; } wah += cpth; } #endif #endif /* EXPERIMENTAL: * * Work in progress stuff */ #ifdef EXPERIMENTAL void swapclients(Client *c1, Client *c2) { Client *tmp; if (c2 == NULL) { c1->prev->next = NULL; c1->next = clients; clients = c1; return; } tmp = c1->next; c1->next = c2->next; c2->next = (tmp == c2 ? c1 : tmp); tmp = c2->prev; c2->prev = c1->prev; c1->prev = (tmp == c1 ? c2 : tmp ); if(c1->next) c1->next->prev = c1; if(c1->prev) c1->prev->next = c1; if(c2->next) c2->next->prev = c2; if(c2->prev) c2->prev->next = c2; //if(clients == c1) // clients = c2; } void swap(const char *arg) { int i; if(sel) { if (*arg=='+') swapclients(sel, sel->next); else if (*arg=='-') swapclients(sel, sel->prev); arrange(); } } #endif #ifdef EXPERIMENTAL void dntile(void) { unsigned int i, n, nx, ny, nw, nh, mw, mh, th, inc; Client *c; for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) n++; if (cpt!=-1 && n>cpt) n = cpt; /* dynamic nmaster */ if (n<5) inc = 0; else if (n<7) inc = 1; else inc = 2; nmaster+=inc; /* window geoms */ mh = (n <= nmaster) ? wah / (n > 0 ? n : 1) : wah / nmaster; mw = (n <= nmaster) ? waw : mwfact * waw; th = (n > nmaster) ? wah / (n - nmaster) : 0; if(n > nmaster && th < bh) th = wah; nx = wax; ny = way; for(i = 0, c = nexttiled(clients); c; c = nexttiled(c->next), i++) { if (cpt!=-1 && i>=cpt) { ban(c); continue; } c->ismax = False; if(i < nmaster) { /* master */ ny = way + i * mh; nw = mw - 2 * c->border; nh = mh; if(i + 1 == (n < nmaster ? n : nmaster)) /* remainder */ nh = wah - mh * i; nh -= 2 * c->border; } else { /* tile window */ if(i == nmaster) { ny = way; nx += mw; } nw = waw - mw - 2 * c->border; if(i + 1 == n) /* remainder */ nh = (way + wah) - ny - 2 * c->border; else nh = th - 2 * c->border; } resize(c, nx, ny, nw, nh, False); if(n > nmaster && th != wah) ny += nh + 2 * c->border; } nmaster -= inc; } #endif