t* dwm + patches
       
   URI git clone git://git.codevoid.de/dwm-sdk
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 940feed3146d6911c79a0a4469f6ede071a4773e
   DIR parent 606b44179dfeec8d31930488aa91c8d4808235a7
   URI Author: anselm@garbe.us <unknown>
       Date:   Sun,  8 Jul 2012 09:43:11 +0200
       
       reverted to old updategeom() after several complains, we need to optimize the old way
       Diffstat:
         M config.mk                           |       2 +-
         M dwm.c                               |     123 ++++++++++++++++++-------------
       
       2 files changed, 71 insertions(+), 54 deletions(-)
       ---
   DIR diff --git a/config.mk b/config.mk
       t@@ -1,5 +1,5 @@
        # dwm version
       -VERSION = 6.1
       +VERSION = 6.0-tip
        
        # Customize below to fit your system
        
   DIR diff --git a/dwm.c b/dwm.c
       t@@ -236,7 +236,7 @@ static void toggleview(const Arg *arg);
        static void unfocus(Client *c, Bool setfocus);
        static void unmanage(Client *c, Bool destroyed);
        static void unmapnotify(XEvent *e);
       -static void updategeom(void);
       +static Bool updategeom(void);
        static void updatebarpos(Monitor *m);
        static void updatebars(void);
        static void updateclientlist(void);
       t@@ -574,18 +574,23 @@ void
        configurenotify(XEvent *e) {
                Monitor *m;
                XConfigureEvent *ev = &e->xconfigure;
       +        Bool dirty;
        
       +        // TODO: updategeom handling sucks, needs to be simplified
                if(ev->window == root) {
       +                dirty = (sw != ev->width || sh != ev->height);
                        sw = ev->width;
                        sh = ev->height;
       -                if(dc.drawable != 0)
       -                        XFreePixmap(dpy, dc.drawable);
       -                dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
       -                updatebars();
       -                for(m = mons; m; m = m->next)
       -                        XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
       -                focus(NULL);
       -                arrange(NULL);
       +                if(updategeom() || dirty) {
       +                        if(dc.drawable != 0)
       +                                XFreePixmap(dpy, dc.drawable);
       +                        dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
       +                        updatebars();
       +                        for(m = mons; m; m = m->next)
       +                                XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
       +                        focus(NULL);
       +                        arrange(NULL);
       +                }
                }
        }
        
       t@@ -1072,8 +1077,8 @@ initfont(const char *fontstr) {
        static Bool
        isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) {
                while(n--)
       -                /* treat origin (x, y) as fixpoint for uniqueness only, first screen wins */
       -                if(unique[n].x_org == info->x_org && unique[n].y_org == info->y_org)
       +                if(unique[n].x_org == info->x_org && unique[n].y_org == info->y_org
       +                && unique[n].width == info->width && unique[n].height == info->height)
                                return False;
                return True;
        }
       t@@ -1883,74 +1888,86 @@ updateclientlist() {
                                                (unsigned char *) &(c->win), 1);
        }
        
       -void
       +Bool
        updategeom(void) {
       -        /* Starting with dwm 6.1 this function uses a new (simpler) strategy:
       -         * whenever screen changes are reported, we destroy all monitors
       -         * and recreate all unique origin monitors and add all clients to
       -         * the first monitor, only. In several circumstances this may suck,
       -         * but dealing with all corner-cases sucks even more.*/
       +        Bool dirty = False;
        
        #ifdef XINERAMA
                if(XineramaIsActive(dpy)) {
       -                int i, j, n;
       +                int i, j, n, nn;
                        Client *c;
       -                Monitor *m, *oldmons = mons;
       -                XineramaScreenInfo *info = XineramaQueryScreens(dpy, &n);
       +                Monitor *m;
       +                XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn);
                        XineramaScreenInfo *unique = NULL;
        
       +                for(n = 0, m = mons; m; m = m->next, n++);
                        /* only consider unique geometries as separate screens */
       -                if(!(unique = (XineramaScreenInfo *)malloc(sizeof(XineramaScreenInfo) * n)))
       -                        die("fatal: could not malloc() %u bytes\n", sizeof(XineramaScreenInfo) * n);
       -                for(i = 0, j = 0; i < n; i++)
       +                if(!(unique = (XineramaScreenInfo *)malloc(sizeof(XineramaScreenInfo) * nn)))
       +                        die("fatal: could not malloc() %u bytes\n", sizeof(XineramaScreenInfo) * nn);
       +                for(i = 0, j = 0; i < nn; i++)
                                if(isuniquegeom(unique, j, &info[i]))
                                        memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo));
                        XFree(info);
       -                /* create new monitor structure */
       -                n = j;
       -                mons = m = createmon(); /* new first monitor */
       -                for(i = 1; i < n; i++) {
       -                        m->next = createmon();
       -                        m = m->next;
       -                }
       -                for(i = 0, m = mons; i < n && m; m = m->next, i++) {
       -                        m->num = i;
       -                        m->mx = m->wx = unique[i].x_org;
       -                        m->my = m->wy = unique[i].y_org;
       -                        m->mw = m->ww = unique[i].width;
       -                        m->mh = m->wh = unique[i].height;
       -                        updatebarpos(m);
       +                nn = j;
       +                if(n <= nn) {
       +                        for(i = 0; i < (nn - n); i++) { /* new monitors available */
       +                                for(m = mons; m && m->next; m = m->next);
       +                                if(m)
       +                                        m->next = createmon();
       +                                else
       +                                        mons = createmon();
       +                        }
       +                        for(i = 0, m = mons; i < nn && m; m = m->next, i++)
       +                                if(i >= n
       +                                || (unique[i].x_org != m->mx || unique[i].y_org != m->my
       +                                    || unique[i].width != m->mw || unique[i].height != m->mh))
       +                                {
       +                                        dirty = True;
       +                                        m->num = i;
       +                                        m->mx = m->wx = unique[i].x_org;
       +                                        m->my = m->wy = unique[i].y_org;
       +                                        m->mw = m->ww = unique[i].width;
       +                                        m->mh = m->wh = unique[i].height;
       +                                        updatebarpos(m);
       +                                }
                        }
       -                free(unique);
       -                /* re-attach old clients and cleanup old monitor structure */
       -                while(oldmons) {
       -                        m = oldmons;
       -                        while(m->clients) {
       -                                c = m->clients;
       -                                m->clients = c->next;
       -                                detachstack(c);
       -                                c->mon = mons;
       -                                attach(c);
       -                                attachstack(c);
       +                else { /* less monitors available nn < n */
       +                        for(i = nn; i < n; i++) {
       +                                for(m = mons; m && m->next; m = m->next);
       +                                while(m->clients) {
       +                                        dirty = True;
       +                                        c = m->clients;
       +                                        m->clients = c->next;
       +                                        detachstack(c);
       +                                        c->mon = mons;
       +                                        attach(c);
       +                                        attachstack(c);
       +                                }
       +                                if(m == selmon)
       +                                        selmon = mons;
       +                                cleanupmon(m);
                                }
       -                        oldmons = m->next;
       -                        cleanupmon(m);
                        }
       +                free(unique);
                }
                else
        #endif /* XINERAMA */
                /* default monitor setup */
                {
       -                if(!mons) /* only true if !XINERAMA compile flag */
       +                if(!mons)
                                mons = createmon();
                        if(mons->mw != sw || mons->mh != sh) {
       +                        dirty = True;
                                mons->mw = mons->ww = sw;
                                mons->mh = mons->wh = sh;
                                updatebarpos(mons);
                        }
                }
       -        selmon = mons;
       -        selmon = wintomon(root);
       +        if(dirty) {
       +                selmon = mons;
       +                selmon = wintomon(root);
       +        }
       +        return dirty;
        }
        
        void