XMonad:有没有办法绑定同时触发的键盘?

时间:2015-01-02 18:52:30

标签: key-bindings xmonad

有没有办法同时按键进入键绑定,例如对于键 w e f ,在0.05秒内相互按下时,触发命令?

更具体一点:

  1. 如果 w e f 在0.05秒内相互按下,然后按下最后一个,XMonad应该触发所述命令。 XMonad也应该拦截这三个键,这样它们就不会被多余地发送到聚焦窗口。

  2. 否则(如果在0.05秒的时间内没有按下其中一个)XMonad应该像往常一样将密钥发送到聚焦窗口。

  3. 我的目标是使用 w e f 将“Escape”转换为类似vim的“普通模式”,一个XMonad.Actions.Submap(submap)。


    使用失败的方法进行更新,以防任何人看到修复方法:

    我试图使用子图实现这一点,所以,例如,如果按 w ,如果按下 e ,最终会进入chord_mode_w从那里你将最终进入chord_mode_we,如果你从那里按 f ,你最终会以normal_mode结束。实现非常混乱:我在主要的键绑定中包含了类似的内容:

    ("w", spawn "xdotool key <chord_mode_w_keybinding> ; sleep 0.05 ; xdotool key <abort_keybinding>")
    (chord_mode_w_keybinding, chord_mode_w)
    

    用于检测 w (其余部分类似),以及(不完整)子图,例如:

     chord_mode_w = submap . mkKeymap c $
                  [
                          ("e",  chord_mode_we )
                        , ("f",  chord_mode_wf )
                        , (abort_keybinding, pasteString "w")
    
                        -- in order for the submap to not eat all other letters,
                        -- would need to include all mappings like:
                        , ("a", pasteString "wa")
                        , ("b", pasteString "wb")
                        ...
                  ]
    
     chord_mode_we = submap . mkKeymap c $
                   [
                          ("f",  normal_mode )
                        , (abort_keybinding, pasteString "we")
    
    
                        -- in order for the submap to not eat all other letters,
                        -- would need to include all mappings like:
                        , ("a", pasteString "wea")
                        , ("b", pasteString "web")
                        ...
                   ]
    
     chord_mode_wf = submap . mkKeymap c $
                   [
                          ("e",  normal_mode )
                        , (abort_keybinding, pasteString "wf")
    
                        -- in order for the submap to not eat all other letters,
                        -- would need to include all mappings like:
                        , ("a", pasteString "wfa")
                        , ("b", pasteString "wfb")
                        ...
                   ]
    

    一个完整的实现显然会非常混乱,但理论上如果我在0.05秒之内按下“wef”,就应该把我送到normal_mode,否则输入并输入字符。然而,有两个问题:

    1. pasteString(以及XMonad.Util.Paste中的其他粘贴功能)对于正常输入来说太慢了

    2. 即使我将中止延迟设置得更高,我也只会在normal_mode中只有一小部分时间。不确定这背后的原因。

    3. (我在中止而不是产生另一个pasteString时使用xdotool的原因是xdotool的输出会重新触发其中一个chord_mode_w_keybinding,{{1} },chord_mode_e_keybinding,回到主键绑定中,无限期地将我送回和弦模式。)

1 个答案:

答案 0 :(得分:6)

https://hackage.haskell.org/package/xmonad-contrib-0.13/docs/XMonad-Actions-Submap.html

Submap确实做了几乎你想要的东西(它让你大部分都在那里)......我会建议你可能想改变你想要做的事情,所以稍微,然后Submaps完美地处理它。

您可以配置Submap以捕获w键事件,并开始等待e然后等待f。我甚至试过这个,并确认它有效:

, ((0, xK_w), submap . M.fromList $
    [ ((0, xK_e),    submap . M.fromList $
      [ ((0, xK_f),  spawn "notify-send \"wef combo detected!\"" ) ])
    ])

然而,上面几乎肯定不是你真正想做的事情......因为现在无法向窗口发送w按键(我必须在输入此答案之前禁用该配置,这需要向活动窗口发送几个w按键事件)

我刚才看到的这种行为是:如果我按w,xmonad会捕获该事件(不会将其发送到活动窗口)并且现在处于等待的状态e或其他...如果我按其他内容,xmonad不再处于该状态,但它不会“重播”那些被困事件。因此,如果我按下w,然后按下其他一些不是e的密钥,结果只是xmonad退出了侦听子图中密钥的状态。它永远不允许w通过活动窗口......我觉得不方便。

我认为你的选择是:   1)解决具有修饰符的初始键绑定,因此您的多键命令将是Mod4-w e f   2)找到一种方法来破解你描述的延迟逻辑到子图中的动作

我开始使用这样的配置,我在概念上嵌套了在嵌套子图树下很少需要的类似操作,类似于我上面粘贴的内容。但是,该树的根始终具有修饰符,因此它不会窃取我想要转发到活动窗口的按键。我使用Mod3-semicolon作为该树的根,然后有许多未经修改的按键只是字母(它们是动作的助记符)。

对我来说,这似乎是一个更好的解决方案,而不是等待几百毫秒,然后转发事件,除非它们匹配。我觉得我觉得这很烦人,因为它会延迟任何w按键事件......

YMMV,希望它可以帮助某人