web-dev-qa-db-ja.com

Linuxで特定のキーボードのみのキーを再マップする方法

最近、スワップされた右AltキーとWindowsキーが付属するUnicompキーボードを購入しました。キーボードは、lsusbで次のように識別します。

Bus 003 Device 002: ID 17f6:0822 Unicomp, Inc 

カーネル(つまり、xmodmapベースではない)が右AltキーとWindowsキーを交換する方法があるので、生のキーボード入力を取得しても、すべてのアプリケーションが交換された場所でそれらを認識します(xmodmapでデータを交換してもそれはできません) ?この1つのキーボードだけにそれを設定する方法はありますか?

20
FUZxxl

はい、XKBを使用して可能です。 xmodmapとは異なり、XKBは個々のデバイスのキーを再マップできます。

注:xkbcomp> 1.2.0であることを確認してください

まず、デバイスをリストします:

xinput list

あなたはこのようなものを得るでしょう:

⎡ Virtual core pointer                      id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ Wacom Bamboo Pen Pen stylus               id=11   [slave  pointer  (2)]
⎜   ↳ Wacom Bamboo Pen Finger touch             id=12   [slave  pointer  (2)]
⎜   ↳ Logitech USB-PS/2 Optical Mouse           id=13   [slave  pointer  (2)]
⎜   ↳ Wacom Bamboo Pen Pen eraser               id=14   [slave  pointer  (2)]
⎜   ↳ Wacom Bamboo Pen Finger pad               id=15   [slave  pointer  (2)]
⎜   ↳ GASIA USB KB V11                          id=17   [slave  pointer  (2)]
⎣ Virtual core keyboard                     id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ Power Button                              id=6    [slave  keyboard (3)]
    ↳ Power Button                              id=7    [slave  keyboard (3)]
    ↳ G19 Gaming Keyboard                       id=8    [slave  keyboard (3)]
    ↳ G19 Gaming Keyboard                       id=9    [slave  keyboard (3)]
    ↳ Logitech G19 Gaming Keyboard              id=10   [slave  keyboard (3)]
    ↳ GASIA USB KB V11                          id=16   [slave  keyboard (3)]

デバイスの文字列を特定し、次のシェルスクリプトを編集して、sed行をデバイスの名前に適合するものに変更します。次に、再マッピングが必要なキーを変更します。

例:xevをロードし、再マッピングするキーを押します。それがキーコード84であるとわかったとします。 https://Gist.github.com/zoqaeski/388064 でルックアップ84キー名は<KP5>。次に、置き換えたいキーを検索し(同じリンクで さらに下 )、角かっこ内の内容をコピーします。必要なすべてのキーに対してプロセスを繰り返します。

remote_id=$(
    xinput list |
    sed -n 's/.*GASIA.*id=\([0-9]*\).*keyboard.*/\1/p'
)
[ "$remote_id" ] || exit

# remap the following keys, only for my custom vintage atari joystick connected
# through an old USB keyboard:
#
# keypad 5 -> keypad 6
# . -> keypad 2
# [ -> keypad 8
# left shift -> left control

mkdir -p /tmp/xkb/symbols
# This is a name for the file, it could be anything you
# want. For us, we'll name it "custom". This is important
# later.
#
# The KP_* come from /usr/include/X11/keysymdef.h
# Also note the name, "remote" is there in the stanza
# definition.
cat >/tmp/xkb/symbols/custom <<\EOF

xkb_symbols "remote" {
    key <KP5>  { [ KP_Right, KP_6, U2192, U21D2 ]       };
    key <I129> { [ KP_Down, KP_2, U2193, U21D3 ]       };
    key <AD12> { [ KP_Up, KP_8, U2191, U21D1 ]  };
    key <LFSH> { [ Control_L ]        };
};
EOF

