t* dwm + patches
       
   URI git clone git://git.codevoid.de/dwm-sdk
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit da2bbd371c522d63d737d43a127601a3fdbcb9d8
   DIR parent b1701adf75297747c52e0c3ed2c314cd10129907
   URI Author: Anselm R. Garbe <garbeam@wmii.de>
       Date:   Thu, 13 Jul 2006 01:04:38 +0200
       
       before leaning things up
       
       Diffstat:
         M bar.c                               |      22 +++++++++++++++++-----
         M client.c                            |      61 ++++++++++++++++++++++++++-----
         M config.h                            |       5 +++++
         M event.c                             |       4 ++--
         M kb.c                                |      17 +++++++++++------
         M menu.c                              |      57 ++++++++-----------------------
         M mouse.c                             |      32 ++++++-------------------------
         M wm.c                                |      51 +++++++++++++++++++++-----------
         M wm.h                                |      13 ++++++++-----
       
       9 files changed, 150 insertions(+), 112 deletions(-)
       ---
   DIR diff --git a/bar.c b/bar.c
       t@@ -8,22 +8,34 @@
        void
        draw_bar()
        {
       +        int i;
                brush.x = brush.y = 0;
                brush.w = bw;
                brush.h = bh;
                draw(dpy, &brush, False, NULL);
        
       +        brush.w = 0;
       +        for(i = 0; i < TLast; i++) {
       +                brush.x += brush.w;
       +                brush.w = textw(&brush.font, tags[i]) + bh;
       +                if(i == tsel) {
       +                        swap((void **)&brush.fg, (void **)&brush.bg);
       +                        draw(dpy, &brush, True, tags[i]);
       +                        swap((void **)&brush.fg, (void **)&brush.bg);
       +                }
       +                else
       +                        draw(dpy, &brush, True, tags[i]);
       +        }
                if(stack) {
       -                brush.w = textw(&brush.font, stack->name) + bh;
                        swap((void **)&brush.fg, (void **)&brush.bg);
       +                brush.x += brush.w;
       +                brush.w = textw(&brush.font, stack->name) + bh;
                        draw(dpy, &brush, True, stack->name);
                        swap((void **)&brush.fg, (void **)&brush.bg);
       -                brush.x += brush.w;
                }
       -
       -        brush.w = textw(&brush.font, statustext) + bh;
       +        brush.w = textw(&brush.font, stext) + bh;
                brush.x = bx + bw - brush.w;
       -        draw(dpy, &brush, False, statustext);
       +        draw(dpy, &brush, False, stext);
                XCopyArea(dpy, brush.drawable, barwin, brush.gc, 0, 0, bw, bh, 0, 0);
                XFlush(dpy);
        }
   DIR diff --git a/client.c b/client.c
       t@@ -11,6 +11,8 @@
        #include "util.h"
        #include "wm.h"
        
       +void (*arrange)(void *aux);
       +
        void
        max(void *aux)
        {
       t@@ -25,12 +27,24 @@ max(void *aux)
        }
        
        void
       -arrange(void *aux)
       +floating(void *aux)
       +{
       +        Client *c;
       +
       +        arrange = floating;
       +        for(c = stack; c; c = c->snext)
       +                resize(c);
       +        discard_events(EnterWindowMask);
       +}
       +
       +void
       +grid(void *aux)
        {
                Client *c;
                int n, cols, rows, gw, gh, i, j;
            float rt, fd;
        
       +        arrange = grid;
                if(!clients)
                        return;
                for(n = 0, c = clients; c; c = c->next, n++);
       t@@ -95,7 +109,13 @@ kill(void *aux)
        static void
        resize_title(Client *c)
        {
       -        c->tw = textw(&brush.font, c->name) + bh;
       +        int i;
       +
       +        c->tw = 0;
       +        for(i = 0; i < TLast; i++)
       +                if(c->tags[i])
       +                        c->tw += textw(&brush.font, c->tags[i]) + bh;
       +        c->tw += textw(&brush.font, c->name) + bh;
                if(c->tw > c->w)
                        c->tw = c->w + 2;
                c->tx = c->x + c->w - c->tw + 2;
       t@@ -190,8 +210,8 @@ focus(Client *c)
        
                old = stack;
                for(l = &stack; *l && *l != c; l = &(*l)->snext);
       -        eassert(*l == c);
       -        *l = c->snext;
       +        if(*l)
       +                *l = c->snext;
                c->snext = stack;
                stack = c;
                if(old && old != c) {
       t@@ -230,17 +250,16 @@ manage(Window w, XWindowAttributes *wa)
                twa.background_pixmap = ParentRelative;
                twa.event_mask = ExposureMask;
        
       +        c->tags[tsel] = tags[tsel];
                c->title = XCreateWindow(dpy, root, c->tx, c->ty, c->tw, c->th,
                                0, DefaultDepth(dpy, screen), CopyFromParent,
                                DefaultVisual(dpy, screen),
                                CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa);
       -        update_name(c);
        
       +        update_name(c);
                for(l=&clients; *l; l=&(*l)->next);
                c->next = *l; /* *l == nil */
                *l = c;
       -        c->snext = stack;
       -        stack = c;
                XMapRaised(dpy, c->win);
                XMapRaised(dpy, c->title);
                XGrabButton(dpy, Button1, Mod1Mask, c->win, False, ButtonPressMask,
       t@@ -249,7 +268,7 @@ manage(Window w, XWindowAttributes *wa)
                                GrabModeAsync, GrabModeSync, None, None);
                XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask,
                                GrabModeAsync, GrabModeSync, None, None);
       -        resize(c);
       +        arrange(NULL);
                focus(c);
        }
        
       t@@ -308,11 +327,24 @@ gravitate(Client *c, Bool invert)
                c->y += dy;
        }
        
       +
        void
        resize(Client *c)
        {
                XConfigureEvent e;
        
       +        if(c->incw)
       +                c->w -= (c->w - c->basew) % c->incw;
       +        if(c->inch)
       +                c->h -= (c->h - c->baseh) % c->inch;
       +        if(c->minw && c->w < c->minw)
       +                c->w = c->minw;
       +        if(c->minh && c->h < c->minh)
       +                c->h = c->minh;
       +        if(c->maxw && c->w > c->maxw)
       +                c->w = c->maxw;
       +        if(c->maxh && c->h > c->maxh)
       +                c->h = c->maxh;
                resize_title(c);
                XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
                e.type = ConfigureNotify;
       t@@ -357,6 +389,7 @@ unmanage(Client *c)
                XFlush(dpy);
                XSetErrorHandler(error_handler);
                XUngrabServer(dpy);
       +        arrange(NULL);
                if(stack)
                        focus(stack);
        }
       t@@ -384,15 +417,25 @@ getclient(Window w)
        void
        draw_client(Client *c)
        {
       +        int i;
                if(c == stack) {
                        draw_bar();
                        return;
                }
        
                brush.x = brush.y = 0;
       -        brush.w = c->tw;
                brush.h = c->th;
        
       +        brush.w = 0;
       +        for(i = 0; i < TLast; i++) {
       +                if(c->tags[i]) {
       +                        brush.x += brush.w;
       +                        brush.w = textw(&brush.font, c->tags[i]) + bh;
       +                        draw(dpy, &brush, True, c->tags[i]);
       +                }
       +        }
       +        brush.x += brush.w;
       +        brush.w = textw(&brush.font, c->name) + bh;
                draw(dpy, &brush, True, c->name);
                XCopyArea(dpy, brush.drawable, c->title, brush.gc,
                                0, 0, c->tw, c->th, 0, 0);
   DIR diff --git a/config.h b/config.h
       t@@ -8,3 +8,8 @@
        #define FGCOLOR                "#ffffff"
        #define BORDERCOLOR        "#9999CC"
        #define STATUSDELAY        10 /* seconds */
       +
       +/* tags, see wm.c for further config */
       +enum { Tscratch, Tdev, Tirc, Twww, Twork, /* never remove: */ TLast };
       +
       +/* see kb.c for shortcut customization */
   DIR diff --git a/event.c b/event.c
       t@@ -126,7 +126,7 @@ enternotify(XEvent *e)
                if((c = getclient(ev->window)))
                        focus(c);
                else if(ev->window == root)
       -                sel_screen = True;
       +                issel = True;
        }
        
        static void
       t@@ -135,7 +135,7 @@ leavenotify(XEvent *e)
                XCrossingEvent *ev = &e->xcrossing;
        
                if((ev->window == root) && !ev->same_screen)
       -                sel_screen = True;
       +                issel = True;
        }
        
        static void
   DIR diff --git a/kb.c b/kb.c
       t@@ -7,27 +7,32 @@
        
        #include <X11/keysym.h>
        
       -static const char *term[] = { 
       +/********** CUSTOMIZE **********/
       +
       +char *cmdterm[] = { 
                "aterm", "-tr", "+sb", "-bg", "black", "-fg", "white", "-fn",
       -        "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*", 0 
       +        "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*",NULL
        };
        
       -static const char *proglist[] = {
       +char *cmdproglist[] = {
                        "sh", "-c", "exec `ls -lL /bin /sbin /usr/bin /usr/local/bin 2>/dev/null "
                        "| awk 'NF>2 && $1 ~ /^[^d].*x/ {print $NF}' | sort | uniq | gridmenu`", 0
        };
        
        static Key key[] = {
       -        { Mod1Mask, XK_Return, run, term },
       -        { Mod1Mask, XK_p, run, proglist }, 
       +        { Mod1Mask, XK_Return, run, cmdterm },
       +        { Mod1Mask, XK_p, run, cmdproglist}, 
                { Mod1Mask, XK_k, sel, "prev" }, 
                { Mod1Mask, XK_j, sel, "next" }, 
       -        { Mod1Mask, XK_g, arrange, NULL }, 
       +        { Mod1Mask, XK_g, grid, NULL }, 
       +        { Mod1Mask, XK_f, floating, NULL }, 
                { Mod1Mask, XK_m, max, NULL }, 
                { Mod1Mask | ShiftMask, XK_c, kill, NULL }, 
                { Mod1Mask | ShiftMask, XK_q, quit, NULL },
        };
        
       +/********** CUSTOMIZE **********/
       +
        void
        update_keys()
        {
   DIR diff --git a/menu.c b/menu.c
       t@@ -12,9 +12,6 @@
        #include <stdlib.h>
        #include <stdio.h>
        #include <string.h>
       -#include <sys/stat.h>
       -#include <sys/wait.h>
       -#include <time.h>
        #include <unistd.h>
        #include <X11/cursorfont.h>
        #include <X11/Xutil.h>
       t@@ -58,11 +55,7 @@ static void kpress(XKeyEvent * e);
        static char version[] = "gridmenu - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
        
        static void
       -usage()
       -{
       -        fprintf(stderr, "%s", "usage: gridmenu [-v] [-t <title>]\n");
       -        exit(1);
       -}
       +usage() { error("usage: gridmenu [-v] [-t <title>]\n"); }
        
        static void
        update_offsets()
       t@@ -213,26 +206,12 @@ kpress(XKeyEvent * e)
                /* first check if a control mask is omitted */
                if(e->state & ControlMask) {
                        switch (ksym) {
       -                case XK_H:
       +                default:        /* ignore other control sequences */
       +                        return;
       +                        break;
                        case XK_h:
                                ksym = XK_BackSpace;
                                break;
       -                case XK_I:
       -                case XK_i:
       -                        ksym = XK_Tab;
       -                        break;
       -                case XK_J:
       -                case XK_j:
       -                        ksym = XK_Return;
       -                        break;
       -                case XK_N:
       -                case XK_n:
       -                        ksym = XK_Right;
       -                        break;
       -                case XK_P:
       -                case XK_p:
       -                        ksym = XK_Left;
       -                        break;
                        case XK_U:
                        case XK_u:
                                text[0] = 0;
       t@@ -243,12 +222,9 @@ kpress(XKeyEvent * e)
                        case XK_bracketleft:
                                ksym = XK_Escape;
                                break;
       -                default:        /* ignore other control sequences */
       -                        return;
       -                        break;
                        }
                }
       -        switch (ksym) {
       +        switch(ksym) {
                case XK_Left:
                        if(!(sel && sel->left))
                                return;
       t@@ -432,21 +408,18 @@ main(int argc, char *argv[])
                XFlush(dpy);
        
                /* main event loop */
       -        while(!XNextEvent(dpy, &ev)) {
       +        while(!done && !XNextEvent(dpy, &ev)) {
                        switch (ev.type) {
       -                        case KeyPress:
       -                                kpress(&ev.xkey);
       -                                break;
       -                        case Expose:
       -                                if(ev.xexpose.count == 0) {
       -                                        draw_menu();
       -                                }
       -                                break;
       -                        default:
       -                                break;
       -                }
       -                if(done)
       +                case KeyPress:
       +                        kpress(&ev.xkey);
       +                        break;
       +                case Expose:
       +                        if(ev.xexpose.count == 0)
       +                                draw_menu();
                                break;
       +                default:
       +                        break;
       +                }
                }
        
                XUngrabKeyboard(dpy, CurrentTime);
   DIR diff --git a/mouse.c b/mouse.c
       t@@ -13,27 +13,6 @@
        #define ButtonMask      (ButtonPressMask | ButtonReleaseMask)
        #define MouseMask       (ButtonMask | PointerMotionMask)
        
       -static void
       -mmatch(Client *c, int x1, int y1, int x2, int y2)
       -{
       -        c->w = abs(x1 - x2);
       -        c->h = abs(y1 - y2);
       -        if(c->incw)
       -                c->w -= (c->w - c->basew) % c->incw;
       -        if(c->inch)
       -                c->h -= (c->h - c->baseh) % c->inch;
       -        if(c->minw && c->w < c->minw)
       -                c->w = c->minw;
       -        if(c->minh && c->h < c->minh)
       -                c->h = c->minh;
       -        if(c->maxw && c->w > c->maxw)
       -                c->w = c->maxw;
       -        if(c->maxh && c->h > c->maxh)
       -                c->h = c->maxh;
       -        c->x = (x1 <= x2) ? x1 : x1 - c->w;
       -        c->y = (y1 <= y2) ? y1 : y1 - c->h;
       -}
       -
        void
        mresize(Client *c)
        {
       t@@ -55,11 +34,13 @@ mresize(Client *c)
                                break;
                        case MotionNotify:
                                XFlush(dpy);
       -                        mmatch(c, old_cx, old_cy, ev.xmotion.x, ev.xmotion.y);
       -                        XResizeWindow(dpy, c->win, c->w, c->h);
       +                        c->w = abs(old_cx - ev.xmotion.x);
       +                        c->h = abs(old_cy - ev.xmotion.y);
       +                        c->x = (old_cx <= ev.xmotion.x) ? old_cx : old_cx - c->w;
       +                        c->y = (old_cy <= ev.xmotion.y) ? old_cy : old_cy - c->h;
       +                        resize(c);
                                break;
                        case ButtonRelease:
       -                        resize(c);
                                XUngrabPointer(dpy, CurrentTime);
                                return;
                        }
       t@@ -91,10 +72,9 @@ mmove(Client *c)
                                XFlush(dpy);
                                c->x = old_cx + (ev.xmotion.x - x1);
                                c->y = old_cy + (ev.xmotion.y - y1);
       -                        XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
       +                        resize(c);
                                break;
                        case ButtonRelease:
       -                        resize(c);
                                XUngrabPointer(dpy, CurrentTime);
                                return;
                        }
   DIR diff --git a/wm.c b/wm.c
       t@@ -18,15 +18,39 @@
        
        #include "wm.h"
        
       +/********** CUSTOMIZE **********/
       +
       +char *tags[TLast] = {
       +        [Tscratch] = "scratch",
       +        [Tdev] = "dev",
       +        [Tirc] = "irc",
       +        [Twww] = "www",
       +        [Twork] = "work",
       +};
       +
       +/* commands */
       +static char *cmdwallpaper[] = {
       +        "feh", "--bg-scale", "/home/garbeam/wallpaper/bg.jpg", NULL
       +};
       +
       +static char *cmdstatus[] = {
       +        "sh", "-c", "echo -n `date '+%Y-%m-%d %H:%M'`" 
       +        " `uptime | sed 's/.*://; s/,//g'`"
       +        " `acpi | awk '{print $4}' | sed 's/,//'`", NULL
       +};
       +
       +/********** CUSTOMIZE **********/
       +
        /* X structs */
        Display *dpy;
        Window root, barwin;
        Atom wm_atom[WMLast], net_atom[NetLast];
        Cursor cursor[CurLast];
        Bool running = True;
       -Bool sel_screen;
       +Bool issel;
        
       -char statustext[1024], tag[256];
       +char stext[1024];
       +int tsel = Tdev; /* default tag */
        int screen, sx, sy, sw, sh, bx, by, bw, bh;
        
        Brush brush = {0};
       t@@ -34,21 +58,12 @@ Client *clients = NULL;
        Client *stack = NULL;
        
        static Bool other_wm_running;
       -static const char version[] = "gridwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
       +static const char version[] =
       +        "gridwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
        static int (*x_error_handler) (Display *, XErrorEvent *);
        
       -static const char *status[] = {
       -        "sh", "-c", "echo -n `date '+%Y-%m-%d %H:%M'`" 
       -        " `uptime | sed 's/.*://; s/,//g'`"
       -        " `acpi | awk '{print $4}' | sed 's/,//'`", 0
       -};
       -
        static void
       -usage()
       -{
       -        fputs("usage: gridwm [-v]\n", stderr);
       -        exit(1);
       -}
       +usage() {        error("usage: gridwm [-v]\n"); }
        
        static void
        scan_wins()
       t@@ -230,10 +245,11 @@ main(int argc, char *argv[])
                if(other_wm_running)
                        error("gridwm: another window manager is already running\n");
        
       +        spawn(dpy, cmdwallpaper);
                sx = sy = 0;
                sw = DisplayWidth(dpy, screen);
                sh = DisplayHeight(dpy, screen);
       -        sel_screen = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask);
       +        issel = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask);
        
                XSetErrorHandler(0);
                x_error_handler = XSetErrorHandler(error_handler);
       t@@ -275,7 +291,7 @@ main(int argc, char *argv[])
                brush.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
                brush.gc = XCreateGC(dpy, root, 0, 0);
        
       -        pipe_spawn(statustext, sizeof(statustext), dpy, (char **)status);
       +        pipe_spawn(stext, sizeof(stext), dpy, cmdstatus);
                draw_bar();
        
                wa.event_mask = SubstructureRedirectMask | EnterWindowMask \
       t@@ -283,6 +299,7 @@ main(int argc, char *argv[])
                wa.cursor = cursor[CurNormal];
                XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
        
       +        arrange = grid;
                scan_wins();
        
                while(running) {
       t@@ -298,7 +315,7 @@ main(int argc, char *argv[])
                        if(select(ConnectionNumber(dpy) + 1, &fds, NULL, NULL, &t) > 0)
                                continue;
                        else if(errno != EINTR) {
       -                        pipe_spawn(statustext, sizeof(statustext), dpy, (char **)status);
       +                        pipe_spawn(stext, sizeof(stext), dpy, cmdstatus);
                                draw_bar();
                        }
                }
   DIR diff --git a/wm.h b/wm.h
       t@@ -22,7 +22,8 @@ enum { NetSupported, NetWMName, NetLast };
        enum { CurNormal, CurResize, CurMove, CurInput, CurLast };
        
        struct Client {
       -        char name[256], tag[256];
       +        char name[256];
       +        char *tags[TLast];
                int proto;
                int x, y, w, h;
                int tx, ty, tw, th;
       t@@ -48,11 +49,12 @@ extern Display *dpy;
        extern Window root, barwin;
        extern Atom wm_atom[WMLast], net_atom[NetLast];
        extern Cursor cursor[CurLast];
       -extern Bool running, sel_screen, grid;
       +extern Bool running, issel;
        extern void (*handler[LASTEvent]) (XEvent *);
       +extern void (*arrange)(void *aux);
        
       -extern int screen, sx, sy, sw, sh, bx, by, bw, bh;
       -extern char statustext[1024], tag[256];
       +extern int tsel, screen, sx, sy, sw, sh, bx, by, bw, bh;
       +extern char stext[1024], *tags[TLast];
        
        extern Brush brush;
        extern Client *clients, *stack;
       t@@ -75,7 +77,8 @@ extern void lower(Client *c);
        extern void kill(void *aux);
        extern void sel(void *aux);
        extern void max(void *aux);
       -extern void arrange(void *aux);
       +extern void floating(void *aux);
       +extern void grid(void *aux);
        extern void gravitate(Client *c, Bool invert);
        
        /* event.c */