WSL2でX11 GUIがスリープ時に消える
去年の暮に投稿した Windows10 WSL のターミナル事情 記事内で、WSL1 でのシェルに VcXsrv+gnome-terminal を利用すると良いという記事を書きました。 状況はそれから少し変わっていて、
- Windows Terminal がマトモになってきた(明るいテーマで常用するのはまだ難しい…)
- 2020 年 5 月に WSL2 がリリースされ、WSL1 の方法で X11 転送を行うことができなくなった
という感じです。 WSL2 時代の GUI 環境の整え方をメモしておきます。
WSL2+VcXsrv の問題点
WSL1 ではカーネルが共有されていたので localhost
等のネットワーク空間も全てが共有されていたが、WSL2 では基本的にカーネルもネットワーク空間も共有されていません。Windows 上から WSL2 上のポートへのアクセスは localhost:80
等でアクセスできるが、逆の WSL2→Windows の接続には IP アドレスを指定する必要が有ります。
WSL1 では単に VcXsrv を起動して export DISPLAY=:0
するだけで X ウインドウが動作していました。これは localhost
への接続を意味します。
WSL2 では export DISPLAY=172.20.0.1:0
などとする必要があります。IP アドレスは WSL2 側から見える Windows のアドレスを指定する必要があります。
この IP アドレスは、 /etc/resolv.conf
から grep,awk を利用して抽出する事が可能です。 .profile
等で以下のようなシェルを実行すれば、今まで通り VcXsrv を動作させることが可能です。
# .profile
# ref: https://github.com/microsoft/WSL/issues/4106#issuecomment-501885675
export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0
しかし、しばらく使えば今までと状況が異なることが分かると思います。 Windows をスリープすると X11 転送した GUI が消えます。
理由を想像すると簡単で、単に TCP セッションが終了しているのでしょう。Windows と WSL2 上でのドメインソケット等が提供されていない現時点で、直接的にこれを解消するのは難しそうです。
WSL2+Xpra でスリープ後もウインドウを維持
そこで利用したのが、Xpra です。 複数 OS で動作するスクリーン・X11 転送ソフトウェアです。 TCP セッションが切断されても GUI を再接続できるようです。GUI 版の tmux みたいな感じですかね。
リモート側の Linux マシン・ローカル側の Windows マシン、それぞれに Xpra をインストールします。
- Download: https://xpra.org/trac/wiki/Download
- apt:
apt install xpra
リモートの Linux マシンで Xpra サーバを起動します。 追加で DISPLAY 環境変数を指定し、以後起動される GUI アプリケーションの接続先を Xpra サーバに設定します。
xpra start --bind-tcp=0.0.0.0:10000 --daemon=yes :10000
export DISPLAY=:10000
Windows 上の Xpra を起動し、 Connect
メニューより Linux 上で起動した Xpra サーバへ接続します。この時に指定するホスト名は localhost
で構いません。
次にリモートの Linux マシンで、適当な GUI アプリケーションを起動します。
gnome-help
無事起動できました。試しにスリープ状態移行してもウインドウは維持されています。
参考資料
- 「Can’t use X-Server in WSL 2」Issue 内での解決策 https://github.com/microsoft/WSL/issues/4106#issuecomment-501885675
- 「WSL2 X11 programs “disappear”」 https://superuser.com/questions/1474559/wsl2-x11-programs-disappear