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

Linux 修改键位映射

  •  
  •   phoulx · 2022-08-28 17:44:05 +08:00 · 4998 次点击
    这是一个创建于 848 天前的主题,其中的信息可能已经有所发展或是发生改变。
    折腾了几天, 分享一下 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  
       355 天前
    @auvt mac 上用 karabiner elements
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1338 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 17:26 · PVG 01:26 · LAX 09:26 · JFK 12:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.