Hi all,
This is the DWMII layout for DWM 5.1. It is a layout in the dwm way this
time ! The only modification is within the Client struct and holds in 11
chars : "int dwmii;\n". This modification prevents from having a more
complex algorithm and more lines of code. The last release of my layout
for dwm 5.0.1 contained bugs that I found later. Now, I think it's bug
free and I review the code for cleaning ! I also added the row layout
because I missed it. Feel free to try it and send me all your comments.
Kind regards,
QUINTIN Guillaume.
--- dwm.org.c 2008-07-30 12:48:52.000000000 +0200
+++ dwm.c 2008-07-30 12:56:10.000000000 +0200
@@ -91,6 +91,7 @@
Client *next;
Client *snext;
Window win;
+ int dwmii;
};
typedef struct {
@@ -201,6 +202,12 @@
static int xerrordummy(Display *dpy, XErrorEvent *ee);
static int xerrorstart(Display *dpy, XErrorEvent *ee);
static void zoom(const Arg *arg);
+static void dwmiitoggle(const Arg *);
+static void dwmiiinsertafter(Client *,Client *,int);
+static void dwmiikeypressed(const Arg *);
+static void dwmiinoinfiniteloop(void);
+static void dwmiilayoutcol(void);
+static void dwmiilayoutrow(void);
/* variables */
static char stext[256];
@@ -1742,3 +1749,127 @@
XCloseDisplay(dpy);
return 0;
}
+
+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 dwmiinoinfiniteloop(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; }
+ dwmiinoinfiniteloop();
+ 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 ; )
+ {
+ if ( t->dwmii )
+ {
+ 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; }
+ dwmiinoinfiniteloop();
+ 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 ; )
+ {
+ if ( t->dwmii )
+ {
+ 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;
+ }
+ }
+}
+
/* See LICENSE file for copyright and license details. */
/* appearance */
static const char font[] = "-*-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*";
static const char normbordercolor[] = "#cccccc";
static const char normbgcolor[] = "#cccccc";
static const char normfgcolor[] = "#000000";
static const char selbordercolor[] = "#0066ff";
static const char selbgcolor[] = "#0066ff";
static const char selfgcolor[] = "#ffffff";
static unsigned int borderpx = 1; /* border pixel of windows */
static unsigned int snap = 32; /* snap pixel */
static Bool showbar = True; /* False means no bar */
static Bool topbar = True; /* False means bottom bar */
/* tagging */
static const char tags[][MAXTAGLEN] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
static Rule rules[] = {
/* class instance title tags mask isfloating */
{ "MPlayer", NULL, NULL, 0, True },
};
/* layout(s) */
static float mfact = 0.5;
static Bool resizehints = True; /* False means respect size hints in tiled resizals */
static Layout layouts[] = {
/* symbol arrange function */
{ "[]=", tile }, /* first entry is default */
{ "COL", dwmiilayoutcol },
{ "ROW", dwmiilayoutrow },
{ "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
};
/* key definitions */
#define MODKEY Mod4Mask
#define TAGKEYS(KEY,TAG) \
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
{ MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
/* commands */
static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL };
static const char *termcmd[] = { "uxterm", NULL };
static Key keys[] = {
/* modifier key function argument */
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
{ MODKEY, XK_b, togglebar, {0} },
{ MODKEY, XK_Down, focusstack, {.i = +1 } },
{ MODKEY, XK_Up, focusstack, {.i = -1 } },
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
{ MODKEY, XK_Return, zoom, {0} },
{ MODKEY, XK_Tab, view, {0} },
{ MODKEY|ShiftMask, XK_c, killclient, {0} },
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
{ MODKEY, XK_c, setlayout, {.v = &layouts[1]} },
{ MODKEY, XK_r, setlayout, {.v = &layouts[2]} },
{ MODKEY, XK_f, setlayout, {.v = &layouts[3]} },
{ MODKEY, XK_m, setlayout, {.v = &layouts[4]} },
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
{ MODKEY, XK_agrave, view, {.ui = ~0 } },
{ MODKEY|ShiftMask, XK_agrave, tag, {.ui = ~0 } },
{ 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} },
TAGKEYS( XK_ampersand, 0)
TAGKEYS( XK_eacute, 1)
TAGKEYS( XK_quotedbl, 2)
TAGKEYS( XK_apostrophe, 3)
TAGKEYS( XK_parenleft, 4)
TAGKEYS( XK_minus, 5)
TAGKEYS( XK_egrave, 6)
TAGKEYS( XK_underscore, 7)
TAGKEYS( XK_ccedilla, 8)
{ MODKEY|ShiftMask, XK_q, quit, {0} },
};
/* button definitions */
/* click can be a tag number (starting at 0),
* ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
static Button buttons[] = {
/* click event mask button function argument */
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
{ ClkWinTitle, 0, Button2, zoom, {0} },
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
{ ClkTagBar, 0, Button1, view, {0} },
{ ClkTagBar, 0, Button3, toggleview, {0} },
{ ClkTagBar, MODKEY, Button1, tag, {0} },
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
};