Skip to content

Launch GUI applications in WSL with Unix Domain Socket

Martin Chloride edited this page May 18, 2019 · 1 revision

TL;DR

Use X-Org on AF_UNIX

  1. Install patched VcXsrv (Windows port of X-Org server) on Windows. Launch it with -listen unix.

  2. Install patched libxcb on WSL.

  3. Create symlink: /tmp/.X11-unix -> /mnt/c/tmp/.X11-unix.

  4. To test, run DISPLAY=unix:0 gnome-terminal in WSL.

Use PulseAudio on AF_UNIX

  1. Install patched PulseAudio server on Windows. Launch it with module module-native-protocol-unix socket=C:\\tmp\\pulse\\pulse.sock auth-anonymous=1.

  2. Install patched libpulse on WSL.

  3. To test, run PULSE_SERVER=/mnt/c/tmp/pulse/pulse.sock paplay -p /mnt/c/Windows/media/ding.wav

Introduction

Running a desktop environment or a GUI application in Windows Subsystem of Linux has not been not a suprise for a long time. In short, for a GUI application on Linux, to show graphics, it connects to a X-Org server through X11 protocol, and to play sounds, it connects to a PulseAudio server. That is how it works on traditional Linux environment, and thanks to its network transparncy, we are able to use the same stack on Windows.

We usually use Unix Domain Socket (AF_UNIX) on Linux to communicate with graphics and audio servers. However, all of the existing solutions to run GUI applications in WSL utilize TCP loopback (TCP connection to 127.0.0.1) instead of Unix Domain Socket.

Windows 10 supports AF_UNIX since 1803, and even better this implementation supports interop between Windows and WSL. Therefore, it is totally possible to let the Windows port of X-Org server and PulseAudio server support Unix Domain Socket. So I did it, and here is the instruction.

Setup servers on Windows

VcXsrv

My patch for X-Org is based on VcXsrv, one of the Windows port of X-Org (I would say it is a fork of XWin, just like others). You can download a compiled release here:

Once it gets installed, you can launch an X-Org server by the following command:

.\vcxsrv.exe -nolisten tcp -listen unix -multiwindow

This will start the server at display port 0. Then you can verify whether it works by right click its icon in the task bar, choose Applications and launch xcalc. You will see a calculatator window if everything works as expected.

Unfortunately you cannot specify the socket path for it, because you are not able to do so neither on Linux. The socket path is hard coded as /tmp/.X11-unix/X# where # is the display port. On Windows this will be converted to C:\tmp\X11-unix\X#.

PulseAudio

You can download a compiled release with my patch here:

There is no installer for it so just unzip it to a place you like. Then you need to modify its launch script to enable Unix Domain Socket. The default launch script is .\etc\default.pa. Alternatively you can copy it to ~\.config\pulse\default.pa. Add the following line in the network access section (you may change the socket path to anywhere you like, but must on NTFS and not in WSL):

load-module module-native-protocol-unix socket=C:\\tmp\\pulse\\pulse.sock auth-anonymous=1

Then you can launch a PulseAudio server by the following command:

.\pulseaudio.exe

To verify your setup, use paplay:

.\paplay -s unix:C:\tmp\pulse\pulse.sock -p C:\Windows\media\ding.wav

You will hear DING if everything works as expected.

Setup clients on WSL

There is not supposed to be patches in WSL. However currently there is a limitation of Unix Domain Socket interop between Windows and WSL: socket() must be followed by bind() or connect(). No other syscalls should be between them. Otherwise the socket will become WSL internal only. So I removed couple of lines in libxcb and libpulse.

libxcb

You can follow the instructions in the release page to install it:

Then you need to create a symlink to point /tmp/.X11-unix to the actual socket path directory in the C drive:

sudo ln -s /mnt/c/tmp/.X11-unix /tmp/

Double check:

ls -l /tmp/.X11-unix

Verification (launch VcXsrv first):

DISPLAY=unix:0 gnome-terminal

libpulse

You can follow the instructions in the release page to install it:

Verification (launch PulseAudio first):

PULSE_SERVER=unix:/mnt/c/tmp/pulse/pulse.sock paplay -p /mnt/c/Windows/media/ding.wav

FAQ

Does Unix Domain Socket perform better than TCP loopback?

  • Likely. I tried to play a YouTube video in 2K resolution on my MacBook Air. The content of the video was roller coaster whose image changed rapidly, so that the throughput of X11 maximized, and I was able to check tearing. I saw about 20% drop of CPU utilization by switching to AF_UNIX. But I need more formal experiment to support this conclusion.

Can I use it in WSL2?

  • No, not now. The first release of WSL2 won't support AF_UNIX interop as I know so far. They might change their mind before release.

I don't trust your binary release

  • Just cherry-pick my feature branch and build by yourself.