# (1) We list our current definition
# (2) Modify it to have a keyboard mapping using the name
#     we used above, in this case it's the "remote" definition
#     described in the file named "custom" which we specify in
#     this world as "custom(remote)".
# (3) Now we take that as input back into our definition of the
#     keyboard. This includes the file we just made, read in last,
#     so as to override any prior definitions.  Importantly we 
#     need to include the directory of the place we placed the file
#     to be considered when reading things in.
#
# Also notice that we aren't including exactly the 
# directory we specified above. In this case, it will be looking
# for a directory structure similar to /usr/share/X11/xkb
# 
# What we provided was a "symbols" file. That's why above we put
# the file into a "symbols" directory, which is not being included
# below.
setxkbmap -device $remote_id -print \
 | sed 's/\(xkb_symbols.*\)"/\1+custom(remote)"/' \
 | xkbcomp -I/tmp/xkb -i $remote_id -synch - $DISPLAY 2>/dev/null

次に、それを調達します(.xinitrcに追加できます)。すべて完了!これで、キーを押すと、指定したデバイスに対してのみ、目的の出力が生成されます。

編集:最近、何らかの理由で新しい構成がすぐに適用されないことに気付きました。最初にotherキーボードのキーを押してから、変更したキーボードで構成済みのキーをテストする必要があります。これがなぜ起こるのか、おそらく何らかのキャッシュがあるのか​​わかりません。

29
Watcom

Googleからここに来て、質問者が最初に望んでいたことにもっと沿って回答を求めている他の人のために、evdevレベルでイベントを再マップして、変更がすべてのアプリケーションに適用される2つの方法を知っています:

  1. udevは、スキャンコードとキーコード間のマッピングを制御するハードウェアデータベースエントリを変更するためのAPIを提供します。 このArchiWikiページ には手順が含まれており、X11とコンソール入力の両方で機能することを明示的に述べています。

    要点は、デバイスの一致パターンとスキャンコードからキーコードへの再マッピング定義で構成される/etc/udev/hwdb.d/にカスタムエントリを作成し、次にsystemd-hwdb updateを実行してデータベースを再構築し、udevadm triggerを適用することです。再起動せずに。

  2. WaylandがX11のキーボードサブシステムを使用せず、GNOME ShellやWestonのような主要なWaylandコンポジターがUIを実装してlibinputの関連する側面を構成しないことを考えると、誰かが evdevremapkeys という名前のデーモンを書いて、同様に問題を解決しますLogicool G15ゲーミングキーボード用のG15Daemonユーザースペースドライバー。

    (再マップする予定のイベントを飲み込むため、デバイスでリッスンしている他のイベントはそれらを見ることができず、ユーザー空間からカーネルレベルの入力デバイスを作成するためにuinput AP​​Iを介して修正されたイベントを発行します。)

7
ssokolow

@Watcomオプションで成功しなかった人のために、次のように新しいマッピングファイルを入れてください:

xkb_symbols "remote" {
    key <KP5>  { [ KP_Right, KP_6, U2192, U21D2 ]       };
    key <I129> { [ KP_Down, KP_2, U2193, U21D3 ]       };
    key <AD12> { [ KP_Up, KP_8, U2191, U21D1 ]  };
    key <LFSH> { [ Control_L ]        };
};

/ usr/share/X11/xkb/symbols /にrootとして(ubuntu、ディストリビューションによって異なる場合があります)として、ファイル「custom」を呼び出します。 setxkbmap -device <device id> -print | grep xkb_symbolsを使用して現在のレイアウト文字列を要求し、+customを追加します。再配置されたキーと変更されたレイアウト文字列で新しいレイアウトを設定します。

setxkbmap -device <device id> -layout "us+ru:2+us:3+inet(evdev)+capslock(grouplock)+custom"

効果は永続的ではなく、残念ながら他のキーボードが接続されたときにリセットされ、まだそれを修正する方法がわかりませんでした。上記のコマンドを.bashrcに追加して、必要に応じて再起動時にキーを交換することもできます。

0
eviltnan