Discussion:
[xmonad] Issue 602 in xmonad: xmonad hangs when clickJustFocuses = False and the user clicks outside of the focused window while a submap is active.
c***@google.com
2015-04-16 13:11:16 UTC
Permalink
Status: New
Owner: ----

New issue 602 by ***@gmail.com: xmonad hangs when clickJustFocuses =
False and the user clicks outside of the focused window while a submap is
active.
https://code.google.com/p/xmonad/issues/detail?id=602

What steps will reproduce the problem?
1. Set clickJustFocuses = False
2. Activate a submap or submapDefault (XMonad.Actions.Submap)
3. Click outside of the currently focused window.


What is the expected output?

I'm not sure if expected output is defined, but when clickJustFocuses =
True, any clicks are ignored until after the submap is exited, after which
the focus is brought to the most recently clicked window.

Ideally, one might be able to specify that a click aborts the submap,
instead, or to specify a submap action resulting from a click.


What do you see instead?

XMonad hangs irrecoverably. Keybindings and clicks have no effect
whatsoever. Any programs active in the background (e.g. music) continue as
without user input.


Please use labels and text to provide additional information.

I have attached a minimal xfce config (I have not tested this outside of
xfce) that reproduces the error.

The steps for reproducing are:

1. Mod+l (activates testSubmap)

2. Click outside of the currently focused window

Remarks: the error also occurs if testSubmap is made into an empty map.

Attachments:
xfce_xmonad.hs 1.1 KB
--
You received this message because this project is configured to send all
issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings
c***@google.com
2015-04-18 17:17:46 UTC
Permalink
Comment #1 on issue 602 by ***@gmail.com: xmonad hangs when
clickJustFocuses = False and the user clicks outside of the focused window
while a submap is active.
https://code.google.com/p/xmonad/issues/detail?id=602

At a guess, it's using a private event loop instead of the main loop and
discarding the messages that would change focus (since it has only a
keyboard grab). Either it should grab the pointer to prevent focusing
anything else, or it should use the main event loop (via handleEventHook)
to recognize keys.

(This is unfortunately a common problem with xmonad contribs; most of their
authors do not understand X11 event flow, or how events interact, and use
naïve solutions that fail in various circumstances. This is most obviously
true with the contribs that manipulate the selection, since the naïve view
thinks a selection is a box that holds content, when it is actually an
invitation to an event dialog with the selection holder; but private event
loops also tend to show the problem.)

--
You received this message because this project is configured to send all
issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings
c***@google.com
2015-04-18 17:22:08 UTC
Permalink
Comment #2 on issue 602 by ***@gmail.com: xmonad hangs when
clickJustFocuses = False and the user clicks outside of the focused window
while a submap is active.
https://code.google.com/p/xmonad/issues/detail?id=602

Actually, a third possibility is to peekEvent and abort the submap if a
non-key event is seen, letting the main loop handle the event. In fact,
this is probably closest to the expected behavior.
--
You received this message because this project is configured to send all
issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings
c***@google.com
2015-04-30 04:48:52 UTC
Permalink
Comment #3 on issue 602 by ***@gmail.com: xmonad hangs when
clickJustFocuses = False and the user clicks outside of the focused window
while a submap is active.
https://code.google.com/p/xmonad/issues/detail?id=602

Thank you for your response. Following your suggestion, I've been working
on a prototype that may eventually lead to a handleEventHook submap.
However, so far I've observed three behaviors that may be problematic:

1. handleEventHook does not process KeyEvents for any particular key (e.g.
if I wanted to put xK_f into my submap) unless I put a dummy binding for
that key in my config's "keys = ..."

