如何将不同的键盘布局永久分配给USB键盘?
我经常在我的笔记本电脑上插入一个USB键盘(除了外接显示器和鼠标,这些都可以将我的笔记本电脑转换为台式电脑),我更喜欢使用不同的键盘布局。
每次插入USB键盘时,我都必须手动更改当前的键盘布局。
如果可能的话,我想用自动方式。
Radu对这个问题的回答给出了一些线索,但似乎我需要一个启动脚本来完成这项任务,因为每次计算机启动时我的USB键盘的设备ID都会改变。
此启动脚本可能首先包含命令xinput -list | grep "USB Keyboard"
xinput -list | grep "USB Keyboard"
,另一个命令用于获取显示的第一个USB键盘ID号,然后在最终命令中使用它来设置我为USB键盘选择的布局,如下所示:
setxkbmap -device -layout
经过一番研究,我找到了一个解决方案,虽然我仍然对其他(可能更好)的答案持开放态度。
这是一个启动脚本 (可以添加到启动应用程序 ),它将把输入的usbkbd_layout变量设置为xinput -list中的usbkbd设备ID :
#!/bin/bash usbkbd=`xinput -list | grep -c "USB Keyboard"` if [[ "$usbkbd" -gt 0 ]] then usbkbd_ids=`xinput -list | grep "USB Keyboard" | awk -F'=' '{print $2}' | cut -c 1-2` usbkbd_layout="tr(f)" for ID in $usbkbd_ids do setxkbmap -device "${ID}" -layout "${usbkbd_layout}" done fi exit 0
对于用户在桌面设置(使用外部键盘,鼠标和显示器等)上开始使用笔记本电脑的场景,此脚本非常有用(并且更稳定),并且只要插入外部USB键盘,它也可以手动运行…
================================================== ========================
更好(几乎完美)解决方案 – 感谢MinimusHeximus以及他在下面的评论中提到的线程的各自贡献者:
我现在只需插入我的USB键盘并自动应用其不同的(TR-F)键盘布局,同时仍保持笔记本电脑上的默认键盘布局(TR-Q)!
以下是使这成为可能的文件及其内容:
/etc/udev/rules.d/00-usb-keyboard.rules
ATTRS{idVendor}=="09da", ATTRS{idProduct}=="0260", OWNER="sadi" ACTION=="add", RUN+="/home/sadi/.bin/usb-keyboard-in_udev" ACTION=="remove", RUN+="/home/sadi/.bin/usb-keyboard-out_udev"
/home/sadi/.bin/usb-keyboard-in_udev
#!/bin/bash /home/sadi/.bin/usb-keyboard-in &
/home/sadi/.bin/usb-keyboard-in
#!/bin/bash sleep 1 DISPLAY=":0.0" HOME=/home/sadi/ XAUTHORITY=$HOME/.Xauthority export DISPLAY XAUTHORITY HOME usbkbd_id=`xinput -list | grep "USB Keyboard" | awk -F'=' '{print $2}' | cut -c 1-2 | head -1` usbkbd_layout="tr(f)" if [ "${usbkbd_id}" ]; then gsettings set org.gnome.settings-daemon.plugins.keyboard active false sleep 2 setxkbmap -device "${usbkbd_id}" -layout "${usbkbd_layout}" fi
/home/sadi/.bin/usb-keyboard-out_udev
#!/bin/bash /home/sadi/.bin/usb-keyboard-out &
/home/sadi/.bin/usb-keyboard-out
#!/bin/bash sleep 1 DISPLAY=":0.0" HOME=/home/sadi/ XAUTHORITY=$HOME/.Xauthority export DISPLAY XAUTHORITY HOME gsettings set org.gnome.settings-daemon.plugins.keyboard active true
笔记:
- 当然,你的。“bin”文件夹中的所有四个文件都应该具有必要的权限(可读和可执行),例如可以使用像
chmod - 755 /home/sadi/.bin/usb-keyboard-*
这样的终端命令来实现chmod - 755 /home/sadi/.bin/usb-keyboard-*
- 有时插入USB键盘后,它仍然使用相同的(默认)键盘布局,并在第二次尝试时切换到指定的布局(可能需要更多的睡眠时间?)
- USB键盘特定布局在登录屏幕(登出时)无效。
- 如果你为/ home使用一个单独的分区,那么最好将四个脚本放在根分区中的某个位置,例如/ usr / local / bin并相应地修改所有相应文件的内容,因为有时udev可能会寻找安装/ home分区之前的那些文件会导致问题。
为了适应不同的要求,请将此设置更改为:
- USB键盘供应商和产品ID应根据命令
lsusb
的输出进行更改(例如,我的lsusb
输出为我的USB键盘输出:Bus 001 Device 006: ID 09da:0260 A4 Tech Co., Ltd
) - OWNER和所有用户目录名称应从“sadi”更改为其他名称
- usbkbd_id可能需要稍微调整才能获取正确的设备ID(例如,输出命令
xinput -list | grep "USB Keyboard"
给我两行;↳ USB Keyboard id=14 [slave keyboard (3)]
和↳ USB Keyboard id=16 [slave keyboard (3)]
;然后使用“=”作为字段分隔符并捕获第二部分,然后使用awk
过滤;然后仅剪切前两位数字,然后仅使用第一行中的值) - usbkbd_layout的值可以是任何其他有效选择
可以在udev规则中指定X11驱动程序选项,不需要自定义脚本。 举个例子,这是我的/etc/udev/rules.d/99-usb-kbd.rules的内容
ACTION=="add", ATTRS{idVendor}=="04d9", ATTRS{idProduct}=="2323", ENV{XKBMODEL}="pc104", ENV{XKBLAYOUT}="us", ENV{XKBVARIANT}="euro", ENV{XKBOPTIONS}="compose:caps"
此规则确保特定USB键盘在Xorg中使用美国布局(我的笔记本电脑的内部键盘是德语,这也是我的主要布局)。 重点:
- 您可以使用
lsusb
或evtest
找到idVendor
idProduct
和evtest
- 您可以使用
/usr/share/X11/xkb/symbols
任何布局。 注意指定有效布局和有效变体。 - 文件名必须以数字> 64开头,以便设置覆盖
/lib/udev/rules.d/64-xorg-xkb.rules
指定的系统范围设置 - 确保Gnome / KDE布局管理不会覆盖您的设置。
我刚刚为一个bépoTypematrix键盘(优化的优秀dvorak的法语版)和广泛的系统环境改进了这个解决方案(假设你有对机器的root访问权限)。 它只需要3个文件。 如果未能找出失败的原因,您可以查阅日志文件。
/etc/udev/96-usb-keyboard.rules
ATTRS{idVendor}=="1e54", ATTRS{idProduct}=="2030", SUBSYSTEMS=="usb", ACTION=="add", RUN+="/etc/udev/bepo-typematrix-kbd.sh in" ATTRS{idVendor}=="1e54", ATTRS{idProduct}=="2030", SUBSYSTEMS=="usb", ACTION=="remove", RUN+="/etc/udev/bepo-typematrix-kbd.sh out"
/etc/udev/bepo-typematrix-kbd.sh (绝对有必要使用中间后台脚本)
#!/bin/bash dir=$(dirname $0) command=$(basename $0) command=$dir/${command%\.sh} arg=$1 # must be "in" or "out" LOG=/var/log/bepo-typematrix-kbd.log [ -x "$command" ] && $command $arg >$LOG 2>&1 &
的/ etc / udev的/ bepo-typematrix-KBD
#!/bin/bash # jp dot ayanides at free.fr MODEL="tm2030USB-102" # keyboard model DISPLAY=':0.0' GSETTING=/usr/bin/gsettings XSET=/usr/bin/xset SETXKBMAP=/usr/bin/setxkbmap XINPUT=/usr/bin/xinput USER=$(/usr/bin/who | /usr/bin/awk -v DIS=':0' '{if ($2==DIS) print $1}') eval HOME=~$USER XAUTHORITY=$HOME/.Xauthority export DISPLAY XAUTHORITY HOME case $1 in 'in') BEPO=$($XINPUT list --short | grep "TypeMatrix.com USB Keyboard" | grep keyboard | sed -e 's/^.*id=\([0-9]\+\).*/\1/g') if [ -n "$BEPO" ]; then [ -x $GSETTING ] && $GSETTING set org.gnome.settings-daemon.plugins.keyboard active false # apparently nothing to do with TDE (trinity KDE) for ID in $BEPO; do # case of multiple bepo keyboard is taken into account [ -x $SETXKBMAP ] && $SETXKBMAP -device $ID -model $MODEL -layout fr -variant bepo done fi echo "bépo keyboard id(s) is (are) $BEPO" [ -x $XSET ] && $XSET -display $DISPLAY r rate 250 40 ;; 'out') # apparently nothing to do with TDE (trinity KDE) [ -x $GSETTING ] && $GSETTING set org.gnome.settings-daemon.plugins.keyboard active true ;; *) printf "wrong parameter: $1\n" exit 1 ;; esac
在摆弄了很多东西之后,这就是我现在所经营的。 也许我会写一篇完整的文章并在存储库中发布代码,如果感兴趣的话。
像这样为udev设置一个新的规则集:
sudo gedit /etc/udev/rules.d/80-external-keyboard.rules
只要具有给定的供应商和产品ID组合的设备触发某个操作,该规则就应该调用shell脚本。
ATTRS{idVendor}=="04b4", ATTRS{idProduct}=="4042", RUN+="/home/phil/.bin/switch-kb-layout-wrapper.sh"
添加新规则集后,重新启动udev服务:
sudo service udev restart
注意:通过在该文件中提供更具体的匹配规则,我无法获得可靠的结果。 最重要的是,添加ACTION
匹配规则不起作用。 据我所知,脚本无论如何都被触发了。 添加ACTION=="add"
,仍会在删除设备时调用脚本。 非常奇怪和混乱。
但是 ,触发udev规则的操作将可用于被调用的脚本,如下所示。
接下来,脚本本身。 嗯,不太好。 请注意文件名中的wrapper
后缀。 这表明这不是实际的脚本,而是一个调用脚本并在后台执行它的包装器,以便udev可以完成其进程。
~/.bin/switch-kb-layout-wrapper.sh
:
#!/bin/sh /home/phil/.bin/switch-kb-layout.sh "${ACTION}" &
变量ACTION
包含由设备触发的udev操作。 它产生的值如add
(设备已插入)和remove
(设备已被删除)。 我们稍后会使用它们。
~/.bin/switch-kb-layout.sh
:
#!/bin/sh sleep 1 # Some environment variables that need to be set in order to run `setxkbmap` DISPLAY=":0.0" HOME=/home/phil XAUTHORITY=$HOME/.Xauthority export DISPLAY XAUTHORITY HOME udev_action=$1 log_file="$HOME/switch-kb-layout.log" if [ "${udev_action}" != "add" ] && [ "${udev_action}" != "remove" ]; then echo "Other action. Aborting." >> $log_file exit 1 fi internal_kb_layout="de" internal_kb_variant="" external_kb_layout="us" external_kb_variant="altgr-intl" kb_layout="" kb_variant="" if [ "${udev_action}" = "add" ]; then kb_layout=$external_kb_layout kb_variant=$external_kb_variant elif [ "${udev_action}" = "remove" ]; then kb_layout=$internal_kb_layout kb_variant=$internal_kb_variant fi setxkbmap -layout "${kb_layout}" echo "set layout:" "$kb_layout" >> $log_file if [ ! -z "${kb_variant}" ]; then setxkbmap -variant "${kb_variant}" echo "set variant:" "$kb_variant" >> $log_file fi
设置HOME
变量时,用你的用户名替换你的用户名( $(whoami)
在这里不起作用,因为你的用户不会调用你的用户名,而是root
)。
sed -i "s/phil/YOUR_USERNAME/g" ~/.bin/switch-kb-layout.sh
出于测试目的,我添加了一些行,将某些事件记录到我的主目录中的文件,以查看是否一切正常。 您可以保存删除这些。
最后,这些脚本需要具有执行权限。 此外,重要的是要注意这些脚本将由root
用户调用,因此请小心您在那里执行的操作。
chmod +x ~/.bin/switch-kb-layout-wrapper.sh ~/.bin/switch-kb-layout.sh
我对udev执行的脚本有一些权限问题。 我用sudo解决了如下问题:
# Estract id of MX3 keyboard devices that present themself as "123 COM Smart Control" IDLIST=$(sudo -u max /usr/bin/xinput -list | grep "123 COM Smart Control" | grep keyboard | sed -e 's/^.*id=\([0-9]\+\).*/\1/g')
设置每个设备的键盘映射
for ID in $IDLIST; do sudo -u max /usr/bin/setxkbmap -device $ID -layout "${kb_layout}" -display :0 done