Wayland/Sway 環境向けの Key Remapper を作った
Wayland/Sway 環境で動作する Key Remapper を作りました。
動機
Wayland/Sway は素晴らしいですが、ネイティブな Wayland 上で動作する Key Remapper が無いのが
つらみでした。
X11 時代は xremap という神ツールがあり、特定のアプリケーション(ブラウザとか)のみに対して Emacs 風のキーバインドを設定していました。 xremap はもう4年以上使っていて、これが無かったら仕事できてないです。まじでありがとうございました。
この特定のアプリケーションでのみ動作させる、というのがポイントで、この点を考慮しなければ下記のようなツールは存在します。
ただ、ターミナルなどそもそも Remap が必要ないアプリケーションにまで設定されると困るので、その辺を解消してくれるものを作りました。
なぜ xremap や keysnail では駄目なのか
今の所 Chromium など XWayland を介して動くソフトウェアでは xremap は動いていますが、将来的に動かなくなるだろうというのと、 Firefox などでも動作させたかったです。
また xremap や keysnail にプルリクを出すことも考えましたが、むずそうなのと、 X11 と Wayland ではキー入力に対する考え方が違うので、新しく自分で作ることにしました。
Wayland のキー入出力モデル
レイヤー的に、Wayland の下にあるので、 Linux の話ですが...
Wayland は X11 よりもコンパクトに設計されていて、キー入力をフックするには Linux カーネルに働きかける必要があります。なので root 権限が必要です。
キーの入力を司っているのは evdev というカーネルで、デバイスは /dev/input/event20 などのファイルとして表現されています。また、 uinput というものを使うと、擬似的にキー入力を再現できます。
Rust で実装しようとして諦めた
勉強がてら Rust で実装しようとしたのですが、むずすぎて諦めましたw
自分の Rust 力が足りなさすぎたというのと、 Python の方が uinput でコンボ入力がハンドルできたので、そちらでやりました。いつか Rust で書き直したい。
インストール
pip で簡単にできます。 root が読み込めるよう、 sudo でインストールします。
sudo pip install wayremap
Run
あとは、下記のようなスクリプトを作り、実行するだけです。
# /opt/wayremap.py
from wayremap.config import WayremapConfig, Binding
from wayremap.main import run
import uinput as k
wayremap_config = WayremapConfig(
# Filter applications which remap will be applied
applications=[
'Chromium',
'Brave-browser',
'Leafpad',
'firefoxdeveloperedition',
],
bindings=[
# Emacs-like key binding
Binding('ctrl.alt.a', [[k.KEY_LEFTCTRL, k.KEY_HOME]]),
Binding('ctrl.alt.e', [[k.KEY_LEFTCTRL, k.KEY_END]]),
Binding('ctrl.alt.h', [[k.KEY_LEFTCTRL, k.KEY_BACKSPACE]]),
Binding('ctrl.f', [[k.KEY_RIGHT]]),
Binding('ctrl.b', [[k.KEY_LEFT]]),
Binding('ctrl.p', [[k.KEY_UP]]),
Binding('ctrl.n', [[k.KEY_DOWN]]),
Binding('ctrl.k',
[[k.KEY_LEFTSHIFT, k.KEY_END], [k.KEY_LEFTCTRL, k.KEY_X]]),
Binding('ctrl.a', [[k.KEY_HOME]]),
Binding('ctrl.e', [[k.KEY_END]]),
Binding('ctrl.y', [[k.KEY_LEFTCTRL, k.KEY_V]]),
Binding('alt.f', [[k.KEY_LEFTCTRL, k.KEY_RIGHT]]),
Binding('alt.b', [[k.KEY_LEFTCTRL, k.KEY_LEFT]]),
Binding('alt.d', [[k.KEY_LEFTCTRL, k.KEY_DELETE]]),
Binding('ctrl.h', [[k.KEY_BACKSPACE]]),
Binding('ctrl.s', [[k.KEY_LEFTCTRL, k.KEY_F]]),
# OSX-like key binding
Binding('alt.a', [[k.KEY_LEFTCTRL, k.KEY_A]]),
Binding('alt.c', [[k.KEY_LEFTCTRL, k.KEY_C]]),
Binding('alt.v', [[k.KEY_LEFTCTRL, k.KEY_V]]),
Binding('alt.x', [[k.KEY_LEFTCTRL, k.KEY_X]]),
# Slack helm!
Binding('alt.x', [[k.KEY_LEFTCTRL, k.KEY_K]]),
])
run(wayremap_config, '/dev/input/event4')
実行:
sudo modprobe uinput
sudo python /opt/wayremap.py
'/dev/input/event4'
は PC によって変わるので、注意してください。
既知のバグ
-
3
is pressed when changing focused window - Key repeating become slow while switching focused windowd
Roadmap
- Enable to run wihtout Sway
- Packaging for Arch Linux, Debian, Fedora, etc.
- Enable to load per-application config.
- Re-write in Rust for better performance.
Discussion