Remember if focus changes were caused by mouse actions or by key commands

If the user used the mouse to change window focus (moving into or clicking on a
window), this should be handled differently than focus changes due to keyboard
commands. Specifically, it's inappropriate to discard window enter/leave events
while the mouse is moving. This fixes the bug where a fast mouse motion across
multiple windows resulted in the wrong window keeping focus.

It's also helpful information for contrib modules such as UpdatePointer - it's
supposed to move the mouse pointer only in response to keyboard actions, not if
the user was moving the mouse.
This commit is contained in:
Klaus Weidner
2008-05-02 17:56:03 +00:00
parent ba3987f299
commit d8d636e573
3 changed files with 8 additions and 3 deletions

View File

@@ -69,6 +69,7 @@ data XConf = XConf
-- ^ a mapping of key presses to actions
, buttonActions :: !(M.Map (KeyMask, Button) (Window -> X ()))
-- ^ a mapping of button presses to actions
, mouseFocused :: !Bool -- ^ was refocus caused by mouse action?
}
-- todo, better name

View File

@@ -98,7 +98,8 @@ xmonad initxmc = do
, normalBorder = nbc
, focusedBorder = fbc
, keyActions = keys xmc xmc
, buttonActions = mouseBindings xmc xmc }
, buttonActions = mouseBindings xmc xmc
, mouseFocused = False }
st = XState
{ windowset = initialWinset
, mapped = S.empty

View File

@@ -165,7 +165,8 @@ windows f = do
-- will overwrite withdrawnState with iconicState
mapM_ (flip setWMState withdrawnState) (W.allWindows old \\ W.allWindows ws)
clearEvents enterWindowMask
isMouseFocused <- asks mouseFocused
unless isMouseFocused $ clearEvents enterWindowMask
-- | setWMState. set the WM_STATE property
setWMState :: Window -> Int -> X ()
@@ -294,7 +295,9 @@ setTopFocus = withWindowSet $ maybe (setFocusX =<< asks theRoot) setFocusX . W.p
-- the mouse to a new screen).
focus :: Window -> X ()
focus w = withWindowSet $ \s -> do
if W.member w s then when (W.peek s /= Just w) $ windows (W.focusWindow w)
if W.member w s then when (W.peek s /= Just w) $ do
local (\c -> c { mouseFocused = True }) $ do
windows (W.focusWindow w)
else whenX (isRoot w) $ setFocusX w
-- | Call X to set the keyboard focus details.