Wayland desktopでキーバインドをOS横断に寄せる設計メモ

Wayland desktopでキーバインドをOS横断に寄せる設計メモ

目的

macOS、Windows、Linux で、アプリ起動、ウィンドウ移動、タイル配置、仮想デスクトップ移動の操作感を近づけたい。 ただし Linux Wayland では、X11 時代のように外部プロセスから任意ウィンドウを横断操作する前提にしていない。

Wayland では compositor が入力とウィンドウ管理の権限境界になる。 このため、キーボードの低レイヤ変換とウィンドウ操作を分ける。

一旦考えた基本方針

  • CapsLock/Ctrl や layer 的なキー変換は keyd に寄せる
  • アプリ起動、ウィンドウ移動、最大化、タイル配置は compositor / window manager 側に寄せる
  • KDE Plasma Wayland では KWin global shortcut と .desktop entry を使う
  • labwc では ~/.config/labwc/rc.xml の native action を使う
  • package install、service enable、設定配置は Ansible などの構成管理に寄せる

keyd は「キーを別のキーとして見せる」層に留める。 アプリ起動やウィンドウ制御まで keyd でやろうとすると、Wayland の compositor 境界を迂回する設計になりやすい。

責務分離

領域Linuxでの担当理由
CapsLockをCtrlにするkeydsession / compositor 非依存にしたい
Hyper風の修飾キーkeyd または keyboard firmware入力層で完結させたい
アプリ起動.desktop entry / compositor shortcutdesktop environment の仕組みに乗せる
ウィンドウのhalf snapKWin / labwc native actionWayland では compositor が正規の管理者
物理ディスプレイ間移動KWin / labwc native actionmonitor layout を compositor が持つ
同一アプリ内のwindow cyclecompositor native action外部プロセスで window list を触らない

KDE Plasma Wayland

KDE Plasma Wayland では、KWin の global shortcut と .desktop entry を中心にする。

確認するもの。

echo "$XDG_CURRENT_DESKTOP"
echo "$XDG_SESSION_TYPE"
command -v kreadconfig6
command -v kwriteconfig6
command -v qdbus6

KWin shortcut は ~/.config/kglobalshortcutsrc に見える。 ただし、単純な file copy だけで即時反映できるとは限らない。 自動化する場合は、まず 1 action だけ kwriteconfig6 で変更し、KWin / Plasma 側の reload と GUI 上の実動作を確認する。

アプリ起動は .desktop entry に寄せると扱いやすい。 shortcut は .desktop entry を起動するだけにし、OS や配布形態による command 名差分は wrapper に閉じ込める。

shortcut
  -> .desktop entry
  -> desktop-launch wrapper
  -> wezterm / wezterm-gui / browser / editor ...

この形にすると、Snap、Flatpak、deb package、AppImage、Web fallback の差分を shortcut から分離できる。

labwc / wlroots

labwc では rc.xml の keybind/action を正本にする。

見る場所。

echo "$XDG_CURRENT_DESKTOP"
echo "$XDG_SESSION_TYPE"
test -f ~/.config/labwc/rc.xml

labwc native action で表現できるものは native action に寄せる。 ydotool のような入力注入ツールは、native action で表現できない操作に限定する。 実機検証では、ydotoold の仮想 device が libinput から keyboard pointer として扱われ、ydotool mousemove --absolute が期待した画面絶対座標 click にならないケースがあった。 Xwayland client だけを対象にする場合は、xdotool / XTest の方が切り分けしやすい場合がある。

例として、次のような操作は labwc 側で持つのが自然である。

  • launcher を開く
  • terminal / browser を起動する
  • active window を左右上下へ half snap する
  • active window を隣接 edge へ移動する
  • fullscreen toggle
  • close
  • window cycle
  • XF86Audio 系の音量操作

既存X11メモとの違い

X11 では wmctrlxdotool で window list を見て、対象 window を前面化・最大化する設計が成立しやすかった。 Wayland では、この前提をそのまま持ち込まない方がよい。

Wayland では次の順に考えてみた。

  1. compositor native shortcut でできるか
  2. desktop environment の .desktop / portal / DBus 経由でできるか
  3. アプリ側の single instance / launch-or-focus 挙動で足りるか
  4. どうしても必要な場合だけ入力注入や補助 daemon を検討する

これにより、セキュリティ境界を崩さず、desktop environment の更新にも追従しやすくなる。

構成管理へ載せるとき

Ansible などで配布する場合、role の責務は小さくする。

  • keyd package を入れる
  • /etc/keyd/default.conf を配置する
  • keyd.service を enable/start する
  • KDE では .desktop entry と wrapper を配置する
  • KWin shortcut の反映は、最初は 1 action だけで検証する
  • labwc では rc.xml template を既存 role へ寄せる

Wayland desktop の shortcut は、ファイルを置けばすぐ効くとは限らない。 自動化時は「配置」と「session が実際に反映したこと」を別々に確認する。

未確定事項

  • KDE Plasma 6 の global shortcut reload の最小手順
  • labwc で同一アプリ内 window cycle をどこまで OS 横断の操作体系に寄せるか
  • Hyper key を keyd で作るか、keyboard firmware 側で作るか
  • アプリ起動 wrapper に focus / maximize まで持たせるか、compositor rule に分けるか