From adced0a8c807f465eb460307bf18b3b16133d53c Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Wed, 9 Feb 2022 23:53:16 +0000 Subject: [PATCH] X.A.{Grid,Tree}Select: Fix keybindings in secondary kbd layouts We didn't clean XKB group bits out of the KeyPress events' state so key bindings only worked in the primary keyboard layout (first XKB group). To fix this, this adds a `cleanKeyMask` function to X.Prelude which is analogous to `cleanMask` but aimed at cleaning regular KeyPress states (as opposed to just KeyPresses from passive key grabs), and this is then used instead of `cleanMask`. Related: https://github.com/xmonad/xmonad-contrib/issues/290 Related: https://github.com/xmonad/xmonad-contrib/pull/590 --- XMonad/Actions/GridSelect.hs | 2 +- XMonad/Actions/TreeSelect.hs | 2 +- XMonad/Prelude.hs | 16 ++++++++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/XMonad/Actions/GridSelect.hs b/XMonad/Actions/GridSelect.hs index f33f0dcd..1ba0aa63 100644 --- a/XMonad/Actions/GridSelect.hs +++ b/XMonad/Actions/GridSelect.hs @@ -409,7 +409,7 @@ makeXEventhandler keyhandler = fix $ \me -> join $ liftX $ withDisplay $ \d -> l then do (ks,s) <- lookupString $ asKeyEvent e return $ do - mask <- liftX $ cleanMask (ev_state ev) + mask <- liftX $ cleanKeyMask <*> pure (ev_state ev) keyhandler (fromMaybe xK_VoidSymbol ks, s, mask) else return $ stdHandle ev me diff --git a/XMonad/Actions/TreeSelect.hs b/XMonad/Actions/TreeSelect.hs index 110930a7..8727634e 100644 --- a/XMonad/Actions/TreeSelect.hs +++ b/XMonad/Actions/TreeSelect.hs @@ -535,7 +535,7 @@ navigate = gets tss_display >>= \d -> join . liftIO . allocaXEvent $ \e -> do if | ev_event_type ev == keyPress -> do (ks, _) <- lookupString $ asKeyEvent e return $ do - mask <- liftX $ cleanMask (ev_state ev) + mask <- liftX $ cleanKeyMask <*> pure (ev_state ev) f <- asks ts_navigate fromMaybe navigate $ M.lookup (mask, fromMaybe xK_VoidSymbol ks) f | ev_event_type ev == buttonPress -> do diff --git a/XMonad/Prelude.hs b/XMonad/Prelude.hs index de2a83cf..227211d1 100644 --- a/XMonad/Prelude.hs +++ b/XMonad/Prelude.hs @@ -24,6 +24,7 @@ module XMonad.Prelude ( safeGetWindowAttributes, keyToString, keymaskToString, + cleanKeyMask, ) where import Foreign (alloca, peek) @@ -116,3 +117,18 @@ keymaskToString numLockMask msk = -- pair, into a string. keyToString :: (KeyMask, KeySym) -> [Char] keyToString = uncurry (++) . bimap (keymaskToString 0) keysymToString + +-- | Strip numlock, capslock, mouse buttons and XKB group from a 'KeyMask', +-- leaving only modifier keys like Shift, Control, Super, Hyper in the mask +-- (hence the \"Key\" in \"cleanKeyMask\"). +-- +-- Core's 'cleanMask' only strips the first two because key events from +-- passive grabs (key bindings) are stripped of mouse buttons and XKB group by +-- the X server already for compatibility reasons. For more info, see: +-- +cleanKeyMask :: X (KeyMask -> KeyMask) +cleanKeyMask = cleanKeyMask' <$> gets numberlockMask + +cleanKeyMask' :: KeyMask -> KeyMask -> KeyMask +cleanKeyMask' numLockMask mask = + mask .&. complement (numLockMask .|. lockMask) .&. (button1Mask - 1)