Hi! I noticed a problem with the dwm bar when the geometry of a monitor changes twice in a row. The problem is in configurenotify() and updategeom(). When two configure notify events come in a row, the first for a smaller geometry than the next, updategeom uses the Xinerama info to get the current screen geometry, not the one reported by the event. In configurenotify the dc.drawable will be created with the width of the notify event, while the monitors already know about the actual bigger size of the screen. When the second configure notify event is seen by dwm, the dc.drawable will not be recreated in the needed size, because updategeom() doesn't see any changes.
There could also be a kind of "window" leaking. updatebars() will always create new barwins for monitors that might have changed. I didn't see any code that destroys the barwin besides the one in cleanupmon(), so I assume there will be additional barwins after a geometry change. This is a patch that addresses both problems: diff -r 2bcd25cce4ab dwm.c --- a/dwm.c Sun Sep 27 20:20:14 2009 +0100 +++ b/dwm.c Thu Oct 01 11:33:49 2009 +0200 @@ -540,19 +540,18 @@ void configurenotify(XEvent *e) { - Monitor *m; XConfigureEvent *ev = &e->xconfigure; if(ev->window == root) { - sw = ev->width; - sh = ev->height; - if(updategeom()) { + if (sw != ev->width) { + sw = ev->width; if(dc.drawable != 0) XFreePixmap(dpy, dc.drawable); dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen)); + } + sh = ev->height; + if(updategeom()) { updatebars(); - for(m = mons; m; m = m->next) - XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); arrange(NULL); } } @@ -613,6 +612,7 @@ m->mfact = mfact; m->showbar = showbar; m->topbar = topbar; + m->barwin = None; m->lt[0] = &layouts[0]; m->lt[1] = &layouts[1 % LENGTH(layouts)]; strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); @@ -1711,11 +1711,14 @@ wa.background_pixmap = ParentRelative; wa.event_mask = ButtonPressMask|ExposureMask; for(m = mons; m; m = m->next) { - m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), - CopyFromParent, DefaultVisual(dpy, screen), - CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); - XDefineCursor(dpy, m->barwin, cursor[CurNormal]); - XMapRaised(dpy, m->barwin); + if (m->barwin == None) { + m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), + CopyFromParent, DefaultVisual(dpy, screen), + CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); + XDefineCursor(dpy, m->barwin, cursor[CurNormal]); + XMapRaised(dpy, m->barwin); + } else + XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); } } -- Eckehard Berns