From 07ad2981337c9154fe84078454e646771b5a3425 Mon Sep 17 00:00:00 2001 From: Anselm R Garbe Date: Mon, 21 Sep 2009 19:51:17 +0100 Subject: implemented different version of updategeom --- dwm.c | 234 ++++++++++++++++++++++++------------------------------------------ 1 file changed, 85 insertions(+), 149 deletions(-) (limited to 'dwm.c') diff --git a/dwm.c b/dwm.c index 73633966..8ddc072e 100644 --- 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 -- cgit v1.2.3