2. If I do put a dummy binding in, xmonad grabs the KeyEvent for that key
under all circumstances - I can't turn it on or off - and never "resends"
them back to the window in question. So if I bind xK_f for example,
programs no longer receive an "f" unless I resend it myself using (the only
working one I've found so far) XMonad.Util.Paste.sendKey.

3. Though sendKey generally seems to work, some programs react differently
to the "fake" sendKey events. Thankfully, it's been limited to some subtle
cursor behaviors in emacs so far.

Is there any method that does not require using sendKey - say, a way to
turn certain keybindings on/off, or otherwise to make it so that
xmonad "forwards" KeyEvents when they are no longer being captured by a
submap? Alternatively, is there some other approach I should be using?

Thanks again.
--
You received this message because this project is configured to send all
issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings
c***@google.com
2015-04-30 05:07:15 UTC
Permalink
Comment #4 on issue 602 by ***@gmail.com: xmonad hangs when
clickJustFocuses = False and the user clicks outside of the focused window
while a submap is active.
https://code.google.com/p/xmonad/issues/detail?id=602

Thank you for your response. Following your suggestion, I've been working
on a prototype that may eventually lead to a handleEventHook submap.
However, so far I've observed three behaviors that may be problematic:

1. handleEventHook does not process KeyEvents for any particular key (e.g.
if I wanted to put xK_f into my submap) unless I put a dummy binding for
that key in my config's "keys = ..."

2. If I do put a dummy binding in, xmonad grabs the KeyEvent for that key
under all circumstances - I can't turn it on or off - and never "resends"
them back to the window in question. So if I bind xK_f for example,
programs no longer receive an "f" unless I resend it myself using (the only
working one I've found so far) XMonad.Util.Paste.sendKey.

3. Some programs react differently to the "fake" sendKey events. So far,
certain file managers (thunar, nemo) doesn't recognize the keys, and some
save dialogs won't let you create folders using those keys.

Is there any method that does not require using sendKey - say, a way to
turn certain keybindings on/off, or otherwise to make it so that
xmonad "forwards" KeyEvents when they are no longer being captured by a
submap? Alternatively, is there some other approach I should be using?

Thanks again.
--
You received this message because this project is configured to send all
issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings
c***@google.com
2015-04-30 15:41:10 UTC
Permalink
Comment #5 on issue 602 by ***@gmail.com: xmonad hangs when
clickJustFocuses = False and the user clicks outside of the focused window
while a submap is active.
https://code.google.com/p/xmonad/issues/detail?id=602

To fix problem 1 (without invoking problem 2), you want to add keyPressMask
to your config's clientMask. This option is available in the darcs source
but it doesn't seem to have made it to any hackage releases yet.

I have noticed problem 3 but can't offer any way to solve it.
--
You received this message because this project is configured to send all
issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings
c***@google.com
2015-04-30 16:02:00 UTC
Permalink
Comment #6 on issue 602 by ***@gmail.com: xmonad hangs when
clickJustFocuses = False and the user clicks outside of the focused window
while a submap is active.
https://code.google.com/p/xmonad/issues/detail?id=602

You should probably look closer at the approach in comment 2
(https://code.google.com/p/xmonad/issues/detail?id=602#c2) instead.
Arguably a key sequence should not involve mouse events at all and should
simply give up if it sees one. Use peekEvent, which leaves the event in the
input queue so that it doesn't need to be reinjected as a synthetic event
that programs may ignore for security reasons.
--
You received this message because this project is configured to send all
issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings
c***@google.com
2015-04-30 17:11:15 UTC
Permalink
Comment #7 on issue 602 by ***@gmail.com: xmonad hangs when
clickJustFocuses = False and the user clicks outside of the focused window
while a submap is active.
https://code.google.com/p/xmonad/issues/detail?id=602

If you return (All True) from your event handler, then the event will be
left on the queue (unless I've badly misunderstood something?). peekEvent
lets you handle the next event regardless of whether it's one that xmonad
cares about, but if you just want to use the submap for keypresses and
abort on mouse events then handleEventHook seems cleaner to me.
--
You received this message because this project is configured to send all
issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings
c***@google.com
2015-04-30 17:21:16 UTC
Permalink
Comment #8 on issue 602 by ***@gmail.com: xmonad hangs when
clickJustFocuses = False and the user clicks outside of the focused window
while a submap is active.
https://code.google.com/p/xmonad/issues/detail?id=602

handleEventHook is used when you are running from the main loop. This is
actually not ideal, as submaps don't really want to be mixed into the main
loop; reworking with the handleEventHook has several potential difficulties
some of which you have already encountered. A potentially worse issue is
that the main loop does not expect to be running under an existing keyboard
grab, as it would need to in this case; I don't know offhand if this will
be a problem, and didn't think about it in my initial response --- which is
kinda bad as ignoring things like that is how we get extensions that hang
or crash xmonad. :/

There is the additional issue that, since you're processing from
handleEventHook, you don't get to deal with events that interrupt your
submap --- exactly the problem you are trying to solve here. Switching
window focus with the mouse in the middle of a key sequence that affects
the focused window may lead to unexpected results and user confusion. This
is why I brought up the third alternative.
--
You received this message because this project is configured to send all
issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings
c***@google.com
2015-05-02 06:33:07 UTC
Permalink
Comment #9 on issue 602 by ***@gmail.com: xmonad hangs when
clickJustFocuses = False and the user clicks outside of the focused window
while a submap is active.
https://code.google.com/p/xmonad/issues/detail?id=602

I like the peekEvent/nextEvent solution (though I'll continue exploring the
handleEventHook one as well), but the fact that it can only read from the
head of the event queue makes me nervous. If I call nextEvent repeatedly
until reaching a KeyEvent/ButtonEvent, that has the side-effect of purging
all intermediate events from the queue. By contrast, submap currently uses
maskEvent to (if I'm understanding correctly) defer intermediate event
processing until after the submap, allowing those events to still be
processed after. Is there a way to do something similar to:

peekMaskEvent dply (keyPressMask .|. buttonReleaseMask) pointer

-- contains key or button event
peeked_event <- getEvent pointer

then decide whether or not to use

maskEvent dply (keyPressMask .|. buttonReleaseMask) pointer

-- contains key or button event
removed_event <- getEvent pointer

to remove it? XPeekIfEvent looks promising, but it doesn't appear to be
implemented yet.
Post by c***@google.com
To fix problem 1 (without invoking problem 2), you want to add
keyPressMask to your config's clientMask.
Thanks.
--
You received this message because this project is configured to send all
issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings
c***@google.com
2015-05-02 17:10:57 UTC
Permalink
Comment #10 on issue 602 by ***@gmail.com: xmonad hangs when
clickJustFocuses = False and the user clicks outside of the focused window
while a submap is active.
https://code.google.com/p/xmonad/issues/detail?id=602

I can't seem to find whether XPutBackEvent generates a synthetic event or
not, but if it doesn't then you can use maskEvent followed by putBackEvent
if the event isn't a keypress.

I'm not familiar with X11's concurrency model, but looking for an event
with peek and then possibly pulling it off the event stack seems unsafe
since the event could be removed in between those steps.
--
You received this message because this project is configured to send all
issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings
c***@google.com
2015-05-02 22:15:36 UTC
Permalink
Comment #11 on issue 602 by ***@gmail.com: xmonad hangs when
clickJustFocuses = False and the user clicks outside of the focused window
while a submap is active.
https://code.google.com/p/xmonad/issues/detail?id=602

Best as I can tell, putBackEvent does not actually work..! I've attached
another minimal (xfce) test config.

Attachments:
xfce_xmonad.hs 3.1 KB
--
You received this message because this project is configured to send all
issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings
c***@google.com
2015-05-02 22:21:47 UTC
Permalink
Comment #12 on issue 602 by ***@gmail.com: xmonad hangs when
clickJustFocuses = False and the user clicks outside of the focused window
while a submap is active.
https://code.google.com/p/xmonad/issues/detail?id=602

You seem to be continuing to miss the point. You do not want to ignore or
bypass or drop those non-key events; you want to *stop processing and
return control to xmonad*. If you click somewhere in the middle of a key
sequence in Emacs, does it continue to process the key sequence? How about
if you go to activate a GUI menu item via keyboard with alt-sequences but
click somewhere in the middle of it?

These do not ignore the click, they abort the key sequence completely and
process the click.
--
You received this message because this project is configured to send all
issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings
c***@google.com
2015-05-02 23:07:30 UTC
Permalink
Comment #13 on issue 602 by ***@gmail.com: xmonad hangs when
clickJustFocuses = False and the user clicks outside of the focused window
while a submap is active.
https://code.google.com/p/xmonad/issues/detail?id=602

The problem is that peekEvent does not only admit key/mouse events, but
every event (as far as I can tell). So, aborting on the first peeked
non-key event leads to the submap being terminated near-instantly.

I've been trying to find a way to only peek at the first key/button event.
But, since peekEvent only peeks at the beginning of the queue, so far I've
only managed to do so by consuming (using nextEvent) every event up until
first key/button event. I think we all agree that shouldn't happen, so
I've been searching for alternatives, such as getting the next key/button
event then putting it back (which unfortunately doesn't seem to be working).
--
You received this message because this project is configured to send all
issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings
Loading...