Xorg 中有 KeyHold 事件吗?

Xorg 中有 KeyHold 事件吗?

我有一台新的 Macbook Pro,我在上面安装了 Arch Linux。我想要做的一件事是使用媒体键搜索曲目(在 mpd 中)并转到下一个或上一个曲目。这在带有 iTunes 的 OSX 上是可能的,所以我认为这并不是根本不可能的。使用xev仅显示按键按下和按键释放事件。拿着钥匙似乎可以快速循环完成这两个事件。

所以我想要做的是:

  • 按下 XF86AudioNext 键时转到下一个 mpd 曲目;或者
  • 按住 XF86AudioNext 键时查找当前 mpd 曲目

当然,XF86AudioPrev 键也是如此(但方向相反)。

看来这只能通过一些高级脚本来实现。希望你们中的一位能够为我指出正确的方向。

编辑:有趣的是,showkey按住某个键时不会在按下和释放之间循环。相反,它只显示按住该键期间发生的一系列按下事件,以及最终松开该键时的最终释放事件。

xset我刚刚注意到的另一件有趣的事情是,当使用then禁用自动重复时,xev无论按住按键多长时间,都只会显示单个按键事件,并且在松开按键时显示单个按键释放事件。另一方面showkey的输出没有改变。它显示了一系列按键事件和释放时的最终按键释放。

可能有一种方法可以使用它来编写我想做的事情的脚本,但sxhkd我正在使用的热键工具似乎遵循这种xev方式。亦是如此Xbindkeys

答案1

不,没有 KeyHold 事件,只有 KeyPress 和 KeyRelease。 KeyPress 在按下按键时发送,并在一定时间后再次发送。时间可以配置为xset r(有两个时间:第一次重复的时间和后续重复的时间)。当按键实际释放时,会发送 KeyRelease 事件(按住按键时不会发送)。

如果应用程序希望对按住的键做出反应,则需要记录初始按键,然后在设定的时间后或在新的 KeyPress 事件后做出反应,假设它在此期间没有收到 KeyRelease。在 Unix GUI 世界中,对按住的键做出反应是非常不寻常的,因此存在一个不这样做的应用程序的自我延续循环,并且编程框架也没有提供一种简单的方法来做到这一点。

XKB允许将某些按键配置为不可重复;这些按键只会生成初始的 KeyPress 和最终的 KeyRelease。我不知道这是在配置中的哪里完成的。对于这些按键,只有 KeyPress+超时策略有效,而第二个 KeyPress 策略无效。

xbindkeys 和 sxhkd 都无法让这变得简单。虽然它们允许将操作绑定到按键释放事件,但它们并不容易将按键按下和按键释放关联起来,因此很难对逻辑进行编程“在按键按下 X 毫秒后执行此操作,但前提是按键尚未释放”+“在按键释放时执行此操作,但前提是尚未触发保持事件”。我不知道有任何其他类似的框架可以让这变得简单。

答案2

虽然 X11 中没有简单的解决方案,但可以从具有“keyhold”事件的内核读取设备输出。 *更多信息来自 kernel.org*

这是 /dev/input/event# 的示例输出(# 因设备而异)

Event: time 1677080541.072921, type 4 (EV_MSC), code 4 (MSC_SCAN), value 9d
Event: time 1677080541.072921, type 1 (EV_KEY), code 97 (KEY_RIGHTCTRL), value 1
Event: time 1677080541.072921, -------------- SYN_REPORT ------------
Event: time 1677080541.319094, type 4 (EV_MSC), code 4 (MSC_SCAN), value 9d
Event: time 1677080541.319094, type 1 (EV_KEY), code 97 (KEY_RIGHTCTRL), value 2
Event: time 1677080541.319094, -------------- SYN_REPORT ------------
Event: time 1677080541.348759, type 4 (EV_MSC), code 4 (MSC_SCAN), value 9d
Event: time 1677080541.348759, type 1 (EV_KEY), code 97 (KEY_RIGHTCTRL), value 2
Event: time 1677080541.348759, -------------- SYN_REPORT ------------
Event: time 1677080541.379604, type 4 (EV_MSC), code 4 (MSC_SCAN), value 9d
Event: time 1677080541.379604, type 1 (EV_KEY), code 97 (KEY_RIGHTCTRL), value 0

输出从 1(按键按下)、2(按键保持)然后 0(按键释放)

通过监视 /dev/input/event# 的输出,我制作的一个简单脚本可以运行命令来模拟搜索和下一个行为(使用“playerctl 位置 5+”和“playerctl next”)。这里是github分支

相关内容