我希望修改XMonad.Actions.Submap,使其接受键盘和鼠标事件(例如,左键单击可能设置为执行操作,或者中止子图)。我认为第一步是抓住并取消鼠标按钮:
-- | Given a 'Data.Map.Map' from key bindings to X () actions, return
-- an action which waits for a user keypress and executes the
-- corresponding action, or does nothing if the key is not found in
-- the map.
--
-- Executes default action def if the key does not match any of the keybindings.
submapDefault :: X () -> M.Map (KeyMask, KeySym) (X ()) -> X ()
submapDefault def keys = do
XConf { theRoot = root, display = d } <- ask
io $ grabKeyboard d root False grabModeAsync grabModeAsync currentTime
-- ADDED: grab mouse buttons
-- Does it make a difference whether it's buttonPressMask or buttonReleaseMask?
io $ grabButton dply button1 anyModifier root True buttonPressMask grabModeAsync grabModeAsync none none
io $ grabButton dply button3 anyModifier root True buttonPressMask grabModeAsync grabModeAsync none none
(m, s) <- io $ allocaXEvent $ \p -> fix $ \nextkey -> do
maskEvent d keyPressMask p
KeyEvent { ev_keycode = code, ev_state = m } <- getEvent p
keysym <- keycodeToKeysym d code 0
if isModifierKey keysym
then nextkey
else return (m, keysym)
-- Remove num lock mask and Xkb group state bits
m' <- cleanMask $ m .&. ((1 `shiftL` 12) - 1)
-- ADDED: ungrab mouse buttons
io $ ungrabButton dply button1 anyModifier root
io $ ungrabButton dply button3 anyModifier root
io $ ungrabKeyboard d currentTime
maybe def id (M.lookup (m', s) keys)
但是,我不明白如何在中间调整代码,接受KeyPress或ButtonPress事件。任何帮助将不胜感激。
编辑:据我所知:
用maskEvent d keyPressMask p
替换maskEvent d (keyPressMask + buttonPressMask) p
可能是一个起点,但我不确定从那里开始。
我真的不明白 fix
。
原始问题: 很明显,如果第一个键是修饰符,则代码意味着获取第二个键。但是,由于
fix f
产生的值x
使得f x = x
,fix
不会立即终止修饰符,而是产生当时的nextKey
?我也不知道如何使用非修饰键来固定点;(m, keysym)
应该等于nextkey
?
评估alternate definition fix' f = f (fix' f)
,我们得到类似的内容:
do
maskEvent d keyPressMask p
KeyEvent { ev_keycode = code, ev_state = m } <- getEvent p
keysym <- keycodeToKeysym d code 0
if isModifierKey keysym
then (fix' \nextkey -> do ...)
else return (m, keysym)
do
maskEvent d keyPressMask p
KeyEvent { ev_keycode = code, ev_state = m } <- getEvent p
keysym <- keycodeToKeysym d code 0
if isModifierKey keysym
then (do
maskEvent d keyPressMask p
KeyEvent { ev_keycode = code, ev_state = m } <- getEvent p
keysym <- keycodeToKeysym d code 0
if isModifierKey keysym
then (fix' \nextkey -> do ...)
else return (m, keysym))
else return (m, keysym)
所以我想它只是一遍又一遍地做同样的事情,直到isModifierKey keysym
为False
。