/* * I used WMII and found it too "heavy". So I switched to dwm but I * quickly missed the possibilities of having several columns, * several windows in each column and moving the windows from a * column into another or change the windows' order within a column. * As there were no patch (or layout) providing that, I wrote one. * I also added a layout that does the same thing but arrange the * windows by rows. * * The col dwmii layout : * * +--+--+--+ * | | | | * +--+ | | * | +--+ | * +--+ | | * | | | | * +--+--+--+ * * The row dwmii layout : * * +--+---+--+ * + | | + * +--+-+-+--+ * | | | * +----+----+ * | | * +---------+ * * You can move a window to the next/previous columnn, after the next * window or before the previous window within a column by simple * combination of keys (the same as in WMII). * * To get the dwmii layouts working you have to : * - have DWM version 5.1 * - add these lines in the config.h file : * - just before the layouts array : * * #include "dwmii.c" * * - in the layouts array : * * { "COL", dwmiilayoutcol }, * { "ROW", dwmiilayoutrow }, * * - in the keys array : * * { MODKEY, XK_c, setlayout, {.v = &layouts[1]} }, * { MODKEY, XK_r, setlayout, {.v = &layouts[2]} }, * { MODKEY|ShiftMask, XK_Up, dwmiikeypressed, {.i = XK_Up} }, * { MODKEY|ShiftMask, XK_Left, dwmiikeypressed, {.i = XK_Left} }, * { MODKEY|ShiftMask, XK_Down, dwmiikeypressed, {.i = XK_Down} }, * { MODKEY|ShiftMask, XK_Right, dwmiikeypressed, {.i = XK_Right} }, * { MODKEY|ShiftMask, XK_n, dwmiitoggle, {0} }, * * - add this line in the Client struct definition in the dwm.c file : * * int dwmii; * * - compile and it should work ! * * The dwmiitoggle sets the dwmii variable of a window, when * the dwmii is non zero then the window marks the start of a * new column/row depending on the layout used. * * As Donald Chai told me the dwmiimarkfirstwindow function is not necessary. * You can comment the two calls to this function in the dwmiilayoutXXX * functions or simply suppress these lines and the function as well. * the differences is in the way the windows are arranged. If you suppress * the function, then the first window of the first column of a tag will not * necessarily have its dwmii set to non zero, which means when you will select * several tags at once, the column you saw in a given tag will not necessarily * be a column ! * * Enjoy it and feel free to send me all your comments ! * * QUINTIN Guillaume * */ static void dwmiitoggle(const Arg *); static void dwmiiinsertafter(Client *,Client *,int); static void dwmiikeypressed(const Arg *); static void dwmiimarkfirstwindow(void); static void dwmiilayoutcol(void); static void dwmiilayoutrow(void); void dwmiitoggle(const Arg *arg) { if ( !lt[sellt]->arrange || (sel && sel->isfloating) ) { return; } Client *firstclients = nexttiled(clients); if ( sel == firstclients ) { return ; } if ( sel->dwmii ) { sel->dwmii = 0; return; } sel->dwmii = 1; arrange(); } void dwmiiinsertafter(Client *c,Client *after,int dwmii) { if ( !c || !after ) { return; } detach(c); c->dwmii = dwmii; c->next = after->next; after->next = c; } void dwmiikeypressed(const Arg *arg) { if ( !lt[sellt]->arrange || (sel && sel->isfloating) ) { return; } Client* firstclients = nexttiled(clients); if ( ( (arg->i == XK_Up) && (lt[sellt]->arrange == dwmiilayoutcol) ) || ( (arg->i == XK_Left) && (lt[sellt]->arrange == dwmiilayoutrow) ) ) { if ( sel->dwmii ) { return; } Client *t = firstclients,*s = 0; for( ; t != sel ; s = t,t = nexttiled(t->next) ); sel->dwmii = s->dwmii; dwmiiinsertafter(s,sel,0); } if ( ( (arg->i == XK_Right) && (lt[sellt]->arrange == dwmiilayoutcol) ) || ( (arg->i == XK_Down) && (lt[sellt]->arrange == dwmiilayoutrow) ) ) { Client *t = nexttiled(sel->next),*s = 0; if ( !t ) { sel->dwmii = 1; arrange(); return; } int i = 2; for( ; t && ((i -= ( t->dwmii ? 1 : 0 )) > 0) ; s = t,t = nexttiled(t->next) ); if ( sel->dwmii ) { t = nexttiled(sel->next); if ( t ) { t->dwmii = 1; } } dwmiiinsertafter(sel,s,( i == 2 ? 1 : 0 )); } if ( ( (arg->i == XK_Down) && (lt[sellt]->arrange == dwmiilayoutcol) ) || ( (arg->i == XK_Right) && (lt[sellt]->arrange == dwmiilayoutrow) ) ) { Client *t = nexttiled(sel->next); if ( !t || t->dwmii ) { return; } t->dwmii = sel->dwmii; dwmiiinsertafter(sel,t,0); } if ( ( (arg->i == XK_Left) && (lt[sellt]->arrange == dwmiilayoutcol) ) || ( (arg->i == XK_Up) && (lt[sellt]->arrange == dwmiilayoutrow) ) ) { if ( sel == firstclients ) { return; } Client *t = firstclients,*s = 0,*u = 0; for( ; t != sel ; s = t,t = nexttiled(t->next),u = ( t->dwmii ? s : u) ); if ( !u ) { return; } if ( sel->dwmii ) { t = nexttiled(sel->next); if ( t ) { t->dwmii = 1; } } dwmiiinsertafter(sel,u,0); } arrange(); } void dwmiimarkfirstwindow(void) { Client* firstclients = nexttiled(clients),*t = firstclients; for( ; t && !t->dwmii ; t = nexttiled(t->next) ); firstclients->dwmii = 1; if ( t && (t != firstclients) ) { t->dwmii = 0; } } void dwmiilayoutcol(void) { Client *firstclients = nexttiled(clients); if ( !firstclients || (lt[sellt]->arrange != dwmiilayoutcol) ) { return; } dwmiimarkfirstwindow(); Client *t = nexttiled(firstclients->next); int n = 1; for( ; t ; n += ( t->dwmii ? 1 : 0 ),t = nexttiled(t->next) ); int x = wx,dw = ww / n; for ( t = firstclients ; t ; ) { n = 1; Client *s = nexttiled(t->next); for( ; s && !s->dwmii ; n++,s = nexttiled(s->next) ); int dh = wh / n,y = wy + dh; resize(t,x,wy,dw - 2 * t->bw,dh - 2 * t->bw,resizehints); for( t = nexttiled(t->next) ; t && !t->dwmii ; t = nexttiled(t->next) ) { resize(t,x,y,dw - 2 * t->bw,dh - 2 * t->bw,resizehints); y += dh; } x += dw; } } void dwmiilayoutrow(void) { Client *firstclients = nexttiled(clients); if ( !firstclients || (lt[sellt]->arrange != dwmiilayoutrow) ) { return; } dwmiimarkfirstwindow(); Client *t = nexttiled(firstclients->next); int n = 1; for( ; t ; n += ( t->dwmii ? 1 : 0 ),t = nexttiled(t->next) ); int y = wy,dh = wh / n; for ( t = firstclients ; t ; ) { n = 1; Client *s = nexttiled(t->next); for( ; s && !s->dwmii ; n++,s = nexttiled(s->next) ); int dw = ww / n,x = wx + dw; resize(t,wx,y,dw - 2 * t->bw,dh - 2 * t->bw,resizehints); for( t = nexttiled(t->next) ; t && !t->dwmii ; t = nexttiled(t->next) ) { resize(t,x,y,dw - 2 * t->bw,dh - 2 * t->bw,resizehints); x += dw; } y += dh; } }