web-dev-qa-db-ja.com

USBキーボードに異なるキーボードレイアウトを永続的に割り当てる方法

USBキーボードをラップトップにプラグインすることがよくあり(外部モニタとマウスに加えて、ラップトップをデスクトップコンピュータに仮想的に変換します)、その場合は別のキーボードレイアウトを使用することを好みます。

このUSBキーボードをプラグインするたびに、現在のキーボードレイアウトを手動で変更する必要があります。

そして、可能であれば自動化された方法を使用したいと思います。

Rad の質問への回答 here はいくつかの手がかりを与えますが、スタートアップスクリプトが必要なようですこのタスクでは、USBキーボードのデバイスIDはコンピューターが起動するたびに変化します。

この起動スクリプトには、おそらく最初にコマンドxinput -list | grep "USB Keyboard"と、表示された最初のUSBキーボードID番号を取得する別のコマンドが含まれ、それを最終コマンドで使用して、そのUSBキーボードの選択したレイアウトを以下のように設定します。

setxkbmap -device <NUMBER> -layout <LAYOUT>

16
Sadi

少し調査した結果、解決策が見つかりましたが、他の(おそらくより良い)答えにはまだ心を開いています。

これは、起動スクリプトStartup Applications)に追加できます手動で入力されたusbkbd_layout変数をusbkbdデバイスidsxinput -listで見つかりました:

#!/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 と、 thread へのそれぞれの貢献者のおかげで見つかりました:

USBキーボードをプラグインするだけで、ラップトップのデフォルトのキーボードレイアウト(TR-Q)を維持したまま、自動的に異なる(TR-F)キーボードレイアウトを適用できます!

これを可能にするファイルとその内容は次のとおりです。

/ 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

注:

  1. もちろん、。 "bin"フォルダー内の4つのファイルすべてに、たとえばchmod - 755 /home/sadi/.bin/usb-keyboard-*のようなターミナルコマンドで実装できる必要な権限(読み取り可能および実行可能)が必要です。
  2. USBキーボードを差し込んだ後も同じ(デフォルトの)キーボードレイアウトが使用され、2回目の試行で指定されたレイアウトに切り替わります(おそらくもう少しスリープ時間が必要ですか?)
  3. USBキーボード固有のレイアウトは、ログイン画面では無効です(ログアウト時)。
  4. / homeに別のパーティションを使用する場合、4つのスクリプトをどこかに置くことをお勧めしますルートパーティション、例えば/ usr/local/binそして、それに応じてすべての各ファイルの内容を変更します。udevは、/ homeパーティションがマウントされ、問題が発生します。

このセットアップを異なる要件に適応させるために:

  1. USBキーボードのベンダーと製品IDは、コマンドlsusbの出力に従って変更する必要があります(たとえば、私のlsusb出力には、USBキーボードの場合はBus 001 Device 006: ID 09da:0260 A4 Tech Co., Ltd)。
  2. OWNERおよびすべてのユーザーディレクトリ名を「sadi」から別の名前に変更する必要があります
  3. Usbkbd_idは、正しいデバイスIDを取得するために少し調整が必要な場合があります(たとえば、コマンドxinput -list | grep "USB Keyboard"の出力は、2行を提供します; ↳ USB Keyboard id=14 [slave keyboard (3)]および↳ USB Keyboard id=16 [slave keyboard (3)];は、awk「=」をフィールド区切り文字として使用し、2番目の部分をキャプチャしてから、最初の2桁のみを切り取り、最初の行の値のみを使用します)
  4. Usbkbd_layoutの値は、他の有効な選択肢である可能性があります
15
Sadi

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のUSレイアウトを使用することを保証します(私のラップトップの内部キーボードはドイツ語であり、これも私の主要なレイアウトです)。重要なポイント:

  1. idVendorまたはidProductを使用して、デバイスのlsusbおよびevtestを確認できます
  2. /usr/share/X11/xkb/symbolsの任意のレイアウトを使用できます。有効なレイアウトと有効なバリアントの両方を指定するよう注意してください。
  3. 設定が/lib/udev/rules.d/64-xorg-xkb.rulesで指定されたシステム全体の設定を上書きするには、ファイル名は64より大きい数字で始まる必要があります
  4. Gnome/KDEレイアウト管理が設定を上書きしないことを確認してください。
9
pavel

このソリューションを、bépoTypematrixキーボード(最適化された優れたdvorakのフランス語版)および幅広いシステムコンテキスト(マシンへのルートアクセスがあると仮定)で改善しました。動作するのに必要なファイルは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
2
JP Ayanidès

多くのことをいじった後、これは私が今実行しているものです。興味のある場合は、完全な種類の記事を書いて、リポジトリ内でコードを公開するかもしれません。


次のようなudev用の新しいルールセットを設定します。

 Sudo gedit /etc/udev/rules.d/80-external-keyboard.rules

ルールは、特定のベンダーと製品IDの組み合わせを持つデバイスによって何らかのアクションがトリガーされるたびにシェルスクリプトを呼び出すことになっています。

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変数を設定するときにユーザー名を自分のものに置き換えます(rootはユーザーによって呼び出されないため、ここでは$(whoami)は機能しません)。

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 
1
kleinfreund

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
1
user835020

Xorg構成ファイルで定義することもできます。

このstackexchangeの答えでレイアウトされています: https://superuser.com/a/946575/437492

0
Golar Ramblar