This page looks best with JavaScript enabled

Linux 下使用 xkb 将 CapsLock 键映射为 Ctrl 键, 同时将 Ctrl 键映射为 Hyper 键

 ·  ☕ 2 min read

“将 CapsLock 键映射为 Ctrl 键, 同时将 Ctrl 键映射为 Hyper 键” 的最简单的做法是给 XkbOptions 选项设置 ctrl:hyper_capscontrol!
你可以用

1
localectl list-x11-keymap-options

来查看XkbOptions 所有的可选项
然后在这几个环境变量中查看对应的 XkbOption 的源码:

1
2
env | grep XKB
XKB_CONFIG_ROOT=/nix/store/5a1nxv69xw6sqhs0b8273y2r09k08w03-xkeyboard-config-2.40/etc/X11/xkb

比如 ctrl:hyper_capscontrol:

// Make the left Ctrl key a left Hyper,
// and the CapsLock key a left Control.
partial modifier_keys
xkb_symbols "hyper_capscontrol" {
    replace key <CAPS> { [ Control_L ], type[group1] = "ONE_LEVEL" };
    replace key <LCTL> { [ Hyper_L ] };
    modifier_map Control { <CAPS> };
    modifier_map Mod4    { <LCTL> };
};

或者,你只想将 Caps 和 Ctrl 调换一下位置:

// Swap the functions of the CapsLock key and the left Ctrl key.
partial modifier_keys
xkb_symbols "swapcaps" {
    replace key <CAPS> { [ Control_L ], type[group1] = "ONE_LEVEL" };
    replace key <LCTL> { [ Caps_Lock ] };
    modifier_map Control { <CAPS> };
    modifier_map Lock    { <LCTL> };
};

参见:

  1. https://wiki.archlinux.org/title/Xorg/Keyboard_configuration
  2. https://www.x.org/releases/X11R7.5/doc/input/XKB-Config.html

本来我想在 Wayland 下自定义一个 layout 呢,但是当我执行 setxkbmap -verbose 10 -layout us-custom 之后,报 Error loading new keyboard description.
无奈,然后我只能自己重写一个 XkbOption, 用我自己的按键设置办法覆盖掉原有的 symbols/ctrl 文件,并且覆盖调原来的 nocaps 选项:
这样在 Wayland 和 X11 下就都能工作了。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    xserver = {
      enable = true;
      xkb = {
        model = "pc104";
        layout = "us";
        options = "ctrl:nocaps";
        extraLayouts = {
          ctrl = {
            description = "Caps as Ctrl, Ctrl as Hyper as Mod3";
            languages = [ "eng" ];
            symbolsFile = pkgs.writeText "ctrl" ''
              // Eliminate CapsLock, making it another Ctrl.
              partial modifier_keys
              xkb_symbols "nocaps" {
                  replace key <CAPS> { [ Control_L ], type[group1] = "ONE_LEVEL" };
                  modifier_map Control { <CAPS> };


                  modifier_map Mod4 { Super_L, Super_R };

                  key <SUPR> {    [ NoSymbol, Super_L ]   };
                  modifier_map Mod4   { <SUPR> };

                  replace key <LCTL> { [ Hyper_L ] };
                  modifier_map Mod3    { <LCTL> };

                  
                  
                  key <HYPR> {    [ NoSymbol, Hyper_L ]   };
                  modifier_map Mod3   { <HYPR> };
              };
            '';
          };
        };
      };

…… 到了 Wayland 下发现,Emacs Pgtk 并不会识别 Hyper_L 键,所以我又回到了 X11 了,因为我实在是离不开 Hyper_L 键。

除了 xkb , 还可以考虑用 keyd 来完成按键映射。 keyd 的配置,看起来挺简单的: https://github.com/rvaiya/keyd

Share on

EXEC
WRITTEN BY
EXEC
Eval EXEC