将 USB 键盘插入笔记本电脑时如何自动更改键盘配置(并获得确定性行为)?

将 USB 键盘插入笔记本电脑时如何自动更改键盘配置(并获得确定性行为)?

我正在使用 Linux Mint 20。udev 规则让我感到不安。有时它们有效,有时则无效。

再说一遍,今天它们不起作用。

我总是最终在网络上复制东西,然后调整它,然后最终得到一个工作配置,只是发现几周/几个月后它们停止工作。

一劳永逸地,我真的很想得到一个确定性的解决方案。

  • 我想要的:当我将键盘插入笔记本电脑时,外部 USB 键盘配置会自动更改(交换大写字母和 ctrl + lwin 撰写)。

  • 我做了什么:

a) 获取我的 USB 键盘设备信息:

# lsusb |grep Dell
Bus 001 Device 045: ID 413c:2107 Dell Computer Corp. 

b) 在我的 /etc/udev/rules.d/90-keyboard_swapcaps.rules 中,我添加了:

## DEBUG
ACTION=="change", ATTRS{idVendor}=="413c", ATTRS{idProduct}=="2107", RUN+="/bin/sh -c 'echo == >> /tmp/udev-env.txt; env >> /tmp/udev-env.txt'"
# ACTUAL
ACTION=="change", ATTRS{idVendor}=="413c", ATTRS{idProduct}=="2107", ENV{XKBLAYOUT}="fr", ENV{XKBOPTIONS}+="ctrl:swapcaps", ENV{XKBOPTIONS}+="compose:lwin"

c)然后我跑了:

# udevadm control --reload-rules && udevadm trigger
  • 我得到什么:

a) 键盘配置没有任何变化。

b) 监控

# udevadm monitor -u
...
UDEV  [10555.979594] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.2/1-1.2:1.0/0003:413C:2107.001E/input/input55 (input)
UDEV  [10555.989903] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.2/1-1.2:1.0/0003:413C:2107.001E/input/input55/input55::numlock (leds)
UDEV  [10555.992442] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.1/1-1.1:1.0/0003:046D:C077.001D/input/input54 (input)
UDEV  [10555.994812] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.2/1-1.2:1.0/0003:413C:2107.001E/input/input55/input55::scrolllock (leds)
UDEV  [10556.001225] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.2/1-1.2:1.0/0003:413C:2107.001E/hidraw/hidraw1 (hidraw)
UDEV  [10556.003513] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.1/1-1.1:1.0/0003:046D:C077.001D/input/input54/mouse1 (input)
UDEV  [10556.005834] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.1/1-1.1:1.0/0003:046D:C077.001D/hidraw/hidraw0 (hidraw)
UDEV  [10556.010005] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.2/1-1.2:1.0/0003:413C:2107.001E/input/input55/input55::capslock (leds)
UDEV  [10556.019614] change   /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.2/1-1.2:1.0/0003:413C:2107.001E/input/input55/input55::numlock (leds)
UDEV  [10556.021307] change   /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.2/1-1.2:1.0/0003:413C:2107.001E/input/input55/input55::scrolllock (leds)
UDEV  [10556.022045] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.2/1-1.2:1.0/0003:413C:2107.001E/input/input55/event20 (input)
UDEV  [10556.024438] change   /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.2/1-1.2:1.0/0003:413C:2107.001E/input/input55/input55::capslock (leds)
UDEV  [10556.026259] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.2/1-1.2:1.0/0003:413C:2107.001E (hid)

这告诉我设备已被检测到并且是正确的

c) 在 /tmp/udev-env.txt 中,许多行类似于:

...
==
ID_FOR_SEAT=leds-pci-0000_00_14_0-usb-0_1_2_1_0
ACTION=change
TRIGGER=kbd-scrolllock
SEQNUM=17431
USEC_INITIALIZED=10059229961
TAGS=:seat:
XKBLAYOUT=fr
XKBOPTIONS=ctrl:swapcaps compose:lwin
DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.2/1-1.2:1.0/0003:413C:2107.001C/input/input53/input53::scrolllock
SUBSYSTEM=leds
ID_PATH=pci-0000:00:14.0-usb-0:1.2:1.0
ID_PATH_TAG=pci-0000_00_14_0-usb-0_1_2_1_0
PWD=/

这告诉我规则匹配并被应用。

我到底做错了什么而无法更改键盘配置?

答案1

环境变量仅从父进程传播到子进程,而不是从子进程传播到父进程。并且从 udev 规则运行的任何内容通常都无法访问 GUI 会话的环境。

RUN+=在您的情况下,由udev 规则部分启动的 shell 进程肯定具有按照您想要的方式设置的XKBLAYOUT和环境变量。XKBOPTIONS但是,一旦RUN+=...完成其中的命令,该 shell 就会退出...并且那些修改的环境变量将随之消失,而不会对任何内容产生任何影响。

仅当其中的信息传递给命令或类似命令时,这些环境变量才会生效setxkbmap...这在您的发行版中可能作为 X11 会话设置的标准部分发生。仅设置变量本身而不以某种方式将其值传递给 X11 服务器对键盘布局没有任何影响。

由于 X11 会话设置通常来源/etc/profile和类似的 shell 启动文件来为 GUI 应用程序提供合理的环境,因此可能只需将这些变量设置/etc/profile.d/*.sh出现上班。但真正的魔力并不在于变量,而在于 X11 会话设置过程,该过程将setxkbmap -layout $XKBLAYOUT ...根据这些变量的值执行或等效。这就是你的 udev 规则中根本没有提供的部分。

udev 规则的执行上下文与 GUI 会话的执行上下文完全无关。因此,即使您添加了一个setxkbmap使用这些变量将更改传达给 X11 服务器的命令,由 udev 规则启动的 shell 也不会有任何DISPLAY变量XAUTHORITY引用您的 GUI 会话,因此该命令只会发出一条Cannot open display错误消息。

DISPLAY变量和 X 会话 cookie 文件,无论是在环境变量~/.Xauthority指向的自定义位置还是在XAUTHORITY环境变量指向的自定义位置,都是成为 X11 GUI 会话一部分或以任何方式向该会话发送命令所需的两个基本要素。)

令人沮丧的是,有几乎是一个可以巧妙解决这个问题的功能。您可以创建一个/etc/udev/hwdb.d/70-keyboard.hwdb以此内容命名的文件:

evdev:input:b????v413Cp2107e*
  XKB_FIXED_LAYOUT="fr"
  # XKB_FIXED_OPTIONS="ctrl:swapcaps compose:lwin" # Unfortunately this part has not been implemented yet!

据我了解,这将允许指定 X11 键盘布局仅适用于该特定键盘,即使系统插入了其他布局的其他键盘。不幸的是,允许指定的部分选项XKB 键盘布局规范的一部分(我想这对您来说是重要的部分)未实​​现。

相关内容