[dev] [dwm] problem with configurenotify()

From: Eckehard Berns <ecki-scklss_AT_ecki.to>
Date: Thu, 1 Oct 2009 11:42:26 +0200

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
Received on Thu Oct 01 2009 - 09:42:26 UTC

This archive was generated by hypermail 2.2.0 : Thu Oct 01 2009 - 10:00:02 UTC