安価な赤軸のマクロキーボード、東莞市世興盛電子科技 (MKESPN) のK806 (30fa:1340) をアリエクで2個928円で買ったのでLinuxで使えるようにします。
なおK806は公式ドライバもありますが、Windows向けであるため今回は使わないこととします。また他のマクロキーボードではSayoDevice/Lichifitには公式Webアプリが、ch57xベースのもの(Vendor ID: 0x1189)にはch57x-keyboard-toolがあるようで、お金があるならそちらの方が良い気がします。
が兎にも角にもK806を使えるようにしていきます。まずはキーボードのXデバイスIDを取得して環境変数 $DEVICE_ID に設定します。
vipper36@ubuntu-desk:~$ xinput list | grep INSTANT\ USB\ GAMING | grep keyboard
↳ INSTANT USB GAMING MOUSE Keyboard id=30 [slave keyboard (3)]
vipper36@ubuntu-desk:~$ DEVICE_ID=`xinput list | grep INSTANT\ USB\ GAMING | grep keyboard | grep -o 'id=[0-9]*' | cut -d= -f2`
xevで調べたK806の標準キーコードは 87, 88, 89, 83, 84, 85, 79, 80 とテンキー互換になっているようです。試しに独自のXkbのキーレイアウトを定義しようとしてみましたが何か上手く行かなかったのでちょっと横着します。まずは下で現在K806に使われているキーマップを引っ張ってきます。
xkbcomp -i $DEVICE_ID $DISPLAY k806.xkb
次にk806.xkbの一部を以下のように改変してマクロキーに割り当てます。
key <KP7> { [ XF86Macro7, XF86Macro7 ] };
key <KP8> { [ XF86Macro8, XF86Macro8 ] };
key <KP9> { [ KP_Prior, KP_9 ] };
key <KPSU> {
type= "CTRL+ALT",
symbols[Group1]= [ KP_Subtract, KP_Subtract, KP_Subtract, KP_Subtract, XF86Prev_VMode ]
};
key <KP4> { [ XF86Macro4, XF86Macro4 ] };
key <KP5> { [ XF86Macro5, XF86Macro5 ] };
key <KP6> { [ XF86Macro6, XF86Macro6 ] };
key <KPAD> {
type= "CTRL+ALT",
symbols[Group1]= [ KP_Add, KP_Add, KP_Add, KP_Add, XF86Next_VMode ]
};
key <KP1> { [ XF86Macro1, XF86Macro1 ] };
key <KP2> { [ XF86Macro2, XF86Macro2 ] };
key <KP3> { [ XF86Macro3, XF86Macro3 ] };
key <KP0> { [ KP_Insert, KP_0 ] };
key <KPDL> { [ KP_Delete, KP_Decimal ] };
その次にそれをXkbにセットします。
vipper36@ubuntu-desk:~$ xkbcomp -i $DEVICE_ID k806.xkb $DISPLAY
設定が上手く行ったらそれをデスクトップ起動時に自動設定するようにします。
[Desktop Entry]
Name=K806
GenericName=
Comment=
Exec=sh -c "env DEVICE_ID=$(xinput list | grep 'INSTANT USB GAMING' | grep keyboard | grep -o 'id=[0-9]*' | cut -d= -f2) sh -c '[ -n \\"$DEVICE_ID\\" ] && [ -f ~/k806.xkb ] && xkbcomp -i \\"$DEVICE_ID\\" ~/k806.xkb $DISPLAY'"
Terminal=false
Type=Application
X-GNOME-Autostart-enabled=true
最後にそのマクロキーをショートカットキーに設定します。MATEデスクトップ環境では以下から設定できます。
vipper36@ubuntu-desk:~$ mate-keybinding-properties
…ダメでした。Mateではどうやら0xffffffを超えるキーコードがショートカットに設定できないようです…(XF86Macro1〜XF86Macro8は0x10081290〜0x10081297)。仕方がないのでキーをXF86Macro1〜XF86Macro8ではなくF21〜F28 (0xffd2〜0xffd9) にマップしてお茶を濁します。
これでやっとフォーカスを変更するwmctrl -x -a pluma.Pluma
、wmctrl -x -a mate-terminal.Mate-terminal
、wmctrl -x -a caja.Caja
(ウインドウIDはwmctrl -lx
で取得)や、オーディオ出力先を変更するpactl set-default-sink <シンク名>
(シンク名はpactl list sinks|grep 名前
で取得)などがセットできるようになりました。
…が、何故か上手く行く時と上手く行かない時があります。上手く行く時はテンキーの方が使えなくなるので原因はどうやらkeycodeの衝突のようです。一瞬行き詰まったかと思いましたが、keysymの設定ではなく別のキーコードへとリダイレクトすれば上手く行くようです。具体的にはk806.xkbの一部を以下のように改変しました:
key <KP7> {
symbols[Group1]= [ NoSymbol, NoSymbol ],
actions[Group1] = [RedirectKey(key=<FK16>), RedirectKey(key=<FK16>)] // XF86Launch7
};
key <KP8> {
symbols[Group1]= [ NoSymbol, NoSymbol ],
actions[Group1] = [RedirectKey(key=<FK17>), RedirectKey(key=<FK17>)] // XF86Launch8
};
key <KP9> { [ KP_Prior, KP_9 ] };
key <KPSU> {
type= "CTRL+ALT",
symbols[Group1]= [ KP_Subtract, KP_Subtract, KP_Subtract, KP_Subtract, XF86Prev_VMode ]
};
key <KP4> {
symbols[Group1]= [ NoSymbol, NoSymbol ],
actions[Group1] = [RedirectKey(key=<I211>), RedirectKey(key=<I211>)] // XF86Launch4
};
key <KP5> {
symbols[Group1]= [ NoSymbol, NoSymbol ],
actions[Group1] = [RedirectKey(key=<FK14>), RedirectKey(key=<FK14>)] // XF86Launch5
};
key <KP6> {
symbols[Group1]= [ NoSymbol, NoSymbol ],
actions[Group1] = [RedirectKey(key=<FK15>), RedirectKey(key=<FK15>)] // XF86Launch6
};
key <KPAD> {
type= "CTRL+ALT",
symbols[Group1]= [ KP_Add, KP_Add, KP_Add, KP_Add, XF86Next_VMode ]
};
key <KP1> {
symbols[Group1]= [ NoSymbol, NoSymbol ],
actions[Group1] = [RedirectKey(key=<I156>), RedirectKey(key=<I156>)] // XF86Launch1
};
key <KP2> {
symbols[Group1]= [ NoSymbol, NoSymbol ],
actions[Group1] = [RedirectKey(key=<I157>), RedirectKey(key=<I157>)] // XF86Launch2
};
key <KP3> {
symbols[Group1]= [ NoSymbol, NoSymbol ],
actions[Group1] = [RedirectKey(key=<I210>), RedirectKey(key=<I210>)] // XF86Launch3
};
これでやっとちゃんと動きました。長かった…。
追記
こちらの記事を参考にキーの変換をXよりも下の階層でやってみた。
evdevとxkbのマッピングはここにあるようです: /usr/share/X11/xkb/keycodes/evdev 。
evdev:name:INSTANT USB GAMING MOUSE Keyboard:dmi:bvn*:bvr*:bd*:svn*:pn*
KEYBOARD_KEY_70059=prog1
KEYBOARD_KEY_7005a=prog2
KEYBOARD_KEY_7005b=prog3
KEYBOARD_KEY_7005c=prog4
KEYBOARD_KEY_7005d=f14
KEYBOARD_KEY_7005e=f15
KEYBOARD_KEY_7005f=f16
KEYBOARD_KEY_70060=f17
$ sudo systemd-hwdb update && sudo udevadm trigger
それと音声出力の切り替えもIDが変わると動かなくなるのでこちらにしました:
sh -c "pactl set-default-sink `LANG=C pactl list sinks|grep -o "Name:.*" | grep <名前の一部>| cut -d: -f2`"