Cygwin/XでWSL2のXアプリケーションを表示する

Posted on November 1, 2020 by nobiruwa

tl;dr

WSL2の起動スクリプト(manではinitialization file)に以下の設定を追加します。

# Cygwin X Server authentication (requires cygwin's "xhost" package)
CYGWIN_ROOT="/mnt/c/cygwin64"
CYGWIN_XHOST="$CYGWIN_ROOT/bin/xhost.exe"
if [ -f "$CYGWIN_XHOST" ] ; then
    # X configuration
    export DISPLAY=`grep -oP "(?<=nameserver ).+" /etc/resolv.conf`:0.0
    # Avoid the following error:
    # libGL error: No matching fbConfigs or visuals found
    # libGL error: failed to load driver: swrast
    # https://x.cygwin.com/docs/ug/using-glx.html
    export LIBGL_ALWAYS_INDIRECT=1

    # On Windows, set DISPLAY=:0.0
    IP_ADDR=`ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1`
    ${CYGWIN_XHOST} +${IP_ADDR}
fi

背景

LinuxマシンでのEmacsは長らくurxvt + emacs-noxという構成で使っていましたが、emacs-lspをGUIで使いたいと思い、GTK版のEmacsに移行しました。これに合わせるために、X接続をCygwin/Xで実現することにしました。

インターネット上にはVcXsrvで表示する方法については色々と情報があるのですが、ウィンドウサイズが10行分しかない状態で起動するのと突然ウィンドウが落ちるので使用を断念しました。ただVcXsrvに関する情報には、アクセスコントロールを無効にする直接のX描画(つまりSSHのX11 port forwardingを使わない)であれば表示できるとあり、Cygwin/Xの設定の参考にします。

前提条件

上記前提条件のうち、技術的要件は以下の2つです。

ほかの2つは既定の設定であるか、環境に関する決めの問題です。

アイディア

Cygwin側でxhost +とすればアクセスコントロールを無効にできますが、もう少しセキュアな設定にしたいです。xhost +<WSL2のIPアドレス>によってWSL2にのみ許可を与えることにします。

  1. Cygwin側はxhostに与える<WSL2のIPアドレス>を知る必要がある。
  2. WSL2側はDISPLAY環境変数にセットするホスト側のIPアドレスを知る必要がある(ディスプレイ番号は0決め打ちとした)。

WindowsとWSL2との間の仮想ネットワークvEthernet (WSL)はWSL2の起動時になって生成され、それまではWSL2のIPアドレスもホスト側のIPアドレスも決定されません。よって、WSL2の起動後に上記2点の設定ができるようになります。

1についてはWSL2側のip addrの出力の加工で取得できますし、2についてもCan’t use X-Server in WSL 2 #4106で議論されている通り、/etc/resolv.confから取得することができます。またはWSL2の中のX clientから VcXsrv に xauth で接続したいにあるように、<マシン名>.mshome.netをホスト名とすることができます。CygwinのコマンドはWSL2からも実行することができるので、1と2の両方の設定もWSL2の起動スクリプトから行えます。

ここまでを踏まえ、以下の設定(再掲)としました。

# Cygwin X Server authentication (requires cygwin's "xhost" package)
CYGWIN_ROOT="/mnt/c/cygwin64"
CYGWIN_XHOST="$CYGWIN_ROOT/bin/xhost.exe"
if [ -f "$CYGWIN_XHOST" ] ; then
    # X configuration
    export DISPLAY=`grep -oP "(?<=nameserver ).+" /etc/resolv.conf`:0.0
    # Avoid the following error:
    # libGL error: No matching fbConfigs or visuals found
    # libGL error: failed to load driver: swrast
    # https://x.cygwin.com/docs/ug/using-glx.html
    export LIBGL_ALWAYS_INDIRECT=1

    # On Windows, set DISPLAY=:0.0
    IP_ADDR=`ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1`
    ${CYGWIN_XHOST} +${IP_ADDR}
fi

Cygwin/Xの起動ショートカットの設定

OpenGL (GLX) - Cygwin/X User’s GuideのTable 3-1からレンダリングオプションの組み合わせを選択します。

indirecthardware-accelerated renderingの組み合わせを選んだので、ショートカットは以下の内容としました。