WSL 2 X Display

As Windows Subsystem for Linux 2 is a separated Virtual Machine on the host Windows Operating System instead of a process it is no longer able to use the same X Windows forwarding over 127.0.0.1 that I was previously available.

Setup X-Windows forwarding

Add the following to your ~/.bashrc file

export DISPLAY=$(awk '/nameserver / {print $2; exit}' /etc/resolv.conf 2>/dev/null):0
export LIBGL_ALWAYS_INDIRECT=1
GDK_SCALE=1

Why?  Read the contents of the file /etc/resolv.conf  use the cat command

cat /etc/resolv.conf

# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false
nameserver 172.28.208.1
  • Extract the ip as it is dynamically assigned by WSL awk '/nameserver / {print $2; exit}' /etc/resolv.conf 2>/dev/null
  • Then assign it to the DISPLAY environment variable export DISPLAY=$(awk '/nameserver / {print $2; exit}' /etc/resolv.conf 2>/dev/null):0
  • Make sure to set the following variables as well for rendering styling and size
export LIBGL_ALWAYS_INDIRECT=1
GDK_SCALE=1

The last one is because GDK scaling by default is 200% which can be disconcerting if not changed to match your other windows.

Configure your X Server

In my case I am using X410 and I recommend you do the same if using WSL2 because of its explicit support for Windows OS.

I use it in windows app mode and set it the Allow Public Access option as the source X Windows client is a true Virtual Machine in WSL2, so allow it to forward as a public ip request.

Wrapping it up in practical case

  • Install latest chrome for your distribution.  First line is to download the latest and second is to run the debian package installer (apt) as a local file install
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt install ./google-chrome-stable_current_amd64.deb
  • Start Chrome google-chrome &
  • Launch the Hello World sample app from Rocket (assume you have done the proper Rust setup) ~/Rocket/examples/hello_world$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.10s
     Running `/home/robin/Rocket/target/debug/hello_world`
🔧 Configured for development.
    => address: localhost
    => port: 8000
    => log: normal
    => workers: 16
    => secret key: generated
    => limits: forms = 32KiB
    => keep-alive: 5s
    => tls: disabled
🛰   Mounting /:
    => GET / (hello)
🚀 Rocket has launched from http://localhost:8000
  • Browser
  • WebServer logs
GET / text/html:
    => Matched: GET / (hello)
    => Outcome: Success
    => Response succeeded.
GET /favicon.ico image/webp:
    => Error: No matching routes for GET /favicon.ico image/webp.
    => Warning: Responding with 404 Not Found catcher.
    => Response succeeded.