After updating from 5.5 to 5.6 I encountered a bug relating to unclutter[1]. Steps to reproduse:
1. Start dwm 5.6 with default config and unclutter with default params. 2. Open more than one window in the active tag. 3. Wait until unclutter hides the cursor. 4. Switch to a window not focused by the previously visible cursor using the keyboard. 5. The window border will start flickering (looking like it gets unfocused and focused rapidly in succession). 6. The cursor will also start to flicker. 7. Using the keboard to focus the window the cursor was focusing when visible will stop the flickering. Moving the cursor (so that unclutter displays it again) will also stop the flicker until unclutter hides it again. This bug was introduced in changeset 1418 37e3b2a40f6f [2]. The problem is that XSetInputFocus is called through the unfocus() function from focus(). As I'm not familiar with Xlib I'm not sure how to fix this bug, but I've been able to pinpoint the erroneous code and disable the XSetInputFocus call when unfocus() is called from focus(). I've attached a patch against changeset 1477 aefd753cfe9b which does exactly this. Note that this was made just to highlight which code path triggers the described behavior and is not meant as a patch for fixing the bug. [1]: http://www.ibiblio.org/pub/X11/contrib/utilities/unclutter-8.README [2]: http://code.suckless.org/hg/dwm/rev/37e3b2a40f6f -- Cheers, Eivind Uggedal
diff -r aefd753cfe9b dwm.c --- a/dwm.c Mon Jul 27 12:01:58 2009 +0100 +++ b/dwm.c Sat Aug 01 13:10:24 2009 +0200 @@ -217,7 +217,9 @@ static void togglefloating(const Arg *arg); static void toggletag(const Arg *arg); static void toggleview(const Arg *arg); +static void _unfocus(Client *c, Bool setinputfocus); static void unfocus(Client *c); +static void unfocus2(Client *c); static void unmanage(Client *c); static void unmapnotify(XEvent *e); static void updategeom(void); @@ -792,7 +794,7 @@ if(!c || !ISVISIBLE(c)) for(c = selmon->stack; c && !ISVISIBLE(c); c = c->snext); if(selmon->sel) - unfocus(selmon->sel); + unfocus2(selmon->sel); if(c) { if(c->mon != selmon) selmon = c->mon; @@ -1613,12 +1615,23 @@ } void -unfocus(Client *c) { +_unfocus(Client *c, Bool setinputfocus) { if(!c) return; grabbuttons(c, False); XSetWindowBorder(dpy, c->win, dc.norm[ColBorder]); - XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); + if(setinputfocus) + XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); +} + +void +unfocus(Client *c) { + _unfocus(c, True); +} + +void +unfocus2(Client *c) { + _unfocus(c, False); } void