Blog Cover

How to use GUI apps in WSL2 (forwarding X server)

Author profile image
Aitor Alonso

Jul 12, 2021

Updated Dec 10, 2021

4 min read

If you have already read some of my WSL related articles, chances are that you are using and/or have discovered the potential of WSL 2. However, you might have experimented problems if tried to launch any graphical application within it.

Nowadays, a third-party app is required to run GUI apps, but Microsoft announced on Build 2020 that adding Linux GUI app native support to WSL is on their roadmap. I currently use VcXsrv Windows X Server for that purpose, and that's the tool I will explain on this post. It's an old open-source tool that updates quite frequently. You can check it on Sourceforge.

Installing and configuring VcXsrv

The first step is to download and run the .exe installer from Sourceforge. On the installation wizard, be sure to check the Disable access control option. This will save us time, avoiding some permission denied errors.

Be sure to disable access control

To be sure that this option is always checked, save the configuration to later launch VcXsrv using that config file.

How to save VcXsrv configuration

Setting permissions in Windows Firewall

Once VcXsrv is installed, we need to set the proper permissions on our firewall. Here, I assume you use the default Windows Firewall, but if you use a custom firewall (like a firewall provided by an antivirus), you may need to configure it manually.

When executing VcXsrv for the first time, a Windows Firewall pop-up should appear. Just be sure to give it permissions on both private and public networks.

Setting permissions in Windows Firewall

If the pop-up doesn't appear, or if you gave it the wrong permissions by mistake, you can just change the permissions manually. To do so, open Windows Security app and go to Firewall & network protection -> Allow an app through firewall and ensure VcXsrv windows x server has both permissions.

Setting the DISPLAY env var

The last step is to set the DISPLAY environment variable on our WSL 2 Linux instance. We need to configure the Windows host's IP address as DISPLAY (where the VcXsrv X server is running). Also, because WSL 2 network changes on every restart, so the Windows host's IP does too, it's needed to dynamically set this value on WSL2 launch.

We can use one of the following statements to dynamically set the DISPLAY env var to the correct value.

export DISPLAY="`grep nameserver /etc/resolv.conf | sed 's/nameserver //'`:0"
export DISPLAY="`sed -n 's/nameserver //p' /etc/resolv.conf`:0"
export DISPLAY=$(ip route|awk '/^default/{print $3}'):0.0

If you run one of the above commands on your Linux terminal, then, you should see and local IP address when reading the var value. Just use whatever of the above that works correctly on your machine.

export DISPLAY=....
echo $DISPLAY # Example working output: 192.168.128.1:0.0

Lastly, to ensure the DISPLAY env var is updated on every restart, we should add the chosen export statement to our ~/.bashrc file (if you are using bash as your command interpreter) or in ~/.zshrc (if using zsh instead).

Testing it out

Let's test it! First, ensure the VcXsrv is running. You can check it by looking at the icons on your task bar. You should be able to see the VcXsrv icon if the server is up and running.

VcXsrv running on the task bar

If you can't see any icon, just start the server by double-clicking on the config file you saved when installing. It will launch VcXsrv server with the configuration on that file. You can open the file with a text editor, if you want to check the configuration inside.

If you have followed all the above steps, you should be able to execute GUI apps within WSL2 already. Let's try with the x11-apps, some very low resources and low dependencies apps made for testing X server configurations.

sudo apt install x11-apps
xeyes
xcalc
GUI apps running on WSL2 Ubuntu

After executing the above commands, you should see two eyes following your mouse. Congratulations! You have successfully configured your WSL2 instance to run GUI apps.

Now what's next? If you want to know how to write code inside WSL with VS Code and run containerized apps using Docker, I wrote about it too.

Troubleshooting

I particularly had an issue trying to use the default 0.0 display as my X server. Indeed, trying to use 0.0 will make the X server to crash on my Windows machine. It took me a few hours to realize, after searching on Google for a while and trying multiple different fixing options.

If you have the same problem, may you can fix it by using the 1.0 display instead. This is how I set the DISPLAY value.

export DISPLAY=$(ip route | awk '/default/ { print $3 }'):1.0

And this is my VcXsrv config.xlaunch config file.

<?xml version="1.0" encoding="UTF-8"?>
<XLaunch WindowMode="MultiWindow" ClientMode="NoClient" LocalClient="False" Display="1" LocalProgram="xcalc" RemoteProgram="xterm" RemotePassword="" PrivateKey="" RemoteHost="" RemoteUser="" XDMCPHost="" XDMCPBroadcast="False" XDMCPIndirect="False" Clipboard="True" ClipboardPrimary="True" ExtraParams="" Wgl="True" DisableAC="True" XDMCPTerminate="False"/>

I hope my article has helped you, or at least, that you have enjoyed reading it. I do this for fun and I don't need money to keep the blog running. However, if you'd like to show your gratitude, you can pay for my next coffee(s) with a one-time donation of just $1.00. Thank you!