Skip to content

Commit

Permalink
X.A.{Grid,Tree}Select: Fix keybindings in secondary kbd layouts
Browse files Browse the repository at this point in the history
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: xmonad#290
Related: xmonad#590
  • Loading branch information
liskin committed Feb 9, 2022
1 parent 2e3254a commit adced0a
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 2 deletions.
2 changes: 1 addition & 1 deletion XMonad/Actions/GridSelect.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion XMonad/Actions/TreeSelect.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 16 additions & 0 deletions XMonad/Prelude.hs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ module XMonad.Prelude (
safeGetWindowAttributes,
keyToString,
keymaskToString,
cleanKeyMask,
) where

import Foreign (alloca, peek)
Expand Down Expand Up @@ -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:
-- <https://www.x.org/releases/X11R7.7/doc/kbproto/xkbproto.html#Delivering_a_Key_or_Button_Event_to_a_Client>
cleanKeyMask :: X (KeyMask -> KeyMask)
cleanKeyMask = cleanKeyMask' <$> gets numberlockMask

cleanKeyMask' :: KeyMask -> KeyMask -> KeyMask
cleanKeyMask' numLockMask mask =
mask .&. complement (numLockMask .|. lockMask) .&. (button1Mask - 1)

0 comments on commit adced0a

Please sign in to comment.