Note
If you want to use Wayland in WSLg in a simpler setup, you can try the WSLg (Wayland) tutorial.
In this tutorial, we will setup GUI in WSL2. No additional software outside WSL (like VcXsrv or GWSL) is required. You will find this tutorial very similar to the one that replaces Xorg with Xvnc. Indeed, it's pretty much the same tutorial, with some few changes.
The key component we need to install is the desktop metapackage you want (GNOME, KDE, Xfce, Budgie, etc), and after that, replace the default Xorg by a script that calls Xwayland instead.
For this setup, I will use Ubuntu 24.04, and install GNOME Desktop. Unfortunately older versions of Ubuntu lack some fundamental things, so we cannot reproduce it in older versions (at least not fully). Since the key components aren't bound to Ubuntu or GNOME, you can use your favorite distro and GUI. Check the Sample screenshots section for examples.
So let's go. First, we need a working WSL2 installation.
Warning
WSLg may not work as expected, since Wayland sockets are disabled for everyone, and not every app can handle this. But if you want to use Wayland apps natively, you can use the command export XDG_RUNTIME_DIR=$HOME/runtime-dir
and then start your WSLg app.
Before going to real business, let's make sure we are updated.
sudo apt update
sudo apt upgrade
You also need to make sure /etc/wsl.conf
have the following lines:
[boot]
systemd=true
If not, create/edit this file, add these lines and restart WSL (for example, using wsl.exe --shutdown
, then reopening the distro terminal).
Now we are ready to go.
-
First you select your favorite desktop environment metapackage. Here is a list of the most common metapackages:
Distro Desktop Environment Metapackage Ubuntu Budgie ubuntu-budgie-desktop
(currently very buggy, I don't recommend using it)GNOME ubuntu-desktop
KDE kubuntu-desktop
Kylin ubuntukylin-desktop
LXDE lubuntu-desktop
MATE ubuntu-mate-desktop
Studio ubuntustudio-desktop
Unity ubuntu-unity-desktop
Xfce xubuntu-desktop
Ubuntu/Debian Cinnamon task-cinnamon-desktop
GNOME task-gnome-desktop
GNOME Flashback task-gnome-flashback-desktop
KDE Plasma task-kde-desktop
LXDE task-lxde-desktop
LXQt task-lxqt-desktop
MATE task-mate-desktop
Xfce task-xfce-desktop
-
Once you have chosen the metapackage, let's install it. For example, if you choose
ubuntu-desktop
, the command will be:sudo apt install ubuntu-desktop xwayland
This will install the
ubuntu-desktop
andxwayland
(if not already included as dependency for your metapackage). The installation will take a while, so be patient. -
If in Ubuntu, you may want to install
snap-store
. If you don't need it, you can skip this step:sudo snap install snap-store
If you are using Debian, you need to configure the locale (this is not needed in Ubuntu):
echo "LANG=en_US.UTF-8" | sudo tee -a /etc/default/locale
-
Now we have everything installed, we need to fix the directory
/tmp/.X11-unix/
, because it's mounted as read-only by default. We will create a new systemd unit:sudo systemctl edit --full --force wslg-fix.service
-
Paste the code below in the editor:
[Service] Type=oneshot ExecStart=-/usr/bin/umount /tmp/.X11-unix ExecStart=/usr/bin/rm -rf /tmp/.X11-unix ExecStart=/usr/bin/mkdir /tmp/.X11-unix ExecStart=/usr/bin/chmod 1777 /tmp/.X11-unix ExecStart=/usr/bin/ln -s /mnt/wslg/.X11-unix/X0 /tmp/.X11-unix/X0 ExecStart=/usr/bin/chmod 0777 /mnt/wslg/runtime-dir ExecStart=/usr/bin/chmod 0666 /mnt/wslg/runtime-dir/wayland-0.lock [Install] WantedBy=multi-user.target
-
Exit the editor saving the changes to the file.
-
Let's enable
wslg-fix.service
:sudo systemctl enable wslg-fix.service
-
We also need to remove all references to Wayland, because if not, some apps (
gnome-terminal
, for example) will open outside the desktop shell. We will edit the[email protected]
service:sudo systemctl edit [email protected]
-
Paste the code below in the editor:
[Service] ExecStartPost=-/usr/bin/rm -f /run/user/%i/wayland-0 /run/user/%i/wayland-0.lock
Warning
Please read the editor instructions about the correct place to position the text cursor before pasting. If you paste the code in the wrong place, it will be discarded.
-
Exit the editor saving the changes to the file.
-
Now we will change the default startup target, because if not, a shell window will appear everytime you start your distro (for example, opening a Terminal of your distro in Windows).
sudo systemctl set-default multi-user.target
By default, the display manager call multiple Xorg
instances, one for each user session, including the login screen, provided by GDM (if you are using the GDM as your display manager, of course). So we will replace Xorg
script by a new version which calls Xwayland
instead the classic Xorg
. This is the real magic we are trying to do.
-
First, let's backup the original
Xorg
script.sudo mv /usr/bin/Xorg /usr/bin/Xorg.original
-
Then, we create a new
Xorg
script.sudo nano /usr/bin/Xorg.Xwayland
-
Paste the code below in the editor:
#!/bin/bash for arg do shift case $arg in # Xwayland doesn't support vtxx argument. So we convert to ttyxx instead vt*) set -- "$@" "${arg//vt/tty}" ;; # -keeptty is not supported at all by Xwayland -keeptty) ;; # -novtswitch is not supported at all by Xwayland -novtswitch) ;; # other arguments are kept intact *) set -- "$@" "$arg" ;; esac done # Check if the runtime dir is present, and create it if not if [ ! -d $HOME/runtime-dir ] then mkdir $HOME/runtime-dir ln -s /mnt/wslg/runtime-dir/wayland-0 /mnt/wslg/runtime-dir/wayland-0.lock $HOME/runtime-dir/ fi # Point the XDG_RUNTIME_DIR variable to $HOME/runtime-dir export XDG_RUNTIME_DIR=$HOME/runtime-dir # Find an available display number for displayNumber in $(seq 1 100) do [ ! -e /tmp/.X11-unix/X$displayNumber ] && break done # Here you can change or add options to fit your needs command=("/usr/bin/Xwayland" ":${displayNumber}" "-geometry" "1920x1080" "-fullscreen" "$@") systemd-cat -t /usr/bin/Xorg echo "Starting Xwayland:" "${command[@]}" exec "${command[@]}"
Please note the resolution of the virtual screen. You can change that to fit your needs (1366x768, 3840x2160, etc).
-
Exit the editor saving the changes.
-
Finally, we set the correct permissions for the file and create a link to it:
sudo chmod 0755 /usr/bin/Xorg.Xwayland sudo ln -sf Xorg.Xwayland /usr/bin/Xorg
Warning
Sometimes, system updates replace Xorg
link with the original version. Just repeat this step if this happens, and Xwayland
will work again as Xorg
replacement.
Currently, one of the annoying things is the resolution of Xwayland. Even with the -geometry
switch, GDM and GNOME don't not respect it. Fortunately, this can be overriden by creating a monitors.xml
file. Let's do it then.
-
First, we create it in the current user directory:
mkdir ~/.config nano ~/.config/monitors.xml
-
Paste the code below in the editor (here it is configured for a 1920x1080 resolution, so change it to reflect your resolution if necessary):
<monitors version="2"> <configuration> <logicalmonitor> <x>0</x> <y>0</y> <scale>1</scale> <primary>yes</primary> <monitor> <monitorspec> <connector>XWAYLAND0</connector> <vendor>unknown</vendor> <product>unknown</product> <serial>unknown</serial> </monitorspec> <mode> <width>1920</width> <height>1080</height> <rate>59.963</rate> </mode> </monitor> </logicalmonitor> </configuration> </monitors>
-
Exit the editor saving the changes to the file.
-
Now let's copy this file to GDM's home directory:
sudo mkdir /var/lib/gdm3/.config sudo cp ~/.config/monitors.xml /var/lib/gdm3/.config/
-
Finally, we set the correct permissions to the monitors.xml of GDM user:
sudo chown -R gdm:gdm /var/lib/gdm3/.config/
-
Restart WSL using
wsl.exe --shutdown
, then reopen your distro terminal.
Now you have everything ready to start. Just do the following command:
sudo systemctl start graphical.target
After a while (usually a few seconds, but it can take more if you don't have a SSD), the login screen must appear.
After logging in, the logged user's desktop must appear. When you log out, the screen will show the login interface again. This applies to GDM (which is the case if you installed Ubuntu Desktop). In GDM, you can change this behavior changing the configuration file like this:
-
sudo nano /etc/gdm3/custom.conf
-
Uncomment and edit the following lines:
AutomaticLoginEnable=true AutomaticLogin=[your username without the brackets]
One important thing is: once you start your WSL instance, you cannot just stop it. You must perform a standard Linux shutdown. You can do one of the alternatives below:
- Power off option on GUI menu
sudo poweroff
After doing that, you can safely shut down your WSL instance, either by wsl.exe --terminate
or wsl.exe --shutdown
. Not doing the shutdown process may cause damage to your WSL instance. So be careful.
-
If it doesn't work at first, try to check your
journalctl
logs:journalctl -b -t /usr/lib/gdm3/gdm-x-session -t /usr/bin/Xorg --no-pager
If you are using Debian, then the command is:
journalctl -b -t /usr/libexec/gdm-x-session -t /usr/bin/Xorg --no-pager
In the output, you must see what command line was generated for
Xwayland
, and which error messages appear. Of course, even if it works correctly, you can check the logs just to see what is happening, or for debugging. -
You must check if the custom
Xorg
script was not replaced by the default version of it. If it was the case, just repeat the steps of Replacing default Xorg by Xwayland section. -
Check if
Xorg
is your default display server, notXephyr
orWayland
. If it's not, you must change it to haveXorg
as your default display server. -
If you are using LightDM, you also need to check logs at
/var/log/lightdm
(you will need to use sudo to cat files in that directory). TheXwayland
output will be in the file/var/log/lightdm/x-0.log
. -
If it still doesn't work, you can try to restart WSL with
wsl.exe --shutdown
(don't forget to save everything that is unsaved before, because WSL will shut down completely), then open your distro terminal again and repeat the steps of section Running your distro with GUI enabled.
Thanks to this guys, whose feedback made this tutorial reach the current level of quality and completeness (and it will be more and more complete as more feedback is given).
@tdcosta100
That's a shame but honestly, this is already good enough from community creation. IDK, what are the effect of WSL going open source mean but I don't think MS look really deep into desktop linux market in WSL, unlike r/linux_gaming , not really a big part of NVIDIA because it's not mainline point of them eg the gpu, but NVIDIA does put commits to support linux. I'm by no means have a statistical data for this but, I think with the current problems from WSL as linux server, it's still a long way for WSL to be desktop linux exp, I think only CUDA has GPU passthrough and that's because both NVIDIA and MS works on it...
e.g, WSL being a linux server option, still has no permanent no-sleep mode, some problems with docker, mainly in networking side, not much choice either setting docker or other softwares linux-only method when the networking bugs that arise could only be fixed if it's using a software that both Ms and the apps in question provide, e.g., docker-desktop bugfix for docker usages in WSL. that's just some of the problems. This is just analysis on Ms side and other softwares that are in WSL and Linux, for this guide, this is already a great effort from community side.
I really don't know how to talk more with the closed source counterparts since the source code is not viewable, so other devs talks at other forums are limited at the release version (I could only read other takes, since I'm not a dev either, tho in language translation, I could help in discussion but not work, no experience yet, but I got enough info to understand it, autodidactically), minus old cases of le aks, e.g., old version of win dows, GT A source code comment video.
I do think the SteamOS as the one of the driving force of linux gaming is nice, even though Steam has license vs owner ship problem, and drm problem vs physical copies, GOG, (ahoy yt channel has some retro or physical copy showcase of gaming history), stopKil lingGames etc. but that's OutOfTopic for this case. pros and cons, this guide is already enough for solution to WSL desktop setup, but without Ms cooperation, this will stays niche, and face problems, the biggest one is GPU passthrough. also the problem of Waydroid when it uses the arm translation layer, it will stay that way until Android of Google, Arm holding, x86 emulator devs, and waydroid cooperate.
Oh yeah, there's also problem of game devs banning people on emulator. so that's a ton of works for linux gaming part, GPU passthrough at the very least and audio support for basic desktop linux, and there are still problems too at linux server level of WSL. (sorry if this gets too long, but these all I think are related since they should be doable in WSL if WSL gets bigger)