URI: 
       drastically changed updategeom() handling, see comment in updategeom() for details - dwm - dynamic window manager
  HTML git clone https://git.parazyd.org/dwm
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 20f6917910306bcb5275d726b01b42a3b5e868b4
   DIR parent 820cbb3545e60e4d2bad120fb6e691c80058a98c
  HTML Author: anselm@garbe.us <unknown>
       Date:   Sat, 23 Jun 2012 10:12:46 +0200
       
       drastically changed updategeom() handling, see comment in updategeom() for details
       Diffstat:
         M config.mk                           |       2 +-
         M dwm.c                               |     123 +++++++++++++------------------
       
       2 files changed, 54 insertions(+), 71 deletions(-)
       ---
   DIR diff --git a/config.mk b/config.mk
       @@ -1,5 +1,5 @@
        # dwm version
       -VERSION = 6.0-tip
       +VERSION = 6.1
        
        # Customize below to fit your system
        
   DIR diff --git a/dwm.c b/dwm.c
       @@ -235,7 +235,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 Bool updategeom(void);
       +static void updategeom(void);
        static void updatebarpos(Monitor *m);
        static void updatebars(void);
        static void updateclientlist(void);
       @@ -573,23 +573,18 @@ 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(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);
       -                }
       +                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);
                }
        }
        
       @@ -1076,8 +1071,8 @@ initfont(const char *fontstr) {
        static Bool
        isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) {
                while(n--)
       -                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)
       +                /* 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)
                                return False;
                return True;
        }
       @@ -1887,86 +1882,74 @@ updateclientlist() {
                                                (unsigned char *) &(c->win), 1);
        }
        
       -Bool
       +void
        updategeom(void) {
       -        Bool dirty = False;
       +        /* 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.*/
        
        #ifdef XINERAMA
                if(XineramaIsActive(dpy)) {
       -                int i, j, n, nn;
       +                int i, j, n;
                        Client *c;
       -                Monitor *m;
       -                XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn);
       +                Monitor *m, *oldmons = mons;
       +                XineramaScreenInfo *info = XineramaQueryScreens(dpy, &n);
                        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) * nn)))
       -                        die("fatal: could not malloc() %u bytes\n", sizeof(XineramaScreenInfo) * nn);
       -                for(i = 0, j = 0; i < nn; i++)
       +                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(isuniquegeom(unique, j, &info[i]))
                                        memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo));
                        XFree(info);
       -                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);
       -                                }
       +                /* create new monitor structure */
       +                n = j;
       +                mons = m = createmon(); /* new first monitor */
       +                for(i = 1; i < n; i++) {
       +                        m->next = createmon();
       +                        m = m->next;
                        }
       -                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);
       -                        }
       +                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);
                        }
                        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);
       +                        }
       +                        oldmons = m->next;
       +                        cleanupmon(m);
       +                }
                }
                else
        #endif /* XINERAMA */
                /* default monitor setup */
                {
       -                if(!mons)
       +                if(!mons) /* only true if !XINERAMA compile flag */
                                mons = createmon();
                        if(mons->mw != sw || mons->mh != sh) {
       -                        dirty = True;
                                mons->mw = mons->ww = sw;
                                mons->mh = mons->wh = sh;
                                updatebarpos(mons);
                        }
                }
       -        if(dirty) {
       -                selmon = mons;
       -                selmon = wintomon(root);
       -        }
       -        return dirty;
       +        selmon = mons;
       +        selmon = wintomon(root);
        }
        
        void