XMonad:有没有办法绑定同时触发的琴键? [英] XMonad: Is there a way to bind a simultaneously triggered keychord?

查看:79
本文介绍了XMonad:有没有办法绑定同时触发的琴键?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有一种方法可以同时按下按键来进行键绑定,例如键 w e f 的键在彼此之间0.05秒内按下时触发命令?

Is there a way to make simultaneous key presses into a keybinding, e.g. for the keys w, e, f, when pressed within 0.05 seconds of each other, to trigger a command?

更具体地说:

  1. 如果在彼此的0.05秒内按下 w e f ,则在最后一个按下时,XMonad应该触发上述命令. XMonad还应该拦截了这三个键,以免将它们不必要地发送到焦点窗口.

  1. If w, e, f are pressed within 0.05 seconds of each other, then upon the pressing of the last one, XMonad should trigger said command. XMonad should also have intercepted the three keys so that they are not superfluously sent to the focused window.

否则(如果至少0.05秒内未按下其中一个),XMonad应当照常将键发送到焦点窗口.

Otherwise (if at least one of them are not pressed within the 0.05 second time period) XMonad should send the keys to the focused window as usual.

我的目标是使用 w e f 将其转义"为类似于vim的正常模式", XMonad.Actions.Submap(子图).

My goal in this is to use w, e, f to "Escape" into a vim-like "Normal Mode", a XMonad.Actions.Submap (submap).

使用失败方法进行更新,以防万一有人看到修复它的方法:

Update with a failed method, in case anyone can see a way to fix it:

我尝试使用子图实现此功能,例如,如果您按 w ,则您将以chord_mode_w结尾,如果从此处按 e 例如,您将以chord_mode_we结尾,如果从那里按 f ,则最终将以normal_mode结尾.该实现非常混乱:我在主要的键盘绑定中包含了以下内容:

I attempted to implement this using submaps, so that, for example, if you pressed w you would end up in chord_mode_w, if you pressed e from there you would end up in chord_mode_we, and if you pressed f from there you would finally end up in normal_mode, for instance. The implementation was very messy: I included, in my main keybindings, something like:

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

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

for detecting w (the rest would be similar), along with (incomplete) submaps such as:

 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,否则中止并键入字符.但是,有两个问题:

A complete implementation would evidently have been very messy, but in theory should have sent me to normal_mode if I pressed "wef" within 0.05 seconds of each other, aborting and typing out the characters otherwise. There were two problems, however:

  1. pasteString(以及XMonad.Util.Paste中的其他粘贴功能)对于正常键入​​而言太慢了

  1. pasteString (as well as the other paste functions in XMonad.Util.Paste) is too slow for normal typing

即使我将中止延迟设置得更高,我也只会在很小的时间内停留在normal_mode中.不知道其背后的原因.

I would end up in normal_mode only a small fraction of the time even if I set the abort delay much higher. Not sure of the reason behind this.

(我中止而不是生成另一个xdotool时使用pasteString的原因是xdotool的输出将重新触发chord_mode_w_keybindingchord_mode_e_keybindingchord_mode_f_keybinding中的一个键绑定,使我无限期地回到和弦模式.)

(The reason I used pasteString when aborting instead of spawning another xdotool was that output of xdotool would re-trigger one of the chord_mode_w_keybinding, chord_mode_e_keybinding, chord_mode_f_keybinding, back in the main keybindings, sending me back to the chord modes indefinitely.)

推荐答案

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

Submap实际上确实做到了几乎 所需的功能(它可以为您提供大部分帮助)...并且我建议您可能想要更改想要的操作,无论如何稍有一点,然后Submaps就可以完美地处理它.

Submap really does do almost what you want (it gets you most of the way there) ... and I will suggest that you may want to change what you are trying to do, ever so slightly, and then Submaps handle it perfectly.

您可以配置Submap来捕获w键事件,并开始等待e,然后等待f.我什至尝试了一下,并确认它有效:

You can configure Submap to capture a w key event, and start waiting for an e which then waits for an f. I even tried this out, and confirmed that it works:

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

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

However, the above is almost certainly not something you'd actually want to do... since it is now impossible to send a w keypress to a window (I had to disable that config before typing this answer, which required sending several w keypress events to the active window)

我现在在玩此游戏时看到的行为是:如果按下w,xmonad会捕获该事件(不会将其发送到活动窗口),并且现在处于等待任一或其他内容...如果我按其他操作,则xmonad不再处于该状态,但不会重播"那些被困事件.因此,如果我按w然后是其他不是e的键,则结果只是xmonad退出了侦听子图中的键的状态.它永远不允许w进入活动窗口...我觉得很不方便.

The behavior I saw just now when playing with this is: if I press w, xmonad traps that event (does not send it to the active window) and is now in a state where it is waiting for either e or something else ... if I press something else, xmonad is no longer in that state, but it does not "replay" those trapped events. So if I press w and then some other key which isn't e, the result is only that xmonad is back out of the state listening for keys in the submap. It does not ever allow a w through to the active window... which I found inconvenient.

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

Your options as I see it are: 1) settle for the initial keybinding having a modifier, so your multi-key command would be Mod4-w e f 2) find a way to hack the delay logic you described into the action in the submap

我开始使用像这样的配置,在该配置中,我在嵌套子图的树下嵌套了一些概念上相似的动作,这些动作与我上面粘贴的类似.但是,该树的根始终带有修饰符,因此它不会窃取要转发到活动窗口的按键.我将Mod3-semicolon用作该树的根,然后有许多未经修改的按键,它们只是字母(它们是操作的助记符).

I started using a config like this, where I nest conceptually similar actions that are infrequently needed under a tree of nested submaps, analogous to what I pasted above. The root of that tree, however, always has a modifier, so it doesn't steal keypresses which I want to forward to the active window. I use Mod3-semicolon as the root of that tree, and then there are many unmodified keypresses which are just letters (they are mnemonics for the actions).

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

To me, this seems like a better solution, rather than waiting for a few hundred milliseconds, and then forwarding the events unless they matched. I feel like I would find that annoying, since it would delay any w keypress event...

YMMV,希望它能对某人有所帮助

YMMV, hope it helps someone

这篇关于XMonad:有没有办法绑定同时触发的琴键?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