跳转至内容

Xorg/键盘配置

来自 ArchWiki
(从 AltGr 重定向而来)

本文档描述了 Xorg 键盘配置的基础知识。关于高级主题,如键盘布局修改或附加按键映射,请分别参阅 X 键盘扩展额外的键盘按键

Xorg 服务器使用 X 键盘扩展 (XKB) 来定义键盘布局。可选地,可以使用 xmodmap 直接访问内部按键映射表,但这不推荐用于复杂任务。此外,systemdlocalectl 可用于为 Xorg 服务器和虚拟控制台定义键盘布局。

注意 XKB 选项可能会被某些桌面环境(如 GNOMEPlasma)提供的工具覆盖。

查看键盘设置

您可以使用以下命令查看实际的 XKB 设置

$ setxkbmap -print -verbose 10
Setting verbose level to 10
locale is C
Applied rules from evdev:
model:      evdev
layout:     us
options:    terminate:ctrl_alt_bksp
Trying to build keymap using the following components:
keycodes:   evdev+aliases(qwerty)
types:      complete
compat:     complete
symbols:    pc+us+inet(evdev)+terminate(ctrl_alt_bksp)
geometry:   pc(pc104)
xkb_keymap {
        xkb_keycodes  { include "evdev+aliases(qwerty)" };
        xkb_types     { include "complete"      };
        xkb_compat    { include "complete"      };
        xkb_symbols   { include "pc+us+inet(evdev)+terminate(ctrl_alt_bksp)"    };
        xkb_geometry  { include "pc(pc104)"     };
};

第三方工具

有一些“非官方”工具允许打印有关当前使用的键盘布局的特定信息。

$ xkb-switch
us
$ xkblayout-state print "%s"
de

设置键盘布局

Xorg 中的键盘布局可以通过多种方式设置。以下是对所用选项的解释

  • XkbModel 选择键盘型号。这仅对您的键盘可能具有的某些附加按键有影响。安全的后备选项是 pc104 (ANSI) 或 pc105 (ISO)。但例如笔记本电脑通常有一些附加按键,有时您只需设置正确的型号即可使其工作。
  • XkbLayout 选择键盘布局。可以指定多个布局,用逗号分隔,例如,如果您想在布局之间快速切换。
  • XkbVariant 选择 XkbLayout 可用的特定布局变体。例如,默认的 sk (斯洛伐克语) 变体是 qwertz,但您可以手动指定 qwerty 等。
  • XkbOptions 包含一些附加选项(用逗号分隔)。用于指定布局切换、通知 LED、组合键模式等。有关示例,请参阅 #常用的 XKB 选项 部分。
注意 您必须指定与指定的布局数量相同的变体数量。如果您想要默认变体,请将空字符串指定为变体(逗号必须保留)。例如,要将默认的 us 布局作为主布局,将 us 布局的 dvorak 变体作为次要布局,请将 us,us 指定为 XkbLayout,将 ,dvorak 指定为 XkbVariant

布局名称通常是 2 字母国家代码。要查看键盘型号、布局、变体和选项的完整列表,以及简短说明,请打开 /usr/share/X11/xkb/rules/base.lst。或者,您可以使用以下命令之一查看不带说明的列表

  • localectl list-x11-keymap-models
  • localectl list-x11-keymap-layouts
  • localectl list-x11-keymap-variants [layout]
  • localectl list-x11-keymap-options

以下子章节中的示例将具有相同的效果,它们将设置 pc104 型号,cz 作为主布局,us 作为次要布局,us 布局的 dvorak 变体,以及 Super+Space 组合键在布局之间切换。有关更详细的信息,请参阅 xkeyboard-config(7)

注意 Fcitx/IBus 用户可能会发现这些方法不起作用,或者只起作用一段时间,因为它们会尝试控制键盘布局。Fcitx 用户需要将第一个输入法设置为 Keyboard - layout。请参阅 Fcitx#输入法配置。IBus 用户在使用 X 配置文件时需要在“首选项”->“高级”中启用“使用系统键盘布局”选项,或者在使用 setxkbmap 时手动指定布局。

