interception-tools
interception-tools 是一套用于控制和自定义键盘输入映射行为的工具集。对于大多数用户来说,它是一个后端,会配合其插件使用。
与较旧的类似工具(xcape、xmodmap)相比,interception-tools 通过使用 libevdev 和 libudev(3) 在更低的级别上运行。因此,它能够同时在 X11、Wayland 和(尽管未正式记录)Linux console 中工作。
安装
提供许多插件
- interception-caps2esc 用于将
CapsLock键切换为Ctrl/Esc - interception-caps2esc-delay-gitAUR
- interception-caps2esc-nocaps-gitAUR
- interception-dual-function-keys 用于修改按键被按下时的行为。
- interception-hideawayAUR
- interception-k2k-gitAUR
- interception-ralt2hyperAUR
- interception-space2metaAUR
- interception-uswitchAUR
- interception-vimproved-gitAUR
- interception-xswitchAUR
基础知识
工作原理
Interception-tool 利用 libevdev,它可以位于内核和处理事件的进程之间。其结构示意图如下:
kernel > libevdev > console kernel > libevdev > xf86-input-evdev > X server > X client kernel > libevdev > Compositor > Wayland client
libevdev 是低级别的,它不了解 X/Wayland。
更准确地说,输入设备被暴露为 /dev/input/eventN,基本上 X 或 Wayland 会直接读取它们。通过 libevdev,它们可以被轻松地“捕获”——不再被 X/Wayland 读取——然后它会创建一个新的虚拟设备,同样是 /dev/input/eventN。然后 X/Wayland 会读取这个新的设备。
组件
Interception-tools 提供了 4 个可执行文件。其中最重要的两个是 intercept 和 uinput;前者将设备输入事件重定向到 stdout,后者创建一个新的虚拟设备,并将 stdin 的事件重定向到该设备。
然而它们是低级别的,通常您不需要手动运行它们。取而代之的是 udevmon 进行协调;用户编写配置文件,然后 udevmon 会根据这些配置运行 intercept、uinput 和插件。当 udevmon 被终止时,所有底层进程也会被终止。
还有用于复杂情况的 mux,它用于组合输入事件流。(mux 一词来自 multiplexer,即多路复用器。)
原始示例 1:无操作
这实际上什么也没做
$ intercept -g DEVNODE | uinput -d DEVNODE
其中 DEVNODE 是实际设备的路径:例如,对于典型的笔记本电脑键盘,它是 /dev/input/by-path/platform-i8042-serio-0-event-kbd。
这里 intercept 捕获了设备,并将其重定向到 stdout。uinput 创建了一个新的虚拟设备,该设备几乎是 DEVNODE 的副本,并将 stdin 重定向到该设备。新设备具有与原始设备相同的名称和能力。
原始示例 2:使用插件
要实际在按键事件和输入之间执行操作,只需将其通过管道连接到 intercept 和 uinput 之间。
例如,在安装了 interception-caps2esc 插件的情况下
$ intercept -g DEVNODE | caps2esc | uinput -d DEVNODE
如果我们省略 -g 标志,那么设备事件将只会被*观察*,而不会被捕获。
用法
配置通过 /etc/interception/udevmon.d/ 中的 yaml 文件进行。然后用户可以从命令行运行 udevmon,或启动 udevmon.service。
/etc/interception/udevmon.yaml。备注
这仅在用户手动运行 udevmon 时适用。如果它由 systemd 运行,则可以忽略此项。
由于该工具必须表现得接近内核级别,请通过提高 udevmon 的优先级来确保一致的行为。
# nice -n -20 udevmon -c udevmon.yaml > udevmon.log 2> udevmon.err &
udevmon systemd 服务以 Nice=-20 运行。错误的配置可能会导致键盘出现问题,以至于您无法停止 interception-tools。为避免这种情况,您可以通过运行 udevmon 并设置超时来测试:
# timeout 10 udevmon &
这将在 10 秒后终止 udevmon(及其运行的 intercept 和 uinput)。
配置
基础知识
配置文件使用 yaml 格式编写。最简单的例子如下:
- JOB: intercept -g $DEVNODE | <plug-in> | uinput -d $DEVNODE
DEVICE:
LINK: /dev/input/by-path/platform-i8042-serio-0-event-kbd
JOB 行指定了如何运行它。
LINK 配置将匹配具有特定名称的设备,但它也接受正则表达式选项。这可以与多个 job 规范结合使用,以创建默认行为,在每种情况下,只有第一个匹配的 job 会被执行。
- JOB: intercept -g $DEVNODE | caps2esc -m 2 | uinput -d $DEVNODE
DEVICE:
LINK: /dev/input/by-id/usb-SEMITEK_USB-HID_Gaming_Keyboard_SN0000000001-event-kbd
- JOB: intercept -g $DEVNODE | caps2esc | uinput -d $DEVNODE
DEVICE:
EVENTS:
EV_KEY: [[KEY_CAPSLOCK, KEY_ESC]]
LINK: .*-event-kbd
将其保存在例如 /etc/interception/udevmon.d/simple.yaml。然后您可以通过运行 $ udevmon 来激活它。
组合设备
除了输入模拟之外,uinput 工具还用于以 YAML 格式打印设备的描述。
$ uinput -p -d /dev/input/by-id/my-kbd
它本身也可以被反馈给 uinput,例如:
$ uinput -c my-kbd.yaml
它还可以合并设备和 YAML 特征,例如用于组合来自键盘和鼠标的事件。
例如,将 CapsLock+Click 实例设置为 Ctrl+Click。
$ uinput -p -d /dev/input/by-id/my-kbd -d /dev/input/by-id/my-mouse -c my-extra.yaml
处理多个任务
mux 用于将多个管道组合成一个。首先需要创建一个 *muxer*,然后可以在给定管道的输入或输出中使用它。在 YAML 规范文件中,使用 CMD 键来创建 muxer。
- CMD: mux -c caps2esc_mixer
- JOB: mux -i caps2esc_mixer | caps2esc | uinput -c /etc/interception/gaming-keyboard.yaml
- JOB: intercept -g $DEVNODE | mux -o caps2esc_mixer
DEVICE:
LINK: /dev/input/by-id/my-kbd
- JOB: intercept $DEVNODE | mux -o caps2esc_mixer
DEVICE:
LINK: /dev/input/by-id/my-mouse
在上面的示例中,当键盘连接时,它会被捕获,其输入事件被发送到最初创建的 caps2esc muxer。从鼠标观察到的输入(未被捕获)也被发送到同一个 muxer。鼠标的按钮会生成 EV_KEY 事件,因此 caps2esc 会接受它们。