mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-05-19 03:20:21 -07:00
XMonad.Prompt: Allow Pointer Events
If this is not done, trying to select another window with the mouse when the prompt is up, the X server executes a pointer/keyboard grab until `allowEvents' is called; which it never is and so both remain frozen indefinitely. C.f.: - xmonad/xmonad/issues/116 - xmonad/xmonad-contrib/issues/445
This commit is contained in:
parent
b8ac9804fc
commit
08a165df40
@ -619,7 +619,8 @@ eventLoop handle stopAction = do
|
|||||||
[] -> do
|
[] -> do
|
||||||
d <- gets dpy
|
d <- gets dpy
|
||||||
io $ allocaXEvent $ \e -> do
|
io $ allocaXEvent $ \e -> do
|
||||||
maskEvent d (exposureMask .|. keyPressMask) e
|
-- Also capture @buttonPressMask@, see Note [Allow ButtonEvents]
|
||||||
|
maskEvent d (exposureMask .|. keyPressMask .|. buttonPressMask) e
|
||||||
ev <- getEvent e
|
ev <- getEvent e
|
||||||
(ks,s) <- if ev_event_type ev == keyPress
|
(ks,s) <- if ev_event_type ev == keyPress
|
||||||
then lookupString $ asKeyEvent e
|
then lookupString $ asKeyEvent e
|
||||||
@ -635,14 +636,39 @@ eventLoop handle stopAction = do
|
|||||||
evDefaultStop :: XP Bool
|
evDefaultStop :: XP Bool
|
||||||
evDefaultStop = (||) <$> (gets modeDone) <*> (gets done)
|
evDefaultStop = (||) <$> (gets modeDone) <*> (gets done)
|
||||||
|
|
||||||
-- | Common patterns shared by all event handlers. Expose events can be
|
-- | Common patterns shared by all event handlers.
|
||||||
-- triggered by switching virtual consoles.
|
|
||||||
handleOther :: KeyStroke -> Event -> XP ()
|
handleOther :: KeyStroke -> Event -> XP ()
|
||||||
handleOther _ (ExposeEvent {ev_window = w}) = do
|
handleOther _ (ExposeEvent {ev_window = w}) = do
|
||||||
|
-- Expose events can be triggered by switching virtual consoles.
|
||||||
st <- get
|
st <- get
|
||||||
when (win st == w) updateWindows
|
when (win st == w) updateWindows
|
||||||
|
handleOther _ (ButtonEvent {ev_event_type = t}) = do
|
||||||
|
-- See Note [Allow ButtonEvents]
|
||||||
|
when (t == buttonPress) $ do
|
||||||
|
d <- gets dpy
|
||||||
|
io $ allowEvents d replayPointer currentTime
|
||||||
handleOther _ _ = return ()
|
handleOther _ _ = return ()
|
||||||
|
|
||||||
|
{- Note [Allow ButtonEvents]
|
||||||
|
|
||||||
|
Some settings (like @clickJustFocuses = False@) set up the passive
|
||||||
|
pointer grabs that xmonad makes to intercept clicks to unfocused windows
|
||||||
|
with @pointer_mode = grabModeSync@ and @keyboard_mode = grabModeSync@.
|
||||||
|
This means that any click in an unfocused window leads to a
|
||||||
|
pointer/keyboard grab that freezes both devices until 'allowEvents' is
|
||||||
|
called. But "XMonad.Prompt" has its own X event loop, so 'allowEvents'
|
||||||
|
is never called and everything remains frozen indefinitely.
|
||||||
|
|
||||||
|
This does not happen when the grabs are made with @grabModeAsync@, as
|
||||||
|
pointer events processing is not frozen and the grab only lasts as long
|
||||||
|
as the mouse button is pressed.
|
||||||
|
|
||||||
|
Hence, in this situation we call 'allowEvents' in the prompts event loop
|
||||||
|
whenever a button event is received, releasing the pointer grab. In this
|
||||||
|
case, 'replayPointer' takes care of the fact that these events are not
|
||||||
|
merely discarded, but passed to the respective application window.
|
||||||
|
-}
|
||||||
|
|
||||||
-- | Prompt event handler for the main loop. Dispatches to input, completion
|
-- | Prompt event handler for the main loop. Dispatches to input, completion
|
||||||
-- and mode switching handlers.
|
-- and mode switching handlers.
|
||||||
handleMain :: KeyStroke -> Event -> XP ()
|
handleMain :: KeyStroke -> Event -> XP ()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user