rvaiya/keyd
GitHub: rvaiya/keyd
keyd 是一个用 C 语言编写的 Linux 系统级按键重映射守护进程,通过内核级输入原语实现低延迟的高级键盘定制功能。
Stars: 5567 | Forks: 254
# 初衷
[](https://repology.org/project/keyd/versions)
Linux 缺乏优秀的按键重映射解决方案。为了达到理想的效果,通常需要组合使用多种工具(例如 xcape、xmodmap),而最终的结果往往依赖于特定的环境(X11)。keyd 试图通过提供一个灵活的系统级守护进程来解决这一问题,该守护进程利用内核级的输入原语(evdev、uinput)来重映射按键。
# 关于 v2 的说明
自首次发布以来,配置格式经历了多次迭代。对于从 v1 迁移配置的用户,建议重新阅读 [man page](https://raw.githubusercontent.com/rvaiya/keyd/refs/heads/master/docs/keyd.scdoc) (`man keyd`)。
另请参阅:[更新日志](docs/CHANGELOG.md)。
# 目标
- 速度 (使用 C 语言编写的手动优化输入循环,耗时 <<1ms)
- 简洁性 (一种直观的[配置格式](#sample-config))
- 一致性 (默认情况下[与各层良好配合](https://github.com/rvaiya/keyd/blob/6dc2d5c4ea76802fd192b143bdd53b1787fd6deb/docs/keyd.scdoc#L128)的修饰键)
- 模块化 (通过使用 [IPC](https://github.com/rvaiya/keyd/blob/90973686723522c2e44d8e90bb3508a6da625a20/docs/keyd.scdoc#L391) 机制实现可扩展的 UNIX 风格核心)
# 功能
keyd 拥有多项独特的功能,其中许多功能通常只能在像 [QMK](https://github.com/qmk/qmk_firmware) 这样的自定义键盘固件中找到,还有一些则是 keyd 独有的。
一些比较有趣的功能包括:
- Layers(支持[混合修饰键](https://github.com/rvaiya/keyd/blob/6dc2d5c4ea76802fd192b143bdd53b1787fd6deb/docs/keyd.scdoc#L128))。
- 按键重载(在点按/长按时表现出不同的行为)。
- 针对特定键盘的配置。
- 瞬时重映射(无需再频繁刷写:))。
- 促进脚本编写且与显示服务器无关的应用程序重映射的客户端-服务器模型。(目前内置了对 X、sway 和 gnome (wayland) 的支持)。
- 系统级配置(可在 VT 中运行)。
- 对修饰键重载的一流支持。
- 支持 Unicode。
### keyd 适合以下人群:
- 希望尝试自定义 [layers](https://docs.qmk.fm/feature_layers)(即自定义 shift 键)和 oneshot 修饰键的人。
- 希望在同一台机器上使用具有不同布局的多个键盘的人。
- 希望能够重映射 `C-1` 而不破坏修饰键语义的人。
- 希望拥有易于理解的键盘配置格式的人。
- 喜欢遵循 Unix 哲学的微型守护进程的人。
- 希望将 control 和 escape 键放在符合天意位置的人。
- 希望能够切换到 VT 调试问题而不破坏其键盘映射的人。
### keyd 不适合:
- 用于编写单个按键按下/抬起事件的工具。
# 依赖
- 你最喜欢的 C 编译器
- Linux 内核头文件(大多数系统已自带)
## 可选
- python (用于特定应用程序的重映射)
- python-xlib (仅用于支持 X)
- dbus-python (仅用于支持 KDE)
# 安装
*注意:* master 分支充当开发分支,在版本发布之间可能会偶尔出现不稳定情况。发布版本均已[打标](https://github.com/rvaiya/keyd/tags),应被视为稳定版本。
## 从源码安装
```
git clone https://github.com/rvaiya/keyd
cd keyd
make && sudo make install
sudo systemctl enable --now keyd
```
# 快速入门
1. 安装并启动 keyd(例如 `sudo systemctl enable keyd --now`)
2. 将以下内容放入 `/etc/keyd/default.conf`:
```
[ids]
*
[main]
# 按下时将 capslock 映射为 escape,按住时映射为 control。
capslock = overload(control, esc)
# 将 escape 键重映射为 capslock
esc = capslock
```
可以通过使用 `keyd monitor` 命令来获取按键名称。请注意,在 keyd 运行时,此命令的输出将对应于 keyd 的输出。要查看原始输入事件,需先停止 keyd,然后再运行该命令。有关更多详细信息,请参阅 man page。
3. 运行 `sudo keyd reload` 以重新加载配置集。
4. 有关更全面的说明,请参阅 man page (`man keyd`)。
配置错误将出现在日志输出中,可以使用你系统的服务管理器以常规方式访问(例如 `sudo journalctl -eu keyd`)。
*注意*:糟糕的配置文件可能会导致你的机器无法使用。如果你发现自己处于这种境地,特殊的按键序列 `backspace+escape+enter` 应该会强制终止 keyd。
某些鼠标(例如 Logitech MX Master)能够发出按键信号,因此会匹配通配符 ID。你可能需要将这些设备明确加入黑名单。
## 特定应用程序重映射(实验性)
- 将自己添加到 keyd 组:
`usermod -aG keyd `
- 填充 `~/.config/keyd/app.conf`:
例如
```
[alacritty]
alt.] = macro(C-g n)
alt.[ = macro(C-g p)
[chromium]
alt.[ = C-S-tab
alt.] = macro(C-tab)
```
- 运行:
`keyd-application-mapper`
你可能需要将 `keyd-application-mapper -d` 放在显示服务器初始化逻辑中的某个位置(例如 ~/.xinitrc),除非你运行的是 Gnome。
有关更多详细信息,请参阅 man page。
## SBC 支持
得益于 Giorgi Chavchanidze 的贡献,添加了通过 usb-gadget 对单板计算机 (SBC) 的实验性支持。
详情请参阅 [usb-gadget.md](src/vkbd/usb-gadget.md)。
## 软件包
某些发行版存在第三方软件包。如果你希望将你的软件包添加到列表中,请提交 PR。这些软件包由社区成员热心维护,我们不对其承担个人责任。
### Alpine Linux
[keyd](https://pkgs.alpinelinux.org/packages?name=keyd) 软件包由 [@jirutka](https://github.com/jirutka) 维护。
### Arch
[Arch Linux](https://archlinux.org/packages/extra/x86_64/keyd/) 软件包由 Arch 打包者维护。
### Debian
在 Debian 13 ("trixie") 及更高版本中提供有 keyd 软件包。要安装:
```
sudo apt install keyd
```
### Fedora
[COPR](https://copr.fedorainfracloud.org/coprs/alternateved/keyd/) 软件包由 [@alternateved](https://github.com/alternateved) 维护。
### Gentoo
[GURU](https://gitweb.gentoo.org/repo/proj/guru.git/tree/app-misc/keyd) 软件包由 [jack@pngu.org](mailto:jack@pngu.org) 维护。
### openSUSE
[opensuse](https://software.opensuse.org//download.html?project=hardware&package=keyd) 软件包由 [@bubbleguuum](https://github.com/bubbleguuum) 维护。
使用 `sudo zypper in keyd` 轻松安装。
### Ubuntu
在 Ubuntu 25.04 ("plucky") 及更高版本中提供有 keyd 软件包。要安装:
```
sudo apt install keyd
```
此外,在 [`ppa:keyd-team/ppa`
存档](https://launchpad.net/~keyd-team/+archive/ubuntu/ppa) 中可以找到已向各 Ubuntu 版本反向移植的最新 Debian 软件包。
### Void Linux
[xbps](https://github.com/void-linux/void-packages/tree/master/srcpkgs/keyd) 软件包由 [@Barbaross](https://gitlab.com/Barbaross) 维护。
使用 `sudo xbps-install -Su keyd` 轻松安装。
# 示例 1
```
[ids]
*
[main]
leftshift = oneshot(shift)
capslock = overload(symbols, esc)
[symbols]
d = ~
f = /
...
```
# 示例 2
此配置覆盖了 macOS 用户可能更熟悉的特定 alt 组合,同时保持其余部分不变。
```
[ids]
*
[alt]
x = C-x
c = C-c
v = C-v
a = C-a
f = C-f
r = C-r
z = C-z
```
# 推荐配置
许多用户可能对充分利用 keyd 不感兴趣。对于寻求简单生活品质改善的用户,我推荐以下配置:
```
[ids]
*
[main]
shift = oneshot(shift)
meta = oneshot(meta)
control = oneshot(control)
leftalt = oneshot(alt)
rightalt = oneshot(altgr)
capslock = overload(control, esc)
insert = S-insert
```
此配置重载了 capslock 键,使其兼具 escape(点按时)和 control(长按时)的功能,并将所有修饰键重映射为 'oneshot' 键。因此,要输入字母 A,你现在只需点按 shift 然后按 a 即可,而无需长按它。最后,它将 insert 重映射为 S-insert(在 X11 中粘贴)。
# 常见问题
## 为什么启用 keyd 后我的触控板会干扰输入?
libinput 是大多数 wayland 和 X11 环境使用的高级输入组件,它包含一项名为“打字时禁用”的功能,会在打字时禁用触控板。
为了实现这一点,它需要区分内置键盘和外接键盘,这是通过为特定硬件硬编码规则('quirks')来实现的。由于 keyd 创建了一个虚拟设备,接管了外接和内置键盘,你需要指示 libinput 将 keyd 虚拟设备视为内置设备。
这可以通过将以下内容添加到 `/etc/libinput/local-overrides.quirks`(可能需要创建此文件)来实现:
```
[Serial Keyboards]
MatchUdevType=keyboard
MatchName=keyd*keyboard
AttrKeyboardIntegration=internal
```
感谢 @mark-herbert42 和 @canadaduane 提供的原始解决方案。
## 那 xmodmap/setxkbmap/* 呢?
xmodmap 及其相关工具是显示服务器级别的工具,功能有限。keyd 是一个系统级解决方案,实现了诸如分层和 [oneshot](https://docs.qmk.fm/#/one_shot_keys) 修饰键等高级功能。虽然某些 X 工具提供了类似的功能,但我尚未发现有比 keyd 更灵活的工具。
## 那 [kmonad](https://github.com/kmonad/kmonad) 呢?
keyd 是几年前编写的,旨在让我能够在我日益增多的键盘收藏上轻松尝试不同的布局。当时 kmonad 尚未出现,而像 [QMK](https://github.com/qmk/qmk_firmware)(keyd 的灵感来源)这样的自定义键盘固件是获得类似功能的唯一途径。我是在发布 keyd 之后才了解到 kmonad 的。虽然 kmonad 是一个有着相似目标的优秀项目,但它采用了不同的方法并有着不同的设计哲学。
值得注意的是,keyd 完全使用 C 语言编写,注重性能和简洁性,可能永远不会像 kmonad(可通过 Haskell 扩展)那样具有高度的可配置性。话虽如此,(在作者看来)它用不到 2000 行 C 代码提供了最有价值的功能,同时提供了一种简单的、与语言无关的配置格式。
## 为什么 keyd 不实现功能 X?
如果你觉得缺少了什么或发现了 bug,欢迎在 github 上提交 issue。keyd 拥有极简(但合理)的设计哲学,有意省略了某些功能(例如以 root 身份执行任意可执行文件)。在像 QMK 这样的自定义键盘固件中已存在的功能是很好的备选功能。
# 贡献
请参阅 [CONTRIBUTING](CONTRIBUTING.md)。
IRC 频道:oftc 上的 #keyd
标签:evdev, uinput, 客户端加密, 系统工具, 逆向工具, 键盘映射