[xmonad] Issue 96 in xmonad: certain dialogs get dropped in gnucash

Jason Creighton jcreigh at gmail.com
Tue Dec 11 02:24:55 EST 2007

On Sun, Dec 09, 2007 at 10:07:34AM +0000, Thomas Adam wrote:
> Hi --
> On 09/12/2007, codesite-noreply at google.com <codesite-noreply at google.com> wrote:
> > Issue 96: certain dialogs get dropped in gnucash
> > http://code.google.com/p/xmonad/issues/detail?id=96
> >
> > Comment #1 by jcreigh:
> > This is definitely an xmonad bug, as the problem does not occur if
> > Gnucash windows
> > are ignored (with, eg, className =? "Gnucash" --> doIgnore)
> I bet I know what this bug is (I;m assuming transient windows here):
> The window is being mapped and unmapped.  If you were to use something
> like xscope then you might see that:
> a) Application sends a mapRequest.
> a1) Before xmonad has a chance to do that, the application asks to be
> put in the WithDrawn state (via a synthetic UnmapNotify event).
> b) The window is mapped.
> c) GNUCash sends a MapRequest.
> d) Another UnmapNotify request is sent and the window is UnMapped.
> e) The MapRequest from (c) is handled and a real UnMapNotify request
> is issued causing the window it close, never being mapped again.
> I'm guessing this is what's happening, but I don't run GnuCash.

Thanks for the pointer. I think I've found the issue, but I'm not 100%
sure it's the same one that you're describing. What I'm seeing is this:

1) Gnucash sends a MapRequest event
2) Gnucash sends a synthetic UnmapNotify event
3) Gnucash sends a MapRequest event agin.

I don't know why Gnucash does it that way., it's just what seems to be
happening from the trace. Presumably there's a reason.

4) xmonad maps the window, in response to (1)
5) xmonad unmaps the window, in response to (2)
6) xmonad receives an UnmapNotify in response to (5), but it isn't
processed yet, because we still haven't even got to (3)
7) xmonad maps the window again, in response to (3)
8) xmonad unmaps the window, due to the UnmapNotify we got in (6) and
have just now got around to processing.

(This account of the events is reconstructed from a xmond [sic] trace of
xmonad, so this is the order that xmonad received them. Obviously an
event trace doesn't tell me *why* xmonad is doing these things, I'm
infering that from looking at the event processing code. So there's a
chance that I'm wrong about which code path is being taken when xmonad
maps or unmaps a window.)

Now, we have a waitingUnmap Map to record how many unmaps we can safely
ignore, but unmange looks like this:

unmanage w = do
    windows (W.delete w)
    setWMState w withdrawnState
    modify (\s -> s {mapped = S.delete w (mapped s), waitingUnmap = M.delete w (waitingUnmap s)})

"windows" will call "hide" on the no-longer-visible window, which will
increment waitingUnmap and remove that window from "mapped". But then
"unmanage" clears "waitingUnmap" after that, which is why in (8) xmonad
doesn't ignore the UnmapNotify like it should.

And indeed, if you comment out that line in "unmanage", the gnucash find
dialog works fine.

So now I'm wondering why unmanage does that in the first place when it
seems like letting "hide" handle it would be fine. On #xmonad, sjanssen
mentioned the issue of avoiding a space leak, so that's one concern to
keep in mind.

Jason Creighton

More information about the xmonad mailing list