使用 X 配置文件

注意 xorg.conf 在启动时由 X 服务器解析。要应用更改,请重启 X。

X 配置文件语法在 Xorg#配置 中进行了说明。此方法创建系统范围的配置,该配置在重新启动后仍然存在。

这是一个例子

/etc/X11/xorg.conf.d/00-keyboard.conf
Section "InputClass"
        Identifier "system-keyboard"
        MatchIsKeyboard "on"
        Option "XkbLayout" "cz,us"
        Option "XkbModel" "pc104"
        Option "XkbVariant" ",dvorak"
        Option "XkbOptions" "grp:win_space_toggle"
EndSection

使用 localectl

为了方便起见,可以使用 localectl 工具代替手动编辑 X 配置文件。它会将配置保存在 /etc/X11/xorg.conf.d/00-keyboard.conf 中,此文件不应手动编辑,因为 localectl 在下次启动时将覆盖更改。

用法如下

# localectl [--no-convert] set-x11-keymap layout [model [variant [options]]]

要设置 型号变体选项,所有前面的字段都需要指定,但可以通过传递空字符串 "" 来跳过前面的字段。除非传递了 --no-convert 选项,否则指定的按键映射也会转换为最接近的控制台按键映射,并应用于 vconsole.conf 中的 控制台配置。有关更多信息,请参阅 localectl(1)

创建与上面类似的 /etc/X11/xorg.conf.d/00-keyboard.conf 文件

# localectl --no-convert set-x11-keymap cz,us pc104 ,dvorak grp:win_space_toggle
提示 localectl 还会使用变量 XKBLAYOUTXKBMODELXKBVARIANTXKBOPTIONS 将键盘配置写入 /etc/vconsole.conf[1] 但 Xorg 服务器不会从该文件中读取它们。

使用 setxkbmap

本文章或章节需要扩充。

