Linux 修改键位映射 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
phoulx
V2EX    Linux

Linux 修改键位映射

  •  
  •   phoulx 2022-08-28 17:44:05 +08:00 5920 次点击
    这是一个创建于 1141 天前的主题,其中的信息可能已经有所发展或是发生改变。
    折腾了几天, 分享一下 Linux 下修改键位映射的思路和工具。

    需达到的效果:
    CapsLock 单按为 Esc ,组合按为 Ctrl
    左 Shift 单按切输入法,右 Shift 单按打出左括号
    文本编辑时适配 Emacs 基础快捷键
    按键布局尽量与 macOS 一致

    macOS 键位的好处是 Command 与 Ctrl 分开,使得一些 Emacs 快捷键与系统命令快捷键能够共存(如 Ctrl+A 跳至行首,Command+A 全选等)。

    调研:
    Linux 下的改键软件大致分为两类:
    一类为使用 X11/Xorg 的键盘映射接口,如 xmodmap 、xkeysnail 等;
    另一类为调用 kernel 层的输入接口,如 keyd 、KMonad 等。
    因为我用的桌面是 Gnome Wayland ,所以 X11 下的就无法考虑了。後面两个目前都在积极开发中:keyd 用 C 写的,配置文件类似 TOML ,Linux 专属; KMonad 是 Haskell ,配置文件是类似 Lisp 但惊人的直观,且跨平台。考虑到效率,我选择了 keyd ( https://github.com/rvaiya/keyd )。

    安装过程不表,说一下遇到的体会和小坑。
    keyd 以 layer 为核心概念,每个 layer 就是一段配置,layer 可以继承和切换。这样很容易实现我需要的效果(如:左 Alt 继承 Ctrl 功能,但特定键下可触发自定义)。
    不过要注意的是,目前 git 仓库中的示例配置有部分是错的(应该是近期迭代了 2.0 版但示例未及时更新),修改要点:
    1. 2.0 版舍弃了`leftmeta = alt`的语法,现在必须写成`leftmeta = layer(alt)`
    2. 切换 layer 时如果有参数,要用 swap2 而不是 swap ,具体用法在 man page 有写

    现在仍有部分 Emacs 键位无法实现,如 Ctrl+k (删至行末),因这一功能没有单键对应。如果定义为 Shift+End+Delete 组合键,不仅删除时有延迟,而且会影响 Terminal 中 Ctrl+k 的行为。
    注意到 Gnome Tweak 中有一个启用 Emacs 键位的选项,研究了一下如何实现的,发现是使用了 gtk 的 Api 自定义了一些配置(位于:/usr/share/themes/Emacs/gtk-3.0/gtk-keys.css ),这样我们可以仿照此配置,新建一个 YourKey 文件夹,将 gtk-keys.css 中需要的搬过来,再通过`gsettings set org.gnome.desktop.interface gtk-key-theme YourKey`设为自己想到的效果。
    不过这对 gtk 应用生效,好在我装的非 gtk 应用不多,目前已基本够用。
    第 1 条附言    2022-08-30 01:14:54 +08:00

    总结keyd的优点(听我给你吹

    1. 设计好:layer概念对键盘事件的统括性很强,结合TOML的易读性,配置写起来简洁而有力
    2. 适用广:使用kernel层API(evdev, uinput),不受X11限制,支持Wayland等
    3. 性能佳:纯C编写,执行效率可靠(自用近一周未感到任何延迟)
    4. 花样多:实时调整配置、支持不同键盘分别设置、支持按程序切换键位(Python扩展)…

    因之前调研时发现相关中文信息分散,在此对同类产品报个菜名,以来者~

    其他可尝试的通用(非X11专属)改键工具(感谢@everyx @leighton 补充):

    X11下的老牌工具:

    找到一篇英文总结: https://medium.com/@canadaduane/key-remapping-in-linux-2021-edition-47320999d2aa (额外提及了kbct、Hawck、Interception、houmain/keymapper等)

    还有修改scancode相关方法,参见本页@haoliang @beetlerx 的评论。


    顺便,XKB与Gnome(不清楚其他DE情况)的键盘布局选项直接相关。
    要对系统键盘设置中某种布局(如Dvorak)进行微调的话,可修改/usr/share/X11/xkb/symbols/us文件(其他语言布局同理)。

    20 条回复    2024-01-03 03:01:05 +08:00
    everyx
        1
    everyx  
       2022-08-28 20:19:08 +08:00
    正在用 https://github.com/sezanzeb/input-remapper ,就是不能映射 fn 组合键,请问不知道 keyd 可以吗?
    haoliang
        2
    haoliang  
       2022-08-28 20:28:09 +08:00
    我依稀记得有人是在 udev 层面做的改映射,不需要借助额外程序。
    哦,找到个参考: https://wiki.archlinux.org/title/map_scancodes_to_keycodes
    beetlerx
        3
    beetlerx  
       2022-08-28 20:28:48 +08:00
    我用的是这个文章里的修改 scancode 方法
    https://harttle.land/2019/08/08/linux-keymap-on-macbook.html
    auvt
        4
    auvt  
       2022-08-28 21:03:06 +08:00 via iPhone
    感谢 lz 分享,在 mac 上实现了全局 vim 方向按键,想跟 mac 快捷键一起搬到 linux 上,结果可耻地失败了无数次,就为了码个字,后来放弃了……
    phoulx
        5
    phoulx  
    OP
       2022-08-28 21:07:42 +08:00 via iPhone
    @everyx 应该也不行,试了下 Filco 的 fn ,检测不到
    everyx
        6
    everyx  
       2022-08-28 21:23:24 +08:00
    @phoulx 谢谢回复,看来这种应该是要那类支持修改固件的键盘才行了
    jinweijie
        7
    jinweijie  
       2022-08-29 08:11:52 +08:00
    用 AutoKey 可以吗?
    leighton
        8
    leighton  
       2022-08-29 09:30:50 +08:00
    phoulx
        9
    phoulx  
    OP
       2022-08-29 10:07:02 +08:00 via iPhone
    @jinweijie AutoKey 也是 X11 专属,而且 GUI 觉得没必要
    TravisMtg
        10
    TravisMtg  
       2022-08-29 13:38:50 +08:00 via iPhone
    非常好推荐!这段时间一直在纠结 spacefn 咋弄,keyd 能完美整出 spacefn 的方案
    xxiaowangwang
        11
    xxiaowangwang  
       2022-08-29 15:45:18 +08:00
    setxkbmap -option "caps:swapescape" 用 XWayland 的话,这个不可以吗?
    phoulx
        12
    phoulx  
    OP
       2022-08-30 00:22:52 +08:00
    @xxiaowangwang 没试过诶,感觉 setxkbmap 预设项太多了,对于复杂需求用起来会混乱…
    phoulx
        13
    phoulx  
    OP
       2022-08-30 01:30:43 +08:00
    贴一个我目前的 keyd 配置(适用 v2.4.2 ): https://paste.rs/nFR
    kaiger
        14
    kaiger  
       2022-09-01 09:47:39 +08:00
    很好用,多谢:)
    kaiger
        15
    kaiger  
       2022-09-01 10:56:52 +08:00
    OP ,有个问题
    为特定的 app 改键好像不成功,例如配置文件:

    ~/.config/keyd/app.conf
    ```
    [google-chrome]
    # Remaps the escape key to capslock
    esc = capslock
    ```
    是我的语法有问题吗?
    975779964
        16
    975779964  
       2022-09-08 21:50:59 +08:00
    请问这个支持 远程 xrdp 或者 nomachine 按键映射么?
    xiaket
        17
    xiaket  
       2022-12-18 17:59:29 +08:00
    xremap 挺好用的, 配置文件思路很清晰也很好读. 不推荐 xkeysnail, 依赖多, 出问题不好排查. ref: https://blog.xiaket.org/2022/xremap.html
    jqtmviyu
        18
    jqtmviyu  
       2023-05-25 11:12:37 +08:00
    感谢, 之前 用 xmodmap, 非常麻烦

    你的配置链接失效了.
    我到 issues 区抄了下, 暂时还没搞清楚怎么实现 mac 上的向前 /后删除一个单词, 向后退格.
    幸好大部分情况都是在 shell 和 vim 中编辑, 它们有泛用的快捷键

    ```
    [ids]

    *

    [main]
    capslock = overload(capslock_layer, esc)

    [capslock_layer]
    esc = capslock

    h = left
    j = down
    k = up
    l = right

    u = pageup
    p = pagedown
    i = home
    o = end

    m = backspace
    ```
    yczjing
        19
    yczjing  
       2023-07-04 20:53:01 +08:00
    @jqtmviyu
    ```
    [capslock_layer:C-S-A-M]
    ```
    这样可以把 caps 默认配置为 hyper
    txl263
        20
    txl263  
       2024-01-03 03:01:05 +08:00
    @auvt mac 上用 karabiner elements
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3304 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 00:18 PVG 08:18 LAX 17:18 JFK 20:18
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86