URI: 
       implemented different version of updategeom - dwm - dynamic window manager
  HTML git clone https://git.parazyd.org/dwm
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 07ad2981337c9154fe84078454e646771b5a3425
   DIR parent f0a4845e7dec3a4c7316311fcf1108148bb29730
  HTML Author: Anselm R Garbe <anselm@garbe.us>
       Date:   Mon, 21 Sep 2009 19:51:17 +0100
       
       implemented different version of updategeom
       Diffstat:
         M config.mk                           |       8 ++++----
         M dwm.c                               |     234 +++++++++++--------------------
       
       2 files changed, 89 insertions(+), 153 deletions(-)
       ---
   DIR diff --git a/config.mk b/config.mk
       @@ -20,10 +20,10 @@ LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS}
        
        # flags
        CPPFLAGS = -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
       -#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
       -CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
       -#LDFLAGS = -g ${LIBS}
       -LDFLAGS = -s ${LIBS}
       +CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
       +#CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
       +LDFLAGS = -g ${LIBS}
       +#LDFLAGS = -s ${LIBS}
        
        # Solaris
        #CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
   DIR diff --git a/dwm.c b/dwm.c
       @@ -163,6 +163,7 @@ static void clearurgent(Client *c);
        static void configure(Client *c);
        static void configurenotify(XEvent *e);
        static void configurerequest(XEvent *e);
       +static Monitor *createmon(void);
        static void destroynotify(XEvent *e);
        static void detach(Client *c);
        static void detachstack(Client *c);
       @@ -592,6 +593,22 @@ configurerequest(XEvent *e) {
                XSync(dpy, False);
        }
        
       +Monitor *
       +createmon(void) {
       +        Monitor *m;
       +
       +        if(!(m = (Monitor *)calloc(1, sizeof(Monitor))))
       +                die("fatal: could not malloc() %u bytes\n", sizeof(Monitor));
       +        m->tagset[0] = m->tagset[1] = 1;
       +        m->mfact = mfact;
       +        m->showbar = showbar;
       +        m->topbar = topbar;
       +        m->lt[0] = &layouts[0];
       +        m->lt[1] = &layouts[1 % LENGTH(layouts)];
       +        m->ltsymbol = layouts[0].symbol;
       +        return m;
       +}
       +
        void
        destroynotify(XEvent *e) {
                Client *c;
       @@ -1005,6 +1022,19 @@ isprotodel(Client *c) {
                return ret;
        }
        
       +#ifdef XINERAMA
       +static Bool
       +isuniquegeom(XineramaScreenInfo *unique, size_t len, XineramaScreenInfo *info) {
       +        unsigned int i;
       +
       +        for(i = 0; i < len; i++)
       +                if(unique[i].x_org == info->x_org && unique[i].y_org == info->y_org
       +                && unique[i].width == info->width && unique[i].height == info->height)
       +                        return False;
       +        return True;
       +}
       +#endif /* XINERAMA */
       +
        void
        keypress(XEvent *e) {
                unsigned int i;
       @@ -1695,165 +1725,71 @@ updatebarpos(Monitor *m) {
        
        Bool
        updategeom(void) {
       -        int i, j, nn = 1, n = 1;
       -        Client *c;
       -        Monitor *newmons = NULL, *m = NULL, *tm;
       -
       -        /* TODO:
       -         * This function needs to be seriously re-designed:
       -         *
       -         * #ifdef XINERAMA
       -         * 1. Determine number of already existing monitors n
       -         * 2. Determine number of monitors Xinerama reports nn
       -         * 3. if(n <= nn) {
       -         *       if(n < nn) {
       -         *          append nn-n monitors to current struct
       -         *          flag dirty
       -         *       }
       -         *       for(i = 0; i < nn; i++) {
       -         *           if(oldgeom != newgeom) {
       -         *               apply newgeom;
       -         *               flag dirty;
       -         *           }
       -         *       }
       -         *    }
       -         *    else {
       -         *       detach all clients
       -         *       destroy current monitor struct
       -         *       create new monitor struct 
       -         *       attach all clients to first monitor
       -         *       flag dirty;
       -         *    }
       -         *    return dirty flag to caller
       -         *        if dirty is seen by caller:
       -         *           re-arrange bars/pixmaps
       -         *           arrange()
       -         * #else
       -         *    don't share between XINERAMA and non-XINERAMA handling if it gets
       -         *    too ugly
       -         * #endif
       -         */
       -#ifdef XINERAMA
       -        XineramaScreenInfo *info = NULL;
       -        Bool *flags = NULL;
       -
       -        if(XineramaIsActive(dpy))
       -                info = XineramaQueryScreens(dpy, &n);
       -        flags = (Bool *)malloc(sizeof(Bool) * n);
       -        for(i = 0; i < n; i++)
       -                flags[i] = False;
       -        /* next double-loop seeks any combination of retrieved Xinerama info
       -         * with existing monitors, this is used to avoid unnecessary
       -         * re-allocations of monitor structs */
       -        for(i = 0, nn = n; i < n; i++)
       -                for(j = 0, m = mons; m; m = m->next, j++)
       -                        if(!flags[j]) {
       -                                if((flags[j] = (
       -                                        info[i].x_org == m->mx
       -                                        && info[i].y_org == m->my
       -                                        && info[i].width == m->mw
       -                                        && info[i].height == m->mh)
       -                                ))
       -                                        --nn;
       -                        }
       -        if(nn == 0) { /* no need to re-allocate monitors */
       -                j = 0;
       -                for(i = 0, m = mons; m; m = m->next, i++) {
       -                        m->num = info[i].screen_number;
       -                        if(info[i].x_org != m->mx
       -                        || info[i].y_org != m->my
       -                        || info[i].width != m->mw
       -                        || info[i].height != m->mh)
       -                        {
       -                                m->mx = m->wx = info[i].x_org;
       -                                m->my = m->wy = info[i].y_org;
       -                                m->mw = m->ww = info[i].width;
       -                                m->mh = m->wh = info[i].height;
       -                                updatebarpos(m);
       -                                j++;
       -                        }
       -                }
       -                XFree(info);
       -                free(flags);
       -                return j > 0;
       -        }
       -        /* next algorithm only considers unique geometries as separate screens */
       -        for(i = 0; i < n; i++)
       -                flags[i] = False; /* used for ignoring certain monitors */
       -        for(i = 0, nn = n; i < n; i++)
       -                for(j = 0; j < n; j++)
       -                        if(i != j && !flags[i]) {
       -                                if((flags[i] = (
       -                                        info[i].x_org == info[j].x_org
       -                                        && info[i].y_org == info[j].y_org
       -                                        && info[i].width == info[j].width
       -                                        && info[i].height == info[j].height)
       -                                ))
       -                                        --nn;
       -                        }
       -#endif /* XINERAMA */
       -        /* allocate monitor(s) for the new geometry setup */
       -        for(i = 0; i < nn; i++) {
       -                if(!(m = (Monitor *)malloc(sizeof(Monitor))))
       -                        die("fatal: could not malloc() %u bytes\n", sizeof(Monitor));
       -                m->next = newmons;
       -                newmons = m;
       -        }
       -        /* initialise monitor(s) */
       +        Bool dirty = False;
       +
        #ifdef XINERAMA
                if(XineramaIsActive(dpy)) {
       -                for(i = 0, m = newmons; m && i < n; i++) {
       -                        if(!flags[i]) { /* only use screens that aren't dublettes */
       -                                m->num = info[i].screen_number;
       -                                m->mx = m->wx = info[i].x_org;
       -                                m->my = m->wy = info[i].y_org;
       -                                m->mw = m->ww = info[i].width;
       -                                m->mh = m->wh = info[i].height;
       -                                m = m->next;
       +                int i, j, n, nn;
       +                Monitor *m;
       +                XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn);
       +                XineramaScreenInfo *unique = NULL;
       +
       +                info = XineramaQueryScreens(dpy, &nn);
       +                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(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 = unique[i].screen_number;
       +                                        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);
       +                                }
                        }
       -                XFree(info);
       -                free(flags);
       +                else { /* less monitors available */
       +                        cleanup();
       +                        setup();
       +                }
       +                free(unique);
                }
                else
        #endif /* XINERAMA */
                /* default monitor setup */
                {
       -                m->num = 0;
       -                m->mx = m->wx = 0;
       -                m->my = m->wy = 0;
       -                m->mw = m->ww = sw;
       -                m->mh = m->wh = sh;
       -        }
       -        /* bar geometry setup */
       -        for(m = newmons; m; m = m->next) {
       -                m->sel = m->stack = m->clients = NULL;
       -                m->seltags = 0;
       -                m->sellt = 0;
       -                m->tagset[0] = m->tagset[1] = 1;
       -                m->mfact = mfact;
       -                m->showbar = showbar;
       -                m->topbar = topbar;
       -                m->lt[0] = &layouts[0];
       -                m->lt[1] = &layouts[1 % LENGTH(layouts)];
       -                m->ltsymbol = layouts[0].symbol;
       -                updatebarpos(m);
       -        }
       -        /* reassign left over clients of disappeared monitors */
       -        for(tm = mons; tm; tm = tm->next)
       -                while(tm->clients) {
       -                        c = tm->clients;
       -                        tm->clients = c->next;
       -                        detachstack(c);
       -                        c->mon = newmons;
       -                        attach(c);
       -                        attachstack(c);
       +                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);
                        }
       -        /* select focused monitor */
       -        cleanupmons();
       -        selmon = mons = newmons;
       -        selmon = wintomon(root);
       -        return True;
       +        }
       +        if(dirty) {
       +                selmon = mons;
       +                selmon = wintomon(root);
       +        }
       +        return dirty;
        }
        
        void