原因: Udev 也起作用(例如在插入键盘时),会撤销 setxkbmap 所做的更改(在 Talk:Xorg/Keyboard configuration#插入 USB 键盘时保持布局 中讨论)。

setxkbmap 仅为当前 X 会话设置键盘布局,但可以在 xinitrcxprofile 中使其持久化。这会覆盖按照 #使用 X 配置文件 指定的系统范围配置。

用法如下(请参阅 setxkbmap(1)

$ setxkbmap [-model xkb_model] [-layout xkb_layout] [-variant xkb_variant] [-option xkb_options]
注意 setxkbmap 将命令行中指定的选项添加到之前设置的选项(已保存在根窗口属性中)。如果您想替换所有先前指定的选项,请先使用 -option 标志并带一个空参数。

仅更改布局(-layout 是默认标志)

$ setxkbmap xkb_layout

进行多项自定义

$ setxkbmap -model pc104 -layout cz,us -variant ,dvorak -option grp:win_space_toggle

常用的 XKB 选项

在键盘布局之间切换

为了能够轻松地切换键盘布局,首先指定您想在它们之间切换的多个布局(第一个是默认的)。然后指定一个按键(或按键组合),用于切换。例如,要使用 CapsLock 键在 US 和 Swedish 布局之间切换,请将 us,se 作为 XkbLayout 的参数,将 grp:caps_toggle 作为 XkbOptions 的参数。XkbLayout 的数量应与 XkbVariant 的数量相匹配 — 如果您只想在不同变体之间切换,请相应地复制布局(例如 de,de)。

可在 xkeyboard-config(7) § 布局 中找到可用布局(和变体)的列表。用于布局切换的按键组合列在 xkeyboard-config(7) § 切换到另一个布局 中。

请注意,grp:alts_toggle 选项是 不可靠的 并且不太可能得到修复;请优先使用其他组合。

使用 Alt+Shift 切换语言

要将 Alt+Shift 设置为布局快捷方式,请在 XkbOptions 中使用 grp:alt_shift_toggle

但是,XKB 有一个 已知问题,会导致 Alt+Shift+any_key 类型的其他快捷方式失效。此外,XKB 默认可能会将右 Alt 设置为某些键盘布局的 AltGr,导致 RAlt+RShift 无法用于布局切换。

作为解决方法,可以使用 sxhkd 通过将以下内容添加到 sxhkdrc 来切换布局

Shift_L + Alt_L
    setxkbmap -query | grep -q 'fr' && setxkbmap us || setxkbmap fr,us
Shift_R + Alt_R
    setxkbmap -query | grep -q 'fr' && setxkbmap us || setxkbmap fr,us

请注意,出于某种原因,必须先按 Alt 再按 Shift 才能被 sxhkd 检测到。

使用 Ctrl+Alt+Backspace 终止 Xorg

默认情况下,Ctrl+Alt+Backspace 组合键是禁用的。您可以传递 terminate:ctrl_alt_bkspXkbOptions 来启用它。也可以通过在 xmodmap 中将一个按键绑定到 Terminate_Server 来实现(这会撤销任何现有的 XkbOptions 设置)。要使任一方法生效,还需要将 ServerFlags 中的 DontZap 设置为“off”:自 2004 年起 [2],这是默认设置。

将 Caps Lock 与 Left Control 键互换

要将 Caps Lock 与 Left Control 键互换,请将 ctrl:swapcaps 添加到 XkbOptions。运行以下命令以查看类似的选项及其说明

$ grep -E "(ctrl|caps):" /usr/share/X11/xkb/rules/base.lst

启用鼠标键

鼠标键,不要与鼠标按键混淆,默认禁用,必须通过将 keypad:pointerkeys 传递给 XkbOptions 来手动启用。这将使 Shift+NumLock 快捷方式切换鼠标键。

有关高级配置,请参见 X 键盘扩展#鼠标控制

配置 AltGr

AltGr(Alternate Graphic)键可用于访问键盘上的附加字符和符号。它作为一个修饰键,类似于 Shift,但提供了对第三级按键映射的访问。请注意,映射级别如下工作

  • 第一级:按键的默认层(无修饰符)。
  • 第二级:通过按下 Shift 键访问,提供次要字符(例如,大写)或符号(例如,@ 符号)。
  • 第三级:通过按下 AltGr 键访问,允许访问在第一级和第二级不可用的附加字符或符号。

第二级字符通常印在键盘按键上,并且易于查找。另一方面,要检查附加级别的字符,可以使用 xmodmap -pk 或查看 /usr/share/X11/xkb/symbols 中的键盘映射。

配置组合键

虽然传统键盘上通常没有,但可以配置一个 组合键 到一个已有的按键上。

Compose 键开始一个按键序列,该序列涉及(通常是两个)额外的按键。通常用于输入键盘未设计的语言中的字符,或用于 AltGr 修饰符未涵盖的其他不太常用的字符。例如,按下 Compose ' e 会产生 é,或 Compose - - - 会产生一个“em dash”:

尽管一些更奇特的键盘具有 Compose 键,但通常可以通过将一个已有的键替换为它来获得。例如,要将 Menu 键设置为 Compose 键,请使用 桌面环境 配置,或者将 compose:menu 传递给 XkbOptions(或 setxkbmapsetxkbmap -option compose:menu)。允许的按键替换定义在 /usr/share/X11/xkb/rules/base.lst 中。

$ grep "compose:" /usr/share/X11/xkb/rules/base.lst

如果文件中未找到所需的映射,另一种方法是使用 xmodmap 将所需的键映射到 Multi_key 键符号,它默认充当组合键(请注意,xmodmap 设置会被 setxkbmap 重置)。

按键组合

组合键的默认组合取决于会话中配置的 区域设置,并存储在 /usr/share/X11/locale/used_locale/Compose 中,其中 used_locale 例如是 en_US.UTF-8

您可以复制默认文件到 ~/.XCompose 并进行编辑来定义您自己的组合键组合。或者,创建一个空的 ~/.XCompose 文件并使用 include "%L" 包含默认文件,例如

~/.XCompose
include "%L"

<Multi_key> <g> <a> : "α"
<Multi_key> <g> <b> : "β"
<Multi_key> <g> <g> : "γ"

组合键(在 ~/.XCompose 文件中表示为 <Multi_key>)适用于数千个有效的 Unicode 字符,包括基本多文种平面之外的字符。请查看 Compose(5) 手册页,它解释了 XCompose 文件的格式。

但是,GTK 默认不使用 XIM,因此不遵循 ~/.XCompose 键。这可以通过配置 图形环境环境变量 GTK_IM_MODULE=xim 和/或 XMODIFIERS="@im=none" 来强制 GTK 使用 XIM 来解决。

提示 XIM 非常老旧,您可能在其他输入法(如 IBusFcitx5)上会有更好的体验;有关详细信息,请参阅 输入法
注意 XIM 将阻止使用 Ctrl+Shift+u 组合键插入 Unicode 字符。

在其他按键上设置货币符号

大多数欧洲键盘在 5 键上印有欧元符号 (€)。例如,要通过 Alt+5 访问它,请使用 lv3:ralt_switcheurosign:5 选项。

卢比符号 (₹) 也可以使用 rupeesign:4 以相同方式使用。

按下 Caps Lock 后立即切换状态

那些喜欢使用 Caps Lock 键输入大写字母的人可能会遇到短暂延迟,因为 Caps Lock 状态切换后,会导致输入两个或更多大写字母(例如,THeARch LInux)。这种情况发生是因为 Caps Lock 在按下 Caps Lock 键时立即启用,但在释放第二个按键时才禁用。这种行为 源于打字机,当时通过物理锁定移码杆来达到 Caps Lock 功能,而释放 Shift 键的操作才是导致锁定释放的原因。

一些更受欢迎的操作系统已经取消了这种行为,无论是自愿的(因为它可能会让一些人感到困惑)还是错误的,但这取决于个人偏好。Xserver 错误跟踪器上已提交错误报告,因为目前没有简单的方法切换到其他操作系统所反映的行为。对于任何想继续关注此问题的人,可以在 [3][4] 找到错误报告和最新进展。

解决方法

首先,将您的键盘配置导出到一个文件

$ xkbcomp -xkb $DISPLAY xkbmap

xkbmap 文件中,找到以 key <CAPS> 开头的 Caps Lock 部分

 key <CAPS> {         [       Caps_Lock ] };

并用以下代码替换整个部分

key <CAPS> {
    repeat=no,
    type[group1]="ALPHABETIC",
    symbols[group1]=[ Caps_Lock, Caps_Lock],
    actions[group1]=[ LockMods(modifiers=Lock), Private(type=3,data[0]=1,data[1]=3,data[2]=3)]
};

保存并重新加载键盘配置

$ xkbcomp -w 0 xkbmap $DISPLAY

考虑将其设置为一个服务,在 X 启动后运行,因为重新加载的配置不会在系统重启后保留。

一键式按键功能

要为修饰键分配额外的单次按键功能,您可以使用 xcape。例如,可以将 CapsLock 单独按下时作为 Escape,与另一个键一起使用时作为 Control。首先,如前所述,使用 setxkbmap 设置 Control 键互换,然后使用 xcape 设置 Escape 关联。

$ xcape -e 'Caps_Lock=Escape'

您可以将多个关联用分号分隔,例如:Caps_Lock=Escape;Shift_L=Escape

如果您按住一个键的时间超过超时值(默认为 500 毫秒),xcape 将不会生成按键事件。

调整按键重复延迟和速率

按键重复延迟 指的是按住一个键才能开始重复过程所需的时间(通常以毫秒为单位)。在触发重复过程后,字符将以一定频率(通常以 Hz 为单位)重复,该频率由 按键重复速率 指定。请注意,这些设置是分别为 Xorg 和 虚拟控制台配置的。

使用 xset

xorg-xset 提供的 xset 工具可用于设置活动 X 服务器的按键重复延迟和速率,尽管在运行时执行某些操作可能会导致 X 服务器重置这些更改并恢复为 seat defaults

用法

$ xset r rate delay [rate]

例如,要将按键重复延迟设置为 200ms,将按键重复速率设置为 30Hz,请使用以下命令

$ xset r rate 200 30

不指定延迟和速率而执行该命令将把按键重复值重置为其各自的默认值;延迟为 660 毫秒,速率为 25Hz

$ xset r rate

使用 xautocfg

xautocfgAUR 可以自动应用新连接设备的重复速率设置。它会监视 X11 事件并将重复速率配置应用于新连接的键盘。

调整配置

~/.config/xautocfg.cfg
[keyboard]

# repeat delay in ms
delay = 200

# repeat rate in Hz
rate = 30

如果 graphical-session.target 由您的窗口管理器或桌面环境启动,请启用 systemd/User xautocfg.service。或者,手动启动 xautocfg

使用 AutoRepeat 配置选项

要使配置在系统范围内持久化,请使用 Xorg 配置文件更改 seat defaults,如 #使用 X 配置文件 中所述,并添加一个 AutoRepeat 部分条目:[5]

AutoRepeat 的参数是 delayinterval(以毫秒为单位)。如果您喜欢 xset 的 25 Hz rate,则相应的 interval 为 1000 / 25 = 40 毫秒。

/etc/X11/xorg.conf.d/00-keyboard.conf
Section "InputClass"
        ...
        Option "AutoRepeat" "200 40"
        ...
EndSection

使用 XServer 启动选项

另一种使配置持久化的方法是在 X 服务器启动时使用以下选项传递所需的设置

  • -ardelay milliseconds - 设置自动重复延迟(按键必须按住的毫秒数,然后才开始自动重复)。
  • -arinterval milliseconds - 设置自动重复间隔(在自动重复生成的按键之间应经过的毫秒数)。

请参阅 Xserver(1) 以获取 X 服务器选项的完整列表,并参考您的 显示管理器 以了解如何传递这些选项。

手动创建新布局

要手动修改或创建布局,需要一些底层知识。

内核分配给物理按键的数字。它们列在 /usr/include/linux/input-event-codes.h 中,前提是已安装 linux-api-headers(它是 linux-headers 的依赖项),如下所示

#define KEY_Q			16
#define KEY_W			17
...
#define KEY_LEFTBRACE		26
#define KEY_RIGHTBRACE		27

这些值由 libevdev 使用。对于依赖 libevdev 的 输入重映射工具,按键名称通常是这些条目的lowercase形式,不带前缀 KEY_。Xorg 的“keycode”值是文件 input-event-codes.h 中的值加 8。(例如,KEY_Q 是 16。打印“Q”的按键的 X keycode 为 24。)

然而,在 XKB 中,即对于 X 和 Wayland,按键名称看起来像 <AD11><TLDE>。它们中的大多数很容易猜测;例如,如果您有一个意大利语键盘,只需查看 /usr/share/X11/xkb/symbols/it。它有以下行

key <TLDE>  {[ backslash,        bar,        notsign,       brokenbar ]};
key <AD11>  {[    egrave,     eacute,    bracketleft,       braceleft ]};

当这还不够时,请查看 /usr/share/X11/xkb/keycodes 中的文件,特别是 evdev 文件。这些行定义了按键名称的 keycode。

<TLDE> = 49;
<AD11> = 34;

最后,可以分配给按键的可能符号是什么,例如上面示例中的 notsignbrokenbar?它们定义在 /usr/include/X11/keysymdef.h 中。

#define XK_brokenbar                     0x00a6  /* U+00A6 BROKEN BAR */
#define XK_notsign                       0x00ac  /* U+00AC NOT SIGN */

带有 XF86 前缀的某些符号列在单独的文件 /usr/include/X11/XF86keysym.h 中。

#define XF86XK_MonBrightnessUp       0x1008ff02  /* Monitor/panel brightness */

此按键在 X 中称为 XF86MonBrightnessUp。(同样是从 XK_ 中提取,但在这种情况下是名称中间部分。)

参见