X-Git-Url: https://jasonwoof.com/gitweb/?p=dwm.git;a=blobdiff_plain;f=dwm.c;h=2b4d6b03c137e8e77fa785209ee5999147e4d29b;hp=5ea74cbb27bd05fdfff429bd35b83c5b31e08afd;hb=82ec7a7ed4f3ba376faadfc2aca783b24618575f;hpb=7fe81359d46df4b3173c233a7787d81ce322c827 diff --git a/dwm.c b/dwm.c index 5ea74cb..2b4d6b0 100644 --- a/dwm.c +++ b/dwm.c @@ -121,6 +121,7 @@ typedef struct { } Layout; struct Monitor { + const char *ltsymbol; float mfact; int num; int by; /* bar geometry */ @@ -218,9 +219,9 @@ static void togglefloating(const Arg *arg); static void toggletag(const Arg *arg); static void toggleview(const Arg *arg); static void unfocus(Client *c); -static void unmanage(Client *c, Bool isdestroyed); +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 updatenumlockmask(void); @@ -238,7 +239,7 @@ static void zoom(const Arg *arg); /* variables */ static const char broken[] = "broken"; -static char stext[256], ntext[8]; +static char stext[256]; static int screen; static int sw, sh; /* X display screen geometry width, height */ static int bh, blw = 0; /* bar geometry */ @@ -384,6 +385,7 @@ arrange(void) { showhide(m->stack); focus(NULL); for(m = mons; m; m = m->next) { + m->ltsymbol = m->lt[m->sellt]->symbol; if(m->lt[m->sellt]->arrange) m->lt[m->sellt]->arrange(m); restack(m); @@ -533,14 +535,15 @@ configurenotify(XEvent *e) { if(ev->window == root) { sw = ev->width; sh = ev->height; - updategeom(); - 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); - arrange(); + if(updategeom()) { + 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); + arrange(); + } } } @@ -649,13 +652,11 @@ dirtomon(int dir) { void drawbar(Monitor *m) { int x; - unsigned int i, n = 0, occ = 0, urg = 0; + unsigned int i, occ = 0, urg = 0; unsigned long *col; Client *c; for(c = m->clients; c; c = c->next) { - if(ISVISIBLE(c)) - n++; occ |= c->tags; if(c->isurgent) urg |= c->tags; @@ -669,15 +670,10 @@ drawbar(Monitor *m) { occ & 1 << i, urg & 1 << i, col); dc.x += dc.w; } - if(blw > 0) { - dc.w = blw; - drawtext(m->lt[m->sellt]->symbol, dc.norm, False); - dc.x += dc.w; - } - snprintf(ntext, sizeof ntext, "%u", n); - dc.w = TEXTW(ntext); - drawtext(ntext, dc.norm, False); - x = (dc.x += dc.w); + dc.w = blw = TEXTW(m->ltsymbol); + drawtext(m->ltsymbol, dc.norm, False); + dc.x += dc.w; + x = dc.x; if(m == selmon) { /* status is only drawn on selected monitor */ dc.w = TEXTW(stext); dc.x = m->ww - dc.w; @@ -1039,9 +1035,15 @@ killclient(const Arg *arg) { ev.xclient.data.l[1] = CurrentTime; XSendEvent(dpy, selmon->sel->win, False, NoEventMask, &ev); } - else + else { + XGrabServer(dpy); + XSetErrorHandler(xerrordummy); + XSetCloseDownMode(dpy, DestroyAll); XKillClient(dpy, selmon->sel->win); - XSync(dpy, False); + XSync(dpy, False); + XSetErrorHandler(xerror); + XUngrabServer(dpy); + } } void @@ -1131,8 +1133,17 @@ maprequest(XEvent *e) { void monocle(Monitor *m) { + static char ntext[8]; + unsigned int n = 0; Client *c; + for(c = m->clients; c; c = c->next) + if(ISVISIBLE(c)) + n++; + if(n > 0) { /* override layout symbol */ + snprintf(ntext, sizeof ntext, "[%d]", n); + m->ltsymbol = ntext; + } for(c = nexttiled(m->clients); c; c = nexttiled(c->next)) resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, False); } @@ -1425,8 +1436,6 @@ setmfact(const Arg *arg) { void setup(void) { - unsigned int i; - int w; XSetWindowAttributes wa; /* clean up any zombies immediately */ @@ -1463,10 +1472,6 @@ setup(void) { if(!dc.font.set) XSetFont(dpy, dc.gc, dc.font.xfont->fid); /* init bars */ - for(blw = i = 0; LENGTH(layouts) > 1 && i < LENGTH(layouts); i++) { - w = TEXTW(layouts[i].symbol); - blw = MAX(blw, w); - } updatebars(); updatestatus(); /* EWMH support per view */ @@ -1627,13 +1632,13 @@ unfocus(Client *c) { } void -unmanage(Client *c, Bool isdestroyed) { +unmanage(Client *c, Bool destroyed) { XWindowChanges wc; /* The server grab construct avoids race conditions. */ detach(c); detachstack(c); - if(!isdestroyed) { + if(!destroyed) { wc.border_width = c->oldbw; XGrabServer(dpy); XSetErrorHandler(xerrordummy); @@ -1646,6 +1651,7 @@ unmanage(Client *c, Bool isdestroyed) { } free(c); focus(NULL); + arrange(); } void @@ -1687,26 +1693,73 @@ updatebarpos(Monitor *m) { m->by = -bh; } -void +Bool updategeom(void) { - int i, n = 1; + int i, j, nn = 1, n = 1; Client *c; Monitor *newmons = NULL, *m = NULL, *tm; #ifdef XINERAMA - int nn; XineramaScreenInfo *info = NULL; + Bool *flags = NULL; if(XineramaIsActive(dpy)) info = XineramaQueryScreens(dpy, &n); - for(i = 1, nn = n; i < n; i++) - if(info[i - 1].x_org == info[i].x_org && info[i - 1].y_org == info[i].y_org - && info[i - 1].width == info[i].width && info[i - 1].height == info[i].height) - --nn; - n = nn; /* we only consider unique geometries as separate screens */ + 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 < n; i++) { + 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; @@ -1715,14 +1768,18 @@ updategeom(void) { /* initialise monitor(s) */ #ifdef XINERAMA if(XineramaIsActive(dpy)) { - for(i = 0, m = newmons; m; m = m->next, i++) { - 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; + 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; + } } XFree(info); + free(flags); } else #endif /* XINERAMA */ @@ -1745,6 +1802,7 @@ updategeom(void) { 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 */ @@ -1761,6 +1819,7 @@ updategeom(void) { cleanupmons(); selmon = mons = newmons; selmon = wintomon(root); + return True; } void