Mac 党转 Linux 必看:用 keyd 复刻你最熟悉的快捷键习惯
Linux 下用 keyd 把 Super 键改成 Mac 风格的 Cmd# Linux Wayland 下把 Super 键改成 Mac 风格的 Cmdkeyd 全流程本文记录一次完整的键位改造把Super也称 Cmd/Win 键映射为 macOS 的Command覆盖复制粘贴 / 启动应用 / 关闭窗口等高频操作。最终效果是按住SuperC/V/X/Z/A/Q/W/S/T/M就等于Ctrl...按住SuperTab切换应用点按Super触发活动概览且SuperR完全屏蔽。适用系统Ubuntu 22.04 / GNOME Wayland其他 Wayland 桌面类似X11 方案更简单文末会提。一、背景与方案选型我平时用 Mac 习惯了CmdC/CmdV切到 Linux GNOME 很不顺手。一开始想用xbindkeys xdotool做键位翻译踩了一堆坑方案问题GNOME 自带快捷键 (Settings → Keyboard)改不了应用级快捷键复制/粘贴/撤销/全选xbindkeys xdotoolWayland 下对 Chrome / IDEA 这种 XWayland 应用经常抓不到合成键事件keyd内核层 evdev 重映射✅ 任何 session、任何应用都生效本次最终方案keyd的核心优势在内核输入子系统层就改键不依赖 X11/Wayland 协议所有应用通吃。二、安装 keydsudoaptinstall-ykeydUbuntu 仓库里就有v2.5.0。装完会自动启动 systemd 服务/lib/systemd/system/keyd.service二进制在/usr/bin/keyd.rvaiya。验证systemctl status keyd# 应该看到 active (running)三、配置文件结构主配置/etc/keyd/default.conf。所有要重映射的键都写在这里。我们的目标行为按键点按 Super触发 GNOME 活动概览按住 Super C复制按住 Super V粘贴按住 Super X剪切按住 Super Z撤销按住 Super A全选按住 Super Q退出应用按住 Super W关闭窗口按住 Super S保存按住 Super T打开 gnome-terminal按住 Super M打开 marktext按住 Super Tab应用切换器按住 Super Space输入源切换按住 Super R无动作四、最终配置文件[ids] * [main] # Hold Super: activates [mac] layer (Super behaves as Ctrl) # Tap Super: emits a leftmeta keypress (mutter triggers activities overview) leftmeta overload(mac, leftmeta) rightmeta overload(mac, rightmeta) # Composite layer inheriting Ctrl base (Superletter acts like Ctrlletter) [mac:C] # Launch apps (need the helper script — see section 5) t command(/usr/local/bin/keyd-launch /usr/share/applications/org.gnome.Terminal.desktop) m command(/usr/local/bin/keyd-launch /usr/share/applications/marktext.desktop) # Pass-through Meta combinations tab M-tab space M-space r noop escape M-escape # Letter keys - Ctrl same key c C-c v C-v x C-x z C-z a C-a q C-q w C-w s C-s加载并启用sudosystemctl restart keydsudokeyd.rvaiya reload五、关键语法解读1.overload(layer, tap_action)这是整个方案的灵魂leftmeta overload(mac, leftmeta)含义按住Super 时激活[mac]层在这个层里所有按键都被重新映射点按Super 时执行 tap action也就是发一个leftmeta按键事件给 muttermutter 看到 Super 就触发「活动概览」所以点按 Super 活动概览按住 进[mac]层。注意tap_action必须是合法键名。用meta会报错正确是leftmeta/rightmeta跑keyd.rvaiya list-keys可以看所有合法键名2. 复合层[mac:C][mac:C]冒号:C表示「继承 Ctrl 作为基修饰键」。意思是显式映射的键如c C-c按映射执行没显式映射的字母键比如e、f自动加上 Ctrl 前缀即CtrlE、CtrlF这正是 macOS 的语义Cmd字母在 macOS 里很多就是Ctrl字母的快捷键。3. 修饰键前缀keyd 的修饰键语法用单字母前缀写法含义C-cCtrl CM-tabSuper TabA-f4Alt F4S-insertShift InsertC-S-aCtrl Shift A4.noop—— 让某个键完全失效r noop按住 SuperR 时什么也不发不映射到任何应用行为。5.command()—— 启动外部应用t command(/usr/bin/gnome-terminal)但是有坑keyd 以 root 运行没有用户会话环境Wayland socket、DBus 都是用户私有的直接command(/usr/bin/xxx)启动 GUI 应用会失败。详见下一节。六、桥接脚本让 command() 能启动 GUI 应用keyd作为 systemd 服务以 root 跑root 默认访问不到/run/user/1000/wayland-0—— Wayland 显示 socketjun 私有/run/user/1000/bus—— 用户 DBus/run/user/1000/.mutter-Xwaylandauth.XXX—— Xwayland 鉴权文件所以command(/usr/bin/gnome-terminal)直接调用会立即退出没有 GUI 窗口。解决方案写一个桥接脚本切到 jun 用户身份 注入环境变量用gio launch走 GNOME 应用激活通道。创建/usr/local/bin/keyd-launch#!/bin/bash# keyd 调用 GUI 应用时的桥接脚本# keyd 以 root 跑没有用户会话环境 — 通过这里切到 jun 并加载 Wayland/DBus 环境execsudo-ujunenv\WAYLAND_DISPLAYwayland-0\DBUS_SESSION_BUS_ADDRESSunix:path/run/user/1000/bus\XDG_RUNTIME_DIR/run/user/1000\XDG_SESSION_TYPEwayland\gio launch$加上可执行权限sudochmodx /usr/local/bin/keyd-launch然后在 keyd 配置里这样用t command(/usr/local/bin/keyd-launch /usr/share/applications/org.gnome.Terminal.desktop) m command(/usr/local/bin/keyd-launch /usr/share/applications/marktext.desktop)几个关键点sudo -u junroot 用 sudo 默认免密可以直接切到普通用户WAYLAND_DISPLAYwayland-0对应/run/user/1000/wayland-0DBUS_SESSION_BUS_ADDRESS对应/run/user/1000/busgio launch desktop对DBusActivatabletrue的应用如 gnome-terminal特别稳会走标准的 DBus 激活机制如果应用不是 DBus activatablegio launch也会按 desktop 文件的Exec字段启动注把环境变量硬编码成wayland-0、/run/user/1000在单用户机器上没问题。如果用户 ID 不同需要相应调整。七、本次踩过的所有坑记录一下方便后来人。坑 1行尾#注释导致解析失败c C-c # 复制 ← 这样写会让 keyd 报 invalid key or action c C-c ← 必须把注释挪到独立行keyd 的解析器不支持 inline 注释所有#注释必须独占一行。坑 2合法的 Meta 键名是leftmeta/rightmeta不是metaleftmeta overload(mac, meta) ← ❌ invalid key or action leftmeta overload(mac, leftmeta) ← ✅查合法名keyd.rvaiya list-keys | grep meta坑 3exec()不存在要用command()keyd 命名习惯不同t exec(/usr/bin/xxx) ← ❌ t command(/usr/bin/xxx) ← ✅坑 4复合层语法是[name:base][mac] ← ❌ 在里面用 C-c 会报 invalid [mac:C] ← ✅ 继承 Ctrl 基修饰键:C中的C是修饰键代码之一C Ctrl, M Meta, A Alt, S Shift。坑 5overload的第二参数必须是合法键名不是任意 action是键名overload(mac, meta) ← ❌ meta 不是键名 overload(mac, leftmeta) ← ✅ overload(mac, esc) ← ✅ (capslock 示例)坑 6root 跑 keyd启动 GUI 应用要桥接直接command(/usr/bin/gnome-terminal)不会出错但会立即退出没有窗口。要用第六节的桥接脚本。八、调试与维护查看当前生效配置sudokeyd.rvaiya reload# 热加载修改配置后用journalctl-ukeyd-n20# 看解析日志和错误sudokeyd.rvaiya monitor# 实时打印所有按键事件调试桥接脚本是否正常直接手动跑/usr/local/bin/keyd-launch /usr/share/applications/org.gnome.Terminal.desktop应该立刻弹出 gnome-terminal。改完配置热加载sudonano/etc/keyd/default.confsudokeyd.rvaiya reload不需要注销、不需要重启 daemon。添加更多 Super键 启动应用# 1. 找应用的 desktop 文件ls/usr/share/applications/|grep-i应用名# 2. 在 [mac:C] 段加一行xcommand(/usr/local/bin/keyd-launch /usr/share/applications/xxx.desktop)# 3. 热加载sudokeyd.rvaiya reload临时禁用整套映射sudosystemctl stop keyd恢复sudosystemctl start keyd九、X11 用户怎么办如果你用的是 X11 会话echo $XDG_SESSION_TYPE显示x11方案更简单sudoaptinstall-yxbindkeys xdotool~/.xbindkeysrcxdotool key --clearmodifiers ctrlc Super c xdotool key --clearmodifiers ctrlv Super v xdotool key --clearmodifiers ctrlx Super x xdotool key --clearmodifiers ctrlz Super z xdotool key --clearmodifiers ctrla Super a xdotool key --clearmodifiers ctrlq Super q xdotool key --clearmodifiers ctrlw Super w xdotool key --clearmodifiers ctrls Super s自启动~/.config/autostart/xbindkeys.desktop[Desktop Entry] TypeApplication Namexbindkeys Execxbindkeys X-GNOME-Autostart-enabledtrue缺点xdotool 合成事件偶尔被应用吞掉且对 Wayland/XWayland 混合场景不友好。所以本文主推 keyd。十、参考keyd GitHubkeyd 自带示例macos.conf—— Mac 风格映射参考nav-layer.conf—— 层修饰键用法capslock-escape-with-vim-mode.conf——overload三态用法GNOME Mutter 文档gsettings set org.gnome.mutter overlay-key —— 关闭 mutter 自带的 Super 单键活动概览keyd 接管后通常不需要最后提醒SuperQ会让应用立即退出多数不弹确认框跟 macOS 行为一致。如果不喜欢可以换成noop或映射到C-w只关窗口不退出应用。