t* dwm + patches
       
   URI git clone git://git.codevoid.de/dwm-sdk
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit cdbc84b9a87c427b3d0a202475b0f5aae315fb90
   DIR parent b2f895166af45b5d84abab90032bd3cc75391dc8
   URI Author: Anselm R. Garbe <arg@suckless.org>
       Date:   Mon, 19 Feb 2007 16:40:36 +0100
       
       introduced Layout struct
       Diffstat:
         M client.c                            |       8 ++++----
         M config.arg.h                        |      11 +++++++----
         M config.default.h                    |      11 +++++++----
         M config.mk                           |       4 ++--
         M dwm.1                               |      38 ++++++++++++++++----------------
         M dwm.h                               |      19 ++++++++++++-------
         M event.c                             |      12 ++++++------
         M main.c                              |      12 ++++++------
         M screen.c                            |      82 ++++++++++++++++++++-----------
       
       9 files changed, 115 insertions(+), 82 deletions(-)
       ---
   DIR diff --git a/client.c b/client.c
       t@@ -263,7 +263,7 @@ manage(Window w, XWindowAttributes *wa) {
                setclientstate(c, NormalState);
                if(isvisible(c))
                        focus(c);
       -        arrange();
       +        lt->arrange();
        }
        
        Client *
       t@@ -430,7 +430,7 @@ unmanage(Client *c) {
                XSync(dpy, False);
                XSetErrorHandler(xerror);
                XUngrabServer(dpy);
       -        arrange();
       +        lt->arrange();
        }
        
        void
       t@@ -440,7 +440,7 @@ zoom(Arg *arg) {
        
                if(!sel)
                        return;
       -        if(sel->isfloat || (arrange == dofloat)) {
       +        if(sel->isfloat || (lt->arrange == dofloat)) {
                        togglemax(sel);
                        return;
                }
       t@@ -452,5 +452,5 @@ zoom(Arg *arg) {
                detach(c);
                attach(c);
                focus(c);
       -        arrange();
       +        lt->arrange();
        }
   DIR diff --git a/config.arg.h b/config.arg.h
       t@@ -5,9 +5,12 @@
        #define TAGS \
        const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL };
        
       -#define DEFMODE                        dotile                /* dofloat */
       -#define FLOATSYMBOL                "><>"
       -#define TILESYMBOL                "[]="
       +#define LAYOUTS \
       +static Layout layout[] = { \
       +        /* symbol                function */ \
       +        { "[]=",                dotile }, /* first entry is default */ \
       +        { "><>",                dofloat }, \
       +};
        
        #define BORDERPX                1
        #define FONT                        "-*-terminus-medium-r-*-*-14-*-*-*-*-*-*-*"
       t@@ -60,7 +63,7 @@ static Key key[] = { \
                { MODKEY|ControlMask|ShiftMask,        XK_8,                toggletag,        { .i = 7 } }, \
                { MODKEY|ControlMask|ShiftMask,        XK_9,                toggletag,        { .i = 8 } }, \
                { MODKEY|ShiftMask,                XK_c,                killclient,        { 0 } }, \
       -        { MODKEY,                        XK_space,        togglemode,        { 0 } }, \
       +        { MODKEY,                        XK_space,        togglelayout,        { 0 } }, \
                { MODKEY|ShiftMask,                XK_space,        togglefloat,        { 0 } }, \
                { MODKEY,                        XK_0,                view,                { .i = -1 } }, \
                { MODKEY,                        XK_1,                view,                { .i = 0 } }, \
   DIR diff --git a/config.default.h b/config.default.h
       t@@ -5,9 +5,12 @@
        #define TAGS \
        const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL };
        
       -#define DEFMODE                        dotile                /* dofloat */
       -#define FLOATSYMBOL                "><>"
       -#define TILESYMBOL                "[]="
       +#define LAYOUTS \
       +Layout layout[] = { \
       +        /* symbol                function */ \
       +        { "[]=",                dotile }, /* first entry is default */ \
       +        { "><>",                dofloat }, \
       +};
        
        #define BORDERPX                1
        #define FONT                        "-*-fixed-medium-r-normal-*-13-*-*-*-*-*-*-*"
       t@@ -55,7 +58,7 @@ static Key key[] = { \
                { MODKEY|ControlMask|ShiftMask,        XK_8,                toggletag,        { .i = 7 } }, \
                { MODKEY|ControlMask|ShiftMask,        XK_9,                toggletag,        { .i = 8 } }, \
                { MODKEY|ShiftMask,                XK_c,                killclient,        { 0 } }, \
       -        { MODKEY,                        XK_space,        togglemode,        { 0 } }, \
       +        { MODKEY,                        XK_space,        togglelayout,        { 0 } }, \
                { MODKEY|ShiftMask,                XK_space,        togglefloat,        { 0 } }, \
                { MODKEY,                        XK_0,                view,                { .i = -1 } }, \
                { MODKEY,                        XK_1,                view,                { .i = 0 } }, \
   DIR diff --git a/config.mk b/config.mk
       t@@ -17,8 +17,8 @@ LIBS = -L/usr/lib -lc -L${X11LIB} -lX11
        # flags
        CFLAGS = -Os ${INCS} -DVERSION=\"${VERSION}\"
        LDFLAGS = ${LIBS}
       -#CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\"
       -#LDFLAGS = -g ${LIBS}
       +CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\"
       +LDFLAGS = -g ${LIBS}
        
        # Solaris
        #CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
   DIR diff --git a/dwm.1 b/dwm.1
       t@@ -6,19 +6,19 @@ dwm \- dynamic window manager
        .RB [ \-v ]
        .SH DESCRIPTION
        dwm is a dynamic window manager for X. It manages windows in tiling and
       -floating modes. Either mode can be applied dynamically, optimizing the
       +floating layouts. Either layout can be applied dynamically, optimizing the
        environment for the application in use and the task performed.
        .P
       -In tiling mode windows are managed in a master and stacking area. The master
       +In tiling layout windows are managed in a master and stacking area. The master
        area contains the windows which currently need most attention, whereas the
       -stacking area contains all other windows. In floating mode windows can be
       +stacking area contains all other windows. In floating layout windows can be
        resized and moved freely. Dialog windows are always managed floating,
       -regardless of the mode applied.
       +regardless of the layout applied.
        .P
        Windows are grouped by tags. Each window can be tagged with one or multiple
        tags. Selecting certain tags displays all windows with these tags.
        .P
       -dwm contains a small status bar which displays all available tags, the mode,
       +dwm contains a small status bar which displays all available tags, the layout,
        the title of the focused window, and the text read from standard input. The
        selected tags are indicated with a different color. The tags of the focused
        window are indicated with a filled square in the top left corner.  The tags
       t@@ -37,17 +37,17 @@ prints version information to standard output, then exits.
        is read and displayed in the status text area.
        .TP
        .B Button1
       -click on a tag label to display all windows with that tag, click on the mode
       -label toggles between tiling and floating mode.
       +click on a tag label to display all windows with that tag, click on the layout
       +label toggles between tiling and floating layout.
        .TP
        .B Button3
        click on a tag label adds/removes all windows with that tag to/from the view.
        .TP
        .B Button4
       -click on the mode label increases the number of windows in the master area (tiling mode only).
       +click on the layout label increases the number of windows in the master area (tiling layout only).
        .TP
        .B Button5
       -click on the mode label decreases the number of windows in the master area (tiling mode only).
       +click on the layout label decreases the number of windows in the master area (tiling layout only).
        .TP
        .B Mod1-Button1
        click on a tag label applies that tag to the focused window.
       t@@ -67,19 +67,19 @@ Focus next window.
        Focus previous window.
        .TP
        .B Mod1-Return
       -Zooms/cycles current window to/from master area (tiling mode), toggles maximization of current window (floating mode).
       +Zooms/cycles current window to/from master area (tiling layout), toggles maximization of current window (floating layout).
        .TP
        .B Mod1-g
       -Grow master area (tiling mode only).
       +Grow master area (tiling layout only).
        .TP
        .B Mod1-s
       -Shrink master area (tiling mode only).
       +Shrink master area (tiling layout only).
        .TP
        .B Mod1-i
       -Increase the number of windows in the master area (tiling mode only).
       +Increase the number of windows in the master area (tiling layout only).
        .TP
        .B Mod1-d
       -Decrease the number of windows in the master area (tiling mode only).
       +Decrease the number of windows in the master area (tiling layout only).
        .TP
        .B Mod1-Shift-[1..n]
        Apply
       t@@ -98,10 +98,10 @@ tag to/from current window.
        Close focused window.
        .TP
        .B Mod1-space
       -Toggle between tiling and floating mode (affects all windows).
       +Toggle between tiling and floating layout (affects all windows).
        .TP
        .B Mod1-Shift-space
       -Toggle focused window between floating and non-floating state (tiling mode only).
       +Toggle focused window between floating and non-floating state (tiling layout only).
        .TP
        .B Mod1-[1..n]
        View all windows with
       t@@ -121,13 +121,13 @@ Quit dwm.
        .SS Mouse commands
        .TP
        .B Mod1-Button1
       -Move current window while dragging (floating mode only).
       +Move current window while dragging (floating layout only).
        .TP
        .B Mod1-Button2
       -Zooms/cycles current window to/from master area (tiling mode), toggles maximization of current window (floating mode).
       +Zooms/cycles current window to/from master area (tiling layout), toggles maximization of current window (floating layout).
        .TP
        .B Mod1-Button3
       -Resize current window while dragging (floating mode only).
       +Resize current window while dragging (floating layout only).
        .SH CUSTOMIZATION
        dwm is customized by creating a custom config.h and (re)compiling the source
        code. This keeps it fast, secure and simple.
   DIR diff --git a/dwm.h b/dwm.h
       t@@ -24,9 +24,8 @@
         *
         * Keys and tagging rules are organized as arrays and defined in the config.h
         * file. These arrays are kept static in event.o and tag.o respectively,
       - * because no other part of dwm needs access to them.  The current mode is
       - * represented by the arrange() function pointer, which wether points to
       - * dofloat() or dotile(). 
       + * because no other part of dwm needs access to them.  The current layout is
       + * represented by the lt pointer.
         *
         * To understand everything else, start reading main.c:main().
         */
       t@@ -81,21 +80,26 @@ struct Client {
                Window win;
        };
        
       +typedef struct {
       +        const char *symbol;
       +        void (*arrange)(void);
       +} Layout;
       +
        extern const char *tags[];                        /* all tags */
        extern char stext[256];                                /* status text */
       -extern int bh, bmw;                                /* bar height, bar mode label width */
        extern int screen, sx, sy, sw, sh;                /* screen geometry */
        extern int wax, way, wah, waw;                        /* windowarea geometry */
       +extern unsigned int bh, blw;                        /* bar height, bar layout label width */
        extern unsigned int master, nmaster;                /* master percent, number of master clients */
        extern unsigned int ntags, numlockmask;                /* number of tags, dynamic lock mask */
        extern void (*handler[LASTEvent])(XEvent *);        /* event handler */
       -extern void (*arrange)(void);                        /* arrange function, indicates mode  */
        extern Atom wmatom[WMLast], netatom[NetLast];
        extern Bool running, selscreen, *seltag;        /* seltag is array of Bool */
        extern Client *clients, *sel, *stack;                /* global client list and stack */
        extern Cursor cursor[CurLast];
        extern DC dc;                                        /* global draw context */
        extern Display *dpy;
       +extern Layout *lt;
        extern Window root, barwin;
        
        /* client.c */
       t@@ -124,17 +128,18 @@ extern void sendevent(Window w, Atom a, long value);        /* send synthetic event to 
        extern int xerror(Display *dsply, XErrorEvent *ee);        /* dwm's X error handler */
        
        /* screen.c */
       -extern void compileregexps(void);                /* initialize regexps of rules defined in config.h */
       +extern void compileregs(void);                        /* initialize regexps of rules defined in config.h */
        extern void dofloat(void);                        /* arranges all windows floating */
        extern void dotile(void);                        /* arranges all windows tiled */
        extern void incnmaster(Arg *arg);                /* increments nmaster with arg's index value */
       +extern void initlayouts(void);                        /* initialize layout array */
        extern Bool isvisible(Client *c);                /* returns True if client is visible */
        extern void resizemaster(Arg *arg);                /* resizes the master percent with arg's index value */
        extern void restack(void);                        /* restores z layers of all clients */
        extern void settags(Client *c, Client *trans);        /* sets tags of c */
        extern void tag(Arg *arg);                        /* tags c with arg's index */
        extern void togglefloat(Arg *arg);                /* toggles focusesd client between floating/non-floating state */
       -extern void togglemode(Arg *arg);                /* toggles global arrange function (dotile/dofloat) */
       +extern void togglelayout(Arg *arg);                /* toggles layout */
        extern void toggletag(Arg *arg);                /* toggles c tags with arg's index */
        extern void toggleview(Arg *arg);                /* toggles the tag with arg's index (in)visible */
        extern void view(Arg *arg);                        /* views the tag with arg's index */
   DIR diff --git a/event.c b/event.c
       t@@ -137,10 +137,10 @@ buttonpress(XEvent *e) {
                                        return;
                                }
                        }
       -                if(ev->x < x + bmw)
       +                if(ev->x < x + blw)
                                switch(ev->button) {
                                case Button1:
       -                                togglemode(NULL);
       +                                togglelayout(NULL);
                                        break;
                                case Button4:
                                        a.i = 1;
       t@@ -156,14 +156,14 @@ buttonpress(XEvent *e) {
                        focus(c);
                        if(CLEANMASK(ev->state) != MODKEY)
                                return;
       -                if(ev->button == Button1 && (arrange == dofloat || c->isfloat)) {
       +                if(ev->button == Button1 && (lt->arrange == dofloat || c->isfloat)) {
                                restack();
                                movemouse(c);
                        }
                        else if(ev->button == Button2)
                                zoom(NULL);
                        else if(ev->button == Button3
       -                && (arrange == dofloat || c->isfloat) && !c->isfixed)
       +                && (lt->arrange == dofloat || c->isfloat) && !c->isfixed)
                        {
                                restack();
                                resizemouse(c);
       t@@ -181,7 +181,7 @@ configurerequest(XEvent *e) {
                        c->ismax = False;
                        if(ev->value_mask & CWBorderWidth)
                                c->border = ev->border_width;
       -                if(c->isfixed || c->isfloat || (arrange == dofloat)) {
       +                if(c->isfixed || c->isfloat || (lt->arrange == dofloat)) {
                                if(ev->value_mask & CWX)
                                        c->x = ev->x;
                                if(ev->value_mask & CWY)
       t@@ -310,7 +310,7 @@ propertynotify(XEvent *e) {
                                case XA_WM_TRANSIENT_FOR:
                                        XGetTransientForHint(dpy, c->win, &trans);
                                        if(!c->isfloat && (c->isfloat = (trans != 0)))
       -                                        arrange();
       +                                        lt->arrange();
                                        break;
                                case XA_WM_NORMAL_HINTS:
                                        updatesizehints(c);
   DIR diff --git a/main.c b/main.c
       t@@ -18,8 +18,8 @@
        /* extern */
        
        char stext[256];
       -int bh, bmw, screen, sx, sy, sw, sh, wax, way, waw, wah;
       -unsigned int ntags, numlockmask;
       +int screen, sx, sy, sw, sh, wax, way, waw, wah;
       +unsigned int bh, ntags, numlockmask;
        Atom wmatom[WMLast], netatom[NetLast];
        Bool running = True;
        Bool *seltag;
       t@@ -246,7 +246,7 @@ setup(void) {
                wa.cursor = cursor[CurNormal];
                XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
                grabkeys();
       -        compileregexps();
       +        compileregs();
                for(ntags = 0; tags[ntags]; ntags++);
                seltag = emallocz(sizeof(Bool) * ntags);
                seltag[0] = True;
       t@@ -262,7 +262,7 @@ setup(void) {
                sx = sy = 0;
                sw = DisplayWidth(dpy, screen);
                sh = DisplayHeight(dpy, screen);
       -        bmw = textw(TILESYMBOL) > textw(FLOATSYMBOL) ? textw(TILESYMBOL) : textw(FLOATSYMBOL);
       +        initlayouts();
                /* bar */
                dc.h = bh = dc.font.height + 2;
                wa.override_redirect = 1;
       t@@ -312,8 +312,8 @@ drawstatus(void) {
                                drawtext(tags[i], dc.norm, sel && sel->tags[i], isoccupied(i));
                        dc.x += dc.w;
                }
       -        dc.w = bmw;
       -        drawtext(arrange == dofloat ? FLOATSYMBOL : TILESYMBOL, dc.norm, False, False);
       +        dc.w = blw;
       +        drawtext(lt->symbol, dc.norm, False, False);
                x = dc.x + dc.w;
                dc.w = textw(stext);
                dc.x = sw - dc.w;
   DIR diff --git a/screen.c b/screen.c
       t@@ -9,9 +9,10 @@
        #include <sys/types.h>
        #include <X11/Xutil.h>
        
       -void (*arrange)(void) = DEFMODE;
        unsigned int master = MASTER;
        unsigned int nmaster = NMASTER;
       +unsigned int blw = 0;
       +Layout *lt = NULL;
        
        /* static */
        
       t@@ -24,39 +25,41 @@ typedef struct {
        typedef struct {
                regex_t *propregex;
                regex_t *tagregex;
       -} Regexps;
       +} Regs;
        
       +LAYOUTS
        TAGS
        RULES
        
       -static Regexps *regexps = NULL;
       -static unsigned int len = 0;
       +static Regs *regs = NULL;
       +static unsigned int nrules = 0;
       +static unsigned int nlayouts = 0;
        
        /* extern */
        
        void
       -compileregexps(void) {
       +compileregs(void) {
                unsigned int i;
                regex_t *reg;
        
       -        if(regexps)
       +        if(regs)
                        return;
       -        len = sizeof rule / sizeof rule[0];
       -        regexps = emallocz(len * sizeof(Regexps));
       -        for(i = 0; i < len; i++) {
       +        nrules = sizeof rule / sizeof rule[0];
       +        regs = emallocz(nrules * sizeof(Regs));
       +        for(i = 0; i < nrules; i++) {
                        if(rule[i].prop) {
                                reg = emallocz(sizeof(regex_t));
                                if(regcomp(reg, rule[i].prop, REG_EXTENDED))
                                        free(reg);
                                else
       -                                regexps[i].propregex = reg;
       +                                regs[i].propregex = reg;
                        }
                        if(rule[i].tags) {
                                reg = emallocz(sizeof(regex_t));
                                if(regcomp(reg, rule[i].tags, REG_EXTENDED))
                                        free(reg);
                                else
       -                                regexps[i].tagregex = reg;
       +                                regs[i].tagregex = reg;
                        }
                }
        }
       t@@ -138,16 +141,29 @@ dotile(void) {
        
        void
        incnmaster(Arg *arg) {
       -        if((arrange == dofloat) || (nmaster + arg->i < 1)
       +        if((lt->arrange == dofloat) || (nmaster + arg->i < 1)
                || (wah / (nmaster + arg->i) <= 2 * BORDERPX))
                        return;
                nmaster += arg->i;
                if(sel)
       -                arrange();
       +                lt->arrange();
                else
                        drawstatus();
        }
        
       +void
       +initlayouts(void) {
       +        unsigned int i, w;
       +
       +        lt = &layout[0];
       +        nlayouts = sizeof layout / sizeof layout[0];
       +        for(blw = i = 0; i < nlayouts; i++) {
       +                w = textw(layout[i].symbol);
       +                if(w > blw)
       +                        blw = w;
       +        }
       +}
       +
        Bool
        isvisible(Client *c) {
                unsigned int i;
       t@@ -160,7 +176,7 @@ isvisible(Client *c) {
        
        void
        resizemaster(Arg *arg) {
       -        if(arrange != dotile)
       +        if(lt->arrange != dotile)
                        return;
                if(arg->i == 0)
                        master = MASTER;
       t@@ -170,7 +186,7 @@ resizemaster(Arg *arg) {
                                return;
                        master += arg->i;
                }
       -        arrange();
       +        lt->arrange();
        }
        
        void
       t@@ -181,9 +197,9 @@ restack(void) {
                drawstatus();
                if(!sel)
                        return;
       -        if(sel->isfloat || arrange == dofloat)
       +        if(sel->isfloat || lt->arrange == dofloat)
                        XRaiseWindow(dpy, sel->win);
       -        if(arrange != dofloat) {
       +        if(lt->arrange != dofloat) {
                        if(!sel->isfloat)
                                XLowerWindow(dpy, sel->win);
                        for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
       t@@ -212,11 +228,11 @@ settags(Client *c, Client *trans) {
                        snprintf(prop, sizeof prop, "%s:%s:%s",
                                        ch.res_class ? ch.res_class : "",
                                        ch.res_name ? ch.res_name : "", c->name);
       -                for(i = 0; i < len; i++)
       -                        if(regexps[i].propregex && !regexec(regexps[i].propregex, prop, 1, &tmp, 0)) {
       +                for(i = 0; i < nrules; i++)
       +                        if(regs[i].propregex && !regexec(regs[i].propregex, prop, 1, &tmp, 0)) {
                                        c->isfloat = rule[i].isfloat;
       -                                for(j = 0; regexps[i].tagregex && j < ntags; j++) {
       -                                        if(!regexec(regexps[i].tagregex, tags[j], 1, &tmp, 0)) {
       +                                for(j = 0; regs[i].tagregex && j < ntags; j++) {
       +                                        if(!regexec(regs[i].tagregex, tags[j], 1, &tmp, 0)) {
                                                        matched = True;
                                                        c->tags[j] = True;
                                                }
       t@@ -242,15 +258,15 @@ tag(Arg *arg) {
                        sel->tags[i] = (arg->i == -1) ? True : False;
                if(arg->i >= 0 && arg->i < ntags)
                        sel->tags[arg->i] = True;
       -        arrange();
       +        lt->arrange();
        }
        
        void
        togglefloat(Arg *arg) {
       -        if(!sel || arrange == dofloat)
       +        if(!sel || lt->arrange == dofloat)
                        return;
                sel->isfloat = !sel->isfloat;
       -        arrange();
       +        lt->arrange();
        }
        
        void
       t@@ -263,14 +279,20 @@ toggletag(Arg *arg) {
                for(i = 0; i < ntags && !sel->tags[i]; i++);
                if(i == ntags)
                        sel->tags[arg->i] = True;
       -        arrange();
       +        lt->arrange();
        }
        
        void
       -togglemode(Arg *arg) {
       -        arrange = (arrange == dofloat) ? dotile : dofloat;
       +togglelayout(Arg *arg) {
       +        unsigned int i;
       +
       +        for(i = 0; i < nlayouts && lt != &layout[i]; i++);
       +        if(i == nlayouts - 1)
       +                lt = &layout[0];
       +        else
       +                lt = &layout[++i];
                if(sel)
       -                arrange();
       +                lt->arrange();
                else
                        drawstatus();
        }
       t@@ -283,7 +305,7 @@ toggleview(Arg *arg) {
                for(i = 0; i < ntags && !seltag[i]; i++);
                if(i == ntags)
                        seltag[arg->i] = True; /* cannot toggle last view */
       -        arrange();
       +        lt->arrange();
        }
        
        void
       t@@ -294,5 +316,5 @@ view(Arg *arg) {
                        seltag[i] = (arg->i == -1) ? True : False;
                if(arg->i >= 0 && arg->i < ntags)
                        seltag[arg->i] = True;
       -        arrange();
       +        lt->arrange();
        }