WSL2 で Sway を動かす(そして自作キーボードレイアウトを飼いならす)
コミュニティのリポジトリ、自宅ネットワーク上のプロキシ、それぞれ自前の証明書ストアを持つ三つのブラウザ、そして時々自分を忘れるエルゴノミクスキーボードレイアウト。
WSL2 上の Sway はおおむね動いた。だが最後の最後で、エルゴノミクスキーボードレイアウトをオンにしたら、何も入力できなくなった——不安にさせる症状の裏にほとんど小さくて馬鹿げた原因が隠れていた一週間の、ふさわしい締めくくりだった。
これは Dell XPS 13 での黒い画面から始まり、音量について嘘をついたステータスバーを経て、暗闇のなかの Fedora アップグレードを寄り道したSway シリーズの第四部。今回はマシンがそもそも Linux ではなかった——Windows で、Sway は WSL2 の中で動いていた。
Sway をとにかく動かす
構築 · WSL2 上の DebianWSL2 で Sway を動かすためのコミュニティリポジトリに従って、新しい Debian のインストールから始めた。git のインストールは unable to locate package で即座に失敗した——パッケージマネージャのキャッシュが空だったのだ。新規インストールで他の何かを入れる前に一度 apt update を実行すると直った。
リポジトリのクローンは server verification failed: certificate signer not trusted で失敗した。原因は HTTPS 通信を検査する、自宅ネットワーク上のプロキシだった。そのプロキシのルート証明書を Windows から書き出し(certmgr.msc → Trusted Root Certification Authorities → Export as Base-64 .CER)、.crt 拡張子で /usr/local/share/ca-certificates/ にコピーし、update-ca-certificates を実行した。
Sway は起動した——形式上は。画面には何も映らなかったが、Windows のタスクバーにはマウスを乗せると奇妙な [WARN:COPY MODE] ラベルを見せる何かが現れていた。見た目だけの、既知の WSLg 表示バグだった:PowerShell から wsl --update、続けて wsl --shutdown、そして再起動すると直った。
その後、キーボードショートカットが一切効かなくなった。Windows が Windows キーを横取りしていると思っていた。実際の原因はもっと単純だった:コピーしてきた Sway の設定ファイルが完全に空で、既定も含めてキーバインドが一つも存在しなかったのだ。Debian の本物の既定設定を /etc/sway/config から ~/.config/sway/config に出発点としてコピーすると、一発で直った。
日常使いにする
構築 · 「動く」から「使える」へSway が実際に動くようになると、ブラウザを皮切りに日常アプリを入れ始めた。同じ証明書の問題が、その後入れたブラウザ一つ一つで独立して戻ってきた。ブラウザは OS の証明書ストアを使わず、自前のストアを持つからだ。Firefox では Settings → Privacy & Security → View Certificates → Authorities → Import から証明書を直接取り込む必要があった。あるいは p11-kit-trust.so をセキュリティデバイスとして読み込ませ、システムストアを自動的に読ませる方法もある。別途入れた Chromium 系ブラウザでは、同じ証明書を certutil -d sql:$HOME/.pki/nssdb(バージョンによっては ~/.local/share/pki/nssdb)で自前の NSS データベースに取り込む必要があった——OS 側の修正はどちらのブラウザもカバーしていなかった。
仕事用の UML 図ツールは真っ灰色の空っぽのウィンドウとして開いた——Java の Swing/AWT アプリが、Sway のような non-reparenting なタイリングウィンドウマネージャの下で正しく描画されない、古くから知られた不具合だ。アプリを起動する前に環境変数 _JAVA_AWT_WM_NONREPARENTING=1 を設定するか、~/.bashrc に恒久的に書いておくと直った。
端末の文字が明らかに小さすぎたが、ラップトップ内蔵の画面だけで、外部モニターでは正常だった。WSLg は、特に Windows の端数のスケーリング設定において、画面ごとの DPI スケーリングを確実には自動検出しない。Sway の設定でその出力用に明示的な倍率を直接指定すること——output WL-1 scale 1.25、出力名は swaymsg -t get_outputs で調べた——で、WSLg が自力では推測できなかった分を補えた。
キーボードレイアウトの顛末
顛末 · 人間工学、二度目最後の課題は人間工学だった:より快適な入力のために、ドイツのエルゴノミクスキーボードレイアウト Neo2 をオンにする。結果は即座に裏目に出た——何も入力できなくなったのだ。Neo2 は古い X11 アプリが想定するよりはるかに多くのシフト段と修飾キーの組み合わせを使うため、基本的な入力自体が壊れてしまう。キーボードに触れずに復旧した:マウスで端末に右クリック貼り付けし、swaymsg input "type:keyboard" xkb_variant "" を実行して、即座に普通のドイツ語配列に戻した。
完全な Neo2 ではなくハイブリッドに落ち着いた:Neo2 のエルゴノミクスな文字配置だけを使い、数字、句読点、AltGr 記号は標準ドイツ語配列のまま完全に残す。レイアウトを記憶から推測するのではなく、すでにインストールされているキーボードデータベース(/usr/share/X11/xkb/symbols/de の neo_base セクション)から本物の Neo2 定義を直接読み取るスクリプトで作り、正確な一致を保証した。
二つのレイアウトを切り替えるはずのショートカットが、黙って何もしなかった。xkbcli compile-keymap --verbose で実際の原因を見つける前に、いくつもの誤った手がかりを追いかけた——重複したキー割り当て、隠れた Windows 形式の改行、フォーカスに関する思い込み。最終的にわかったのは、コンポジタのキーボードライブラリが、ドキュメントが示唆するようにはカスタムレイアウト用の ~/.config/xkb をそもそも探していなかったことだった。xkbcli compile-keymap --include ~/.config/xkb --include-defaults --layout de,mylayout > ~/.config/xkb/mykeymap.xkb で完成したキーマップファイルを事前にコンパイルし、レイアウトをその場で解決させる代わりに、入力設定の xkb_file で Sway に直接そのファイルを指させると直った。
文字だけのバージョンを作ったことで、同じキーに乗っていた AltGr の特殊文字——@ など——が静かに壊れていた。キーのシンボルリストの一部を上書きすると、指定した段だけでなく、すべての段を含むリスト全体が置き換わってしまうのだ。解決策は、独自レイアウトを生成する際に、各キーについて標準ドイツ語配列から AltGr 段(3段目以降)のシンボルを取り出し、最初の二段だけを残すのではなく、新しい Neo2 の文字の後ろに追加することだった。
そこまでやっても、フォーカスが別のウィンドウに切り替わるたびに、独自レイアウトは静かに標準ドイツ語配列へ戻ってしまった。本当の原因:WSLg の RDP ベースのキーボードブリッジが、フォーカスが変わるたびに Windows 自身の入力言語からアクティブなレイアウトを再同期しており、Linux のキーマップの中にしか存在しないレイアウトという概念をそもそも持っていない——Linux 側からは直しようのない、本物の、いまだ未解決の WSLg プラットフォームの限界だった。

回避策は、リセット自体を防ごうとするのではなく、ウィンドウを切り替えたあとに独自レイアウトのインデックスへ直接戻るキーを割り当てることだった——他ではほとんど使わない Insert を使った。だから実際の日常の動きはこうなる:アプリにフォーカスするために Super+左か Super+右、レイアウトを戻すために Insert、それから入力する。きれいな一回の切り替えを望んでいた場所に三回のキー操作。それでも惜しくないキーだし、最初から欲しかったハイブリッドレイアウトで、いま入力できている——ただ小さな儀式が一つ増えただけだ。
時に、キーボードへ戻る唯一の道はマウスだ。