uSBキーボードを接続したときに新しいキーボードレイアウトをロードしようとしていますが、udevルールが機能していません。
SUBSYSTEM == "input"、ATTR {idVendor} == "062a"、ATTR {idProduct} == "0201"、GOTO = "usb_xmodmap_auto" LABEL = " usb_xmodmap_auto " ACTION ==" add "、RUN + ="/usr/bin/xmodmap〜/ .usbXmodmap " ACTION ==" remove "、RUN + ="/usr/bin/xmodmap〜 /.pndXmodmap"
私は使用してルールをリロードしました:
> sudo udevadm control --reload-rules
システムを再起動しますが、USBキーボードを接続すると、元のxmodmapがまだロードされているため、キーボードレイアウトが間違っていますが、ターミナルでコマンドを実行すると
>/usr/bin/xmodmap〜/ .usbXmodmap
>/usr/bin/xmodmap〜/ .pndXmodmap
彼らはうまく働きます。
soneoneがお役に立てば幸いです。
編集:
さらに支援するために、いくつかのudevadmテストを実行しました。
> udevadm test --action = add /devices/platform/ehci-omap.0/usb1/1-2/1-2.3/1-2.3:1.1/input/input10
出力:
run_command:呼び出し:test udevadm_test:バージョン151 このプログラムはデバッグ専用であり、RUNキーで指定されたプログラムを実行しません 。 一部の値が異なるか、シミュレーションの実行時に使用できない場合があるため、正しくない結果が表示される場合があります。 [...] parse_file:reading ' /etc/udev/rules.d/usb-keyboard.rules 'as rules file udev_rules_new:rules use 100572 bytes tokens(8381 * 12 bytes)、21523 bytes buffer udev_rules_new:temporary index used 35380バイト(1769 * 20バイト) udev_device_new_from_syspath:device 0x3b4d8 has devpath '/devices/platform/ehci-omap.0/usb1/1-2/1-2.3/1-2.3:1.1/input/input10 ' udev_rules_apply_to_event:RUN'/sbin/modprobe -b $ env {MODALIAS} '/etc/udev/rules.d/80-drivers.rules:5 udev_rules_apply_to_event:RUN' socket:@/org/freedesktop/hal/udev_event '/etc/udev/rules.d/90-hal.rules:2 udev_rules_apply_to_event:RUN'/sbin/modprobe $ env {MODALIAS} '/ etc/udev/rules .d/local.rules:31 udev_rules_apply_to_event:RUN 'socket:/ org/kernel/udev/monitor' /etc/udev/rules.d/run.rules:2 udev_rules_apply_to_event:RUN '/ usr/bin/xmodmap〜 /.usbXmodmap '/etc/udev/rules.d/usb-keyboard.rules:4 udevadm_test:UDEV_LOG = 6 udevadm_test:DEVPATH =/devices/platform/ehci-omap.0/usb1/1-2/1-2.3/1-2.3:1.1/input/input10 udevadm_test:PRODUCT = 3/62a/201/110 udevadm_test:NAME = "USB準拠のキーボード" udevadm_test:PHYS = "usb-ehci-omap.0-2.3/input1" udevadm_test:UNIQ = "" udevadm_test:EV == 1f udevadm_test :KEY == 837fff 2c3027 bf004444 0 0 1fe3 c04 a27c000 267bfa d941dfed 9e0000 0 0 0 udevadm_test:REL == 143 udevadm_test:ABS == 1 0 udevadm_test:MSC = = 10 udevadm_test:MODALIAS = input:b0003v062Ap0201e0110-e0,1,2,3,4、k71,72,73,74,77,80,82,83,85,86,87,88,89 、8A、8B、8C、8E、8F、90、96、98、9B、9C、9E、9F、A1、A3、A4、A5、A6、A7、A8、A9、AB、AC、AD、AE、B1 、B2、B5、CE、CF、D0、D1、D2、D5、D9、DB、E2、EA、EB、100、101、105、106、107、108、109、10A、10B、10C、162、166、16A、16E、178、179、17A、17B、17C、17D 、17F、180、181、182、185、18C、18D、192、193、195、1A0、1A1、1A2、1A3、1A4、1A5、1A6、1A7、1A8、1A9、1AA、1AB、1AC、1AD、1AE、1B0、1B1、1B7、r0、1 、6、8、 a20、m4、lsfw udevadm_test:ACTION = add udevadm_test:SUBSYSTEM = input udevadm_test:run: '/ sbin/modprobe -b input:b0003v062Ap0201e0110-e0,1,2 、3、4、k71、72、73、74、77、80、82、83、85、86、87、88、89、8A、8B、8C、8E、8F、90、96、98、9B、9C 、9E、9F、A1、A3、A4、A5、A6、A7、A8、A9、AB、AC、AD、AE、B1、B2、B5、CE、CF、D0、D1、D2、D5、D9、DB 、E2、EA、EB、100、101、105、106、107、108、109、10A、10B、10C、162、166、16A、16E、178、179、17A、17B、17C、17D、17F、180、181、182、185、18C、18D、192、193、195、1A0、1A1、1A2、1A3、1A3、1A3 、1A5,1A6,1A7,1A8,1A9,1AA、1AB、1AC、1AD、1AE、1B0,1B1,1B7、r0,1,6,8、a20、m4、lsfw ' udevadm_test:run: 'socket:@/org/freedesktop/hal/udev_event' udevadm_test:run: '/ sbin/modprobe input:b0003v062Ap0201e0110-e0,1,2,3,4、k71,72,73,74,77 、80、82、83、85、86、87、88、89、8A、8B、8C、8E、8F、90、96、98、9B、9C、9E、9F、A1、A3、A4、A5、A6 、A7、A8、A9、AB、AC、AD、AE、B1、B2、B5、CE、CF、D0、D1、D2、D5、D9、DB、E2、EA、EB、100、101、105、106、107、108、109、10A、10B、10C 、162、166、16A、16E、178、179、17A、17B、17C、17D、17F、180、181、182、185、18C、18D、192、193、195、1A0、1A1、1A2、1A3、1A4、1A5、1A6、1A7、1A8、1A9、1AA、1A B、1AC、1AD、1AE、1B0,1B1,1B7、r0,1,6,8、a20、m4、lsfw ' udevadm_test:run:' socket:/ org/kernel/udev/monitor ' udevadm_test:実行: '/ usr/bin/xmodmap〜/ .usbXmodmap'
そして
> udevadm test --action = remove /devices/platform/ehci-omap.0/usb1/1-2/1-2.3/1-2.3:1.1/input/input10
出力:
run_command:呼び出し:test udevadm_test:バージョン151 このプログラムはデバッグ専用であり、RUNキーで指定されたプログラムを実行しません 。 一部の値が異なるか、シミュレーションの実行時に使用できない場合があるため、正しくない結果が表示される場合があります。 [...] parse_file:reading ' /etc/udev/rules.d/usb-keyboard.rules 'as rules file udev_rules_new:rules use 100572 bytes tokens(8381 * 12 bytes)、21523 bytes buffer udev_rules_new:used temp一時インデックス35380バイト(1769 * 20バイト) udev_device_new_from_syspath:device 0x3b4d8 has devpath '/devices/platform/ehci-omap.0/usb1/1-2/1-2.3/1-2.3:1.1/input/input10 ' udev_rules_apply_to_event:RUN' socket:@/org/freedesktop/hal/udev_event '/etc/udev/rules.d/90-hal.rules:2 udev_rules_apply_to_event:RUN' socket:/ org/kernel/udev/monitor '/etc/udev/rules.d/run.rules:2 udev_rules_apply_to_event:RUN'/usr/bin/xmodmap〜/ .pndXmodmap '/etc/udev/rules.d /usb-keyboard.rules:5 udevadm_test:UDEV_LOG = 6 udevadm_test:DEVPATH =/devices/platform/ehci-omap.0/usb1/1-2/1-2.3/1- 2.3:1.1/input/input10 udevadm_test:PRODUCT = 3 /62a/201/110 udevadm_test:NAME = "USB準拠のキーボード" udevadm_test:PHYS = "usb-ehci-omap.0-2.3/input1" udevadm_test: UNIQ = "" udevadm_test:EV == 1f udevadm_test:KEY == 837fff 2c3027 bf004444 0 0 1fe3 c04 a27c000 267bfa d941dfed 9e0000 0 0 0 udevadm_test:REL == 143 udevadm_test:ABS == 1 0 udevadm_test:MSC == 10 udevadm_test:MODALIAS = input:b0003v062Ap0201e0110-e0,1,2,3,4、k71,72、 73、74、77、80、82、83、85、86、87、88、89、8A、8B、8C、8E、8F、90、96、98、9B、9C、9E、9F、A1、A3、 A4、A5、A6、A7、A8、A9、AB、AC、AD、AE、B1、B2、B5、CE、CF、D0、D1、D2、D5、D9、DB、E2、EA、EB、100、101、105、106、107、108、109、 10A、10B、10C、162、166、16A、16E、178、179、17A、17B、17C、17D、17F、180、181、182、185、18C、18D、192、193、195、1A0、1A1、1A2、1A3、1A4、1A5、1A6、1A7、1A8、 1A9,1AA、1AB、1AC、1AD、1AE、1B0,1B1,1B7、r0,1,6,8、a20、m4、lsfw udevadm_test:ACTION = remove udevadm_test:SUBSYSTEM = input udevadm_test:run: 'socket:@/org/freedesktop/hal/udev_event' udevadm_test:run: 'socket:/ org/kernel/udev/monitor' udevadm_test:実行: '/ usr/bin/xmodmap〜/ .pndXmodmap'
これは動作するはずですが、これが答えを得るのに役立つことは望んでいません。
私はこれを回避する方法を見つけましたが、少しハックです。
Udev、setxkbmap、およびxinput --listを使用して2つのキーボードをセットアップし、それらがUSBホットプラグで動作するようにすることで、今日とまったく同じ点に到達しました。レイアウトを変更するのではなく、キーを交換していますが、ホットプラグでキーボードを特定し、条件付きでsetxkbmapを呼び出すことができれば、指定したキーボードのみの言語を設定できるはずです。 。キーボードレイアウトのリストは_ls -l /usr/share/kbd/keymaps/i386/
_にあり、_xinput -list
_でデバイス名を確認できます。
rizumu
をユーザー名に置き換えることをお勧めします。明示的にしないとこれを行う方法はありません。your
キーボード名をgrepしてください。lsusb
を使用して、udevルールで設定する必要があるハードウェアIDを見つけます。私のdasキーボードは次のように見えます_Bus 002 Device 009: ID 04d9:2013 Holtek Semiconductor, Inc.
_最初にudevルールを設定して、キーボードがautodetctになるようにudevルールを作成します。
ファイル_/etc/udev/rules.d/00-usb-keyboards.rules
_内:
_ACTION=="add", ATTRS{idVendor}=="04d9", ATTRS{idProduct}=="2013", RUN+="/home/rizumu/bin/kbd_udev", OWNER="rizumu"
_
〜/ bin/kbdと〜/ bin/kbd_udevの2つのファイルがあります。適切な権限があることを確認してください_chmod 755 ~/bin/kbd*
_
_~/bin/kbd_udev
_スクリプトには以下が含まれます。
_#!/bin/bash
/home/rizumu/bin/kbd &
_
そして、バックグラウンドで_~/bin/kbd
_を呼び出すだけで、udevがプロセスを完了し、キーボードをアクティブにできることがわかります。 __inputを使用してデバイスIDを取得できるようにキーボードがアクティブになるまで待機する必要があるため、_~/bin/kbd
_スクリプト内で1秒間スリープします。これを実現するために、いくつかの変数を設定してエクスポートし、xinput setxkbmapがこれらの作業を実行できるようにしました:DISPLAY
、XAUTHORITY
、HOME
、および1つの_daskb_id
_私のdaskeyboardのID:
_#!/bin/bash
sleep 1
DISPLAY=":0.0"
HOME=/home/rizumu/
XAUTHORITY=$HOME/.Xauthority
export DISPLAY XAUTHORITY HOME
daskb_id=`xinput -list | grep -i 'daskeyboard' | grep -o id=[0-9]. | grep -o [0-9]. | head -1`
xset r rate 200 30
setxkbmap -layout colemak
setxkbmap -option ctrl:nocaps
if [ "${daskb_id}" ]; then
setxkbmap -device "${daskb_id}" -option altwin:swap_lalt_lwin
fi
_
ディストリビューションによっては、/ lib/udev/rules.d/64-xorg-xkb.rulesにすでにキーボードのudevルールがある場合があります。 Ubuntuでは、これは/ etc/default/keyboardをインポートします。これには、おおよそ次のようなオプションがあります。
XKBMODEL="pc105"
XKBLAYOUT="us"
XKBVARIANT=""
XKBOPTIONS=""
私のセットアップでは、この組み込みルールがカスタムudevルールの後に実行され、設定を上書きしていたことがわかりました。代わりに、/ etc/default/keyboardのXKBOPTIONSを次のように変更しました。
XKBOPTIONS="-option ctrl:nocaps"
「Caps Lock is Control」動作を実現するために、すべてのキーボードで望みました。
udev
とxmodmap
はX11ディスプレイにアクセスできないため、機能しません。実際、udev
はareアクティブなX11ディスプレイがあるかどうかさえ知りません。
GNOMEを実行している場合は、レイアウトの変更を上書きしないように、キーボード管理プラグインを無効にする必要があります。
gconftool-2 --toggle /apps/gnome_settings_daemon/plugins/keyboard/active
同じコマンドを再度実行して、必要に応じて有効にします。
X.Org構成についてはどうですか? From Gentoo Wiki:X.Org/Input_drivers-udev :
例:スイスのフランス語圏用のLogitech Accessキーボードをお持ちの場合は、以下を使用できます。
ファイル:/etc/X11/xorg.conf.d/10-keyboard.conf
Section "InputClass"
Identifier "evdev keyboard catchall"
MatchIsKeyboard "on"
MatchDevicePath "/dev/input/event*"
Driver "evdev"
Option "XkbModel" "logiaccess"
Option "XkbLayout" "ch"
Option "XkbVariant" "fr"
EndSection
詳細な説明については、以下をお読みください。
man xorg.conf
そして:
man evdev
ArchWiki は、xorg.confで同じ構文を使用する方法を示しますが、「現在、/ etc/X11/xorg.conf.d/90-keyboard-layouts.confのような個別の構成ファイルを作成する必要があります」 。私はArchを使用し、既存の/etc/X11/xorg.conf.d/vim 10-evdev.confで自分のUSBキーボードを構成しました。
@rizumu:賢いクラッジ、共有してくれてありがとう。
私はこれを構成するはるかにきれいな方法を見つけたと思います、それは特別なX11ハックを必要としません。
これの背後にある考え方は、udev
が新しいキーボード入力を検出して各レイアウトのシンボリックリンクを作成するだけであり、次にinotify
がユーザースペースで新しいレイアウトを監視するというものです。
#/etc/udev/rules.d/61-usb-keyboard-layout.rules
# will match my Logitech keyboard with US layout
SUBSYSTEM=="input", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c31c", GROUP="plugdev", MODE="0660", SYMLINK+="input/by-layout/us"
# will match my Lenovo integrated keyboard with IT layout
SUBSYSTEM=="input", ENV{ID_PATH}=="platform-i8042-serio-0", SYMLINK+="input/by-layout/it"
# force the directory to be recreated, just in case you unplug all input
SUBSYSTEM=="input", RUN="/bin/mkdir -p /dev/input/by-layout"
このルールにより、私はdev(/dev/input/by-layout
)ユーザースペーススクリプトの変更を監視します。
たとえば、KDEを使用する場合、次のスクリプトを(自動)実行します。
#!/bin/bash
# In case no link are found, switch to this layout
DEFAULT="it"
switch_layout () {
[ ! -z "$1" ] || return 0
/usr/bin/qdbus org.kde.keyboard /Layouts org.kde.KeyboardLayouts.setLayout $1
}
best_layout() {
local LAYOUT=$(ls -1t /dev/input/by-layout/ | head -n 1)
if [ -z "$LAYOUT" ] ; then
LAYOUT=$DEFAULT
fi
echo $LAYOUT
}
switch_layout $(best_layout)
while true ; do
EVENT=$(inotifywait -q -e create -e delete --exclude '.*tmp.*' /dev/input/by-layout/)
if echo "$EVENT" | grep -qe CREATE ; then
LAYOUT=${EVENT#?*CREATE }
fi
if echo "$EVENT" | grep -qe DELETE ; then
LAYOUT=$(best_layout)
fi
switch_layout $LAYOUT
done
これは私にとって魅力のように機能します。システムレイアウトを変更するには(今は必要ありません)、loadkeys
を使用する同様のスクリプトをシステム初期化スクリプトを使用して悪用できます。
実行中のディスプレイへのアクセスに関する質問に答えるために、ディスプレイの権限が正しく設定されていると想定して、スクリプト内の適切なDISPLAY変数をエクスポートできます。 (man xset
(表示権限の場合)。
通常、多くの場合、単純にexport DISPLAY=:0
は、シングルユーザーシステムでの最初の表示であるため、コマンド用です。 xmodmapを直接実行するのではなく、スクリプトを直接実行するのがおそらく最も簡単です。これにより、環境変数やその他の変数をより詳細に制御できるようになります。 (したがって、ルール内の「/ usr/bin/xmodmap〜/ .usbXmodmap」を「/usr/local/bin/keyboard_plug.sh」に置き換え、そのスクリプトに適切なコマンドをDISPLAY変数とともに配置します。)
ただし、上記のように、DISPLAY =:0であると想定した場合、複数のユーザーまたはディスプレイがあると、後で問題が発生する可能性があります。適切な表示を検出するスクリプトを書くことができますが、その場合は(この回答に関する限り)自分で行います。 :)
ハックを取得してudevルールを機能させることができなかったので、入力イベントを監視するためにpyudev
を使用して小さなPythonスクリプトを記述しました。
#! /usr/bin/env python3
import pyudev
import time
import subprocess
ctx = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(ctx)
monitor.filter_by("input")
def defer_xmodmap():
time.sleep(1) # not sure if there's a race here, but it feels like there could be.
subprocess.run("xmodmap ~/dotfiles/.xmodmap", Shell=True)
for device in iter(monitor.poll, None):
# there might be a way to add the action condition to the filter, but I couldn't find it
if device.action != "add":
continue
# ensure the KB is initialized -- not sure if this is actually a needed check
if not device.is_initialized:
continue
# my keyboard, from the output of `lsusb`
if not "045E:07A5" in device.device_path:
continue
# it's the keyboard being added.
defer_xmodmap()
次に、このsystemdユーザーユニットファイルを使用して、実行を続けます(systemctl --user enable name_of_service_file
):
[Unit]
Description=udev xmodmap monitor
[Service]
ExecStart=/usr/bin/env python3 %h/local/bin/monitor_kb_udev
Restart=always
RestartSec=10
[Install]
WantedBy=default.target
@ giosh94mhzのinotifywait
ソリューションは少し単純で、pyudev
への依存を回避します。しかし、何らかの理由で、キーボードが接続されてから10〜20秒間inotify
イベントがトリガーされないことがわかりました。