interception-tools
interception-tools 是一组用于控制和自定义键盘输入映射行为的实用程序。
Interception-tools 与其他类似工具(xcape, xmodmap)相比,在更低的级别上运行,它使用 libevdev 和 libudev(3)。这使其成为跨 X11、Wayland 和 Linux 控制台 自定义键盘行为的唯一可用选项之一。
安装
有许多插件可用
- 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
配置
这些工具包括命令行工具和 systemd 服务。
在启动打包的 udevmon.service
之前,需要在 /etc/interception/udevmon.yaml
中添加配置。
/etc/interception/udevmon.d/
中找到的配置文件,然后回退到 /etc/interception/udevmon.yaml
。工作原理
Interception-tool 使用 libevdev,根据其 wiki 的说法,它本质上是 /dev/input/eventX
设备上增强版的 read(2)。它位于内核和处理事件的进程之间。最简单的场景看起来像这样
kernel | libevdev | evtest
对于 X.Org 输入模块,堆栈看起来像这样
kernel | libevdev | xf86-input-evdev | X server | X client
对于 Wayland,堆栈看起来像这样
kernel | libevdev | Compositor | Wayland client
换句话说,libevdev
的级别非常低,以至于它不了解 X/Wayland 客户端。
实际示例
Interception-tools 提供了 4 个实用程序
intercept
: 将设备输入事件重定向到 stdout,mux
: 组合输入事件流,udevmon
: 监视输入设备以启动任务,uinput
: 将设备输入事件从 stdin 重定向到虚拟设备。
提高优先级
由于该工具将位于设备输入的最低级别,请通过提高 udevmon
优先级来确保它始终如一地运行
# nice -n -20 udevmon -c udevmon.yaml > udevmon.log 2> udevmon.err &
udevmon
systemd 服务以 Nice=-20
运行。简单重定向
将事件重定向到 stdin 的最简单方法(不执行任何操作)是
$ intercept -g DEVNODE | uinput -d DEVNODE
其中 DEVNODE
是实际设备的路径:例如 /dev/input/by-path/platform-i8042-serio-0-event-kbd
。
嵌入命令
要在按键事件和输入之间实际执行操作,只需在 intercept
和 uinput
之间进行管道传输即可。
例如,安装了 interception-caps2esc 插件
$ intercept -g DEVNODE | caps2esc | uinput -d DEVNODE
如果我们省略 -g
标志,那么设备事件将仅被观察,而不是捕获。
以 YAML 格式提供
这种拦截输入的方式可能很快变得不理想,这就是 udevmon
派上用场的地方。 udevmon 接受 YAML 配置,其中包含要执行的任务列表(默认为 sh 命令)。
如果设备与给定的描述匹配
$ udevmon -c caps2esc.conf.yml
- JOB: intercept -g DEVNODE | caps2esc | uinput -d DEVNODE DEVICE: LINK: /dev/input/by-path/platform-i8042-serio-0-event-kbd
LINK
配置将匹配具有特定名称的设备,但它也接受正则表达式选项。这可以与多个作业规范结合使用以创建默认行为,在每种情况下,只会执行第一个匹配的作业
- 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
组合设备
除了输入模拟之外,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 - JOB: mux -i caps2esc | caps2esc | uinput -c /etc/interception/gaming-keyboard.yaml - JOB: intercept -g DEVNODE | mux -o caps2esc DEVICE: LINK: /dev/input/by-id/my-kbd - JOB: intercept DEVNODE | mux -o caps2esc DEVICE: LINK: /dev/input/by-id/my-mouse
在上面的示例中,当键盘连接时,它会被捕获,并且其输入事件被发送到最初创建的 caps2esc
muxer。来自鼠标的观察到的输入(未捕获)也被发送到同一 muxer。鼠标的按钮生成 EV_KEY
事件,因此 caps2esc
将接受它们。