Skip to content

Instantly share code, notes, and snippets.

@tdcosta100
Last active September 21, 2026 05:25
Show Gist options
  • Select an option

  • Save tdcosta100/7def60bccc8ae32cf9cacb41064b1c0f to your computer and use it in GitHub Desktop.

Select an option

Save tdcosta100/7def60bccc8ae32cf9cacb41064b1c0f to your computer and use it in GitHub Desktop.
Using full desktop shell in WSL2 using WSLg (Wayland)

Full desktop shell in WSL2 using WSLg (Wayland)

Note

If you want a more complete experience and already tried the Xvnc tutorial, maybe you should try the WSLg (Xwayland) instead.

Warning

This is a work in progress tutorial. Things done here may break existing functionality, so be careful!

In this tutorial, we will install and use a full GNOME Desktop environment in WSL2, without any external software. The only requirement is a working WSLg installation. At the moment, the instructions are only for Ubuntu (20.04, 22.04 and 24.04) distros and GNOME, but you can request me to test other distros and desktop environments.

Current limitations

  • No fullscreen support
  • No complete desktop support (with Display Manager)
  • No support to clipboard (copy & paste) from/to Windows

Ubuntu

GNOME

Installing the required packages

  1. Open a Ubuntu (20.04, 22.04 or 24.04) terminal. First of all, we need to make sure everything is up to date.

    sudo apt update
    sudo apt upgrade
    
  2. WSL doesn't install the app store by default, so we can install it manually (or you can skip this step if you don't need it).

    sudo snap install snap-store
    
  3. Now we can install the required packages. This may take a long time, so be patient.

    For Ubuntu 20.04 and Ubuntu 22.04
    sudo apt install ubuntu-desktop acpi-support-
    
    For Ubuntu 24.04
    sudo apt install ubuntu-desktop
    

Important

Note the minus sign (-) after the package acpi-support. This is necessary because it will be installed by default and installing it will render your distro almost unusable (see microsoft/WSL#10059), so we will tell apt to not install it.

Configuring the environment

  1. Now we have everything installed, we must configure some things before using the GNOME Shell. First, we need to deactivate the GDM service, because unfortunately it doesn't work with WSLg yet (at least I didn't figure it out how to make it work).

    sudo systemctl mask gdm.service
    
  2. Now 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
    
  3. Paste the code below in the editor.

    For Ubuntu 20.04 and Ubuntu 22.04
    [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
    
    [Install]
    WantedBy=multi-user.target
    
    For Ubuntu 24.04
    [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
    
  4. Save the file and close the editor. Now we have to enable this service.

    sudo systemctl enable wslg-fix.service
    
  5. The last step is to configure the GNOME Shell to start in nested mode.

    For Ubuntu 20.04
    sudo mkdir /etc/systemd/user/gnome-shell-wayland.service.d/
    sudo nano /etc/systemd/user/gnome-shell-wayland.service.d/override.conf
    
    For Ubuntu 22.04 and Ubuntu 24.04
    sudo mkdir /etc/systemd/user/org.gnome.Shell@wayland.service.d/
    sudo nano /etc/systemd/user/org.gnome.Shell@wayland.service.d/override.conf
    
  6. Paste the code below in the editor.

    [Service]
    ExecStart=
    ExecStart=/usr/bin/gnome-shell --nested
    
  7. Save the file and close the editor. Then close the distro terminal window.

  8. Finally we will shutdown WSL.

    wsl.exe --shutdown
    

    The configuration is complete.

Starting the GNOME Shell

  1. Now open again your distro terminal, then paste the command below.

    DESKTOP_SESSION=ubuntu \
    GDMSESSION=ubuntu \
    GNOME_SHELL_SESSION_MODE=ubuntu \
    GTK_IM_MODULE=ibus \
    GTK_MODULES=gail:atk-bridge \
    IM_CONFIG_CHECK_ENV=1 \
    IM_CONFIG_PHASE=1 \
    QT_ACCESSIBILITY=1 \
    QT_IM_MODULE=ibus \
    XDG_CURRENT_DESKTOP=ubuntu:GNOME \
    XDG_DATA_DIRS=/usr/share/ubuntu:$XDG_DATA_DIRS \
    XDG_SESSION_TYPE=wayland \
    XMODIFIERS=@im=ibus \
    MUTTER_DEBUG_DUMMY_MODE_SPECS=1366x768 \
    gnome-session
    
  2. A GNOME Shell window will appear.

    Ubuntu 20.04

    GNOME Shell on Ubuntu 20.04

    Ubuntu 22.04

    GNOME Shell on Ubuntu 22.04

    Ubuntu 24.04

    GNOME Shell on Ubuntu 24.04

@stwarr

stwarr commented Aug 26, 2026

Copy link
Copy Markdown

dbus-run-session -- gnome-shell --devkit --no-x11

I could get this incantation to display the ubuntu-26.04 desktop, but found that it had some serious drawbacks - there isn't a valid gnome-session associated with the gnome-shell, or a logind context, so anything that requires credentials (eg. such as App Center) is just totally broken.

Full Desktop for Ubuntu-26.04.1 LTS / WSLg

The Ubuntu 26.04 desktop (GNOME 50) is Wayland only and doesn't support X11/Xorg, which is why the instructions for Ubuntu 24.04 don't work. However with a small modification, they can be made to work:

image

Installing the required packages

  1. Open a Ubuntu 26.04 terminal and make sure everything is up to date.
$ sudo apt update
$ sudo apt upgrade
  1. Install the desktop and the snap-store packages (remove the --no-install-recommends option if you want the full-fat desktop experience):
$ sudo apt install --no-install-recommends ubuntu-desktop
$ sudo snap install snap-store
  1. Make sure mutter devkit is installed:
$ sudo apt install mutter-dev-bin

Configuring the environment

  1. Skip all the steps listed in this section above (ie. don't mask the GDM service or create the wslg-fix service). Instead just create a gnome-shell startup override like this:
$ sudo mkdir /etc/systemd/user/org.gnome.Shell@.service.d/
$ sudo nano /etc/systemd/user/org.gnome.Shell@.service.d/override.conf
  1. Paste this code in the editor:
[Service]
ExecStart=
ExecStart=/usr/bin/gnome-shell --devkit --no-x11 --mode=%i
  1. Save the file, close the editor, then close the Ubuntu terminal window completely. Force a WSL restart from a windows/powershell terminal:
> wsl.exe --shutdown

Starting the GNOME Shell

  1. Open a new Ubuntu terminal, and start the desktop:
$ XDG_CURRENT_DESKTOP=ubuntu:GNOME \
  XDG_SESSION_TYPE=wayland \
  gnome-session

Enabling graphics acceleration

Adding GALIUM_DRIVER=d3d12 to the gnome-session startup command may improve the rendering performance and enable some desktop animation effects. However for me it meant that App Center would no longer launch. You can fix this as follows:

  1. Create an App Center override:
$ mkdir -p ~/.local/share/applications
$ cp /var/lib/snapd/desktop/applications/snap-store_snap-store.desktop \
   ~/.local/share/applications/snap-store_snap-store.desktop
$ sed -i 's|^Exec=/snap/bin/snap-store %U|Exec=env -u GALLIUM_DRIVER /snap/bin/snap-store %U|' \
   ~/.local/share/applications/snap-store_snap-store.desktop

Remote Desktop Connections

The gnome-shell override also works if you want instead to display the desktop using GNOME remote desktop functionality. After performing steps 1-6 above, add the following:

  1. Install GNOME remote desktop:
$ sudo apt update
$ sudo apt install gnome-remote-desktop
  1. Generate a TLS certificate and key
$ sudo mkdir -p /etc/gnome-remote-desktop
$ sudo openssl req -x509 -newkey rsa:4096 -nodes \
  -keyout /etc/gnome-remote-desktop/rdp-key.pem \
  -out /etc/gnome-remote-desktop/rdp-cert.pem \
  -days 3650 \
  -subj "/CN=$(hostname)"
  1. Update key permissions:
$ sudo chown gnome-remote-desktop:gnome-remote-desktop /etc/gnome-remote-desktop/rdp-key.pem
$ sudo chmod 600 /etc/gnome-remote-desktop/rdp-key.pem
  1. Configure the RDP backend
$ sudo grdctl --system rdp enable
$ sudo grdctl --system rdp set-port 3390
$ sudo grdctl --system rdp set-tls-cert /etc/gnome-remote-desktop/rdp-cert.pem
$ sudo grdctl --system rdp set-tls-key /etc/gnome-remote-desktop/rdp-key.pem
$ sudo grdctl --system rdp set-credentials $USER
  1. After setting your RDP password at the prompt, check the configuration:
$ sudo grdctl --system status
  1. Close the Ubuntu terminal and force another WSL restart:
> wsl.exe --shutdown
  1. Start a new Ubuntu terminal and check the RDP socket (it should print a line starting with 'LISTEN'):
$ sudo ss -ltnp | grep ':3390'
  1. Connect to Ubuntu instance using the windows remote desktop application, via the computer name localhost:3390. You should get the Ubuntu greeter screen, followed by the desktop once you have entered your RDP password.
image

For reference, my WSL environment is:

> wsl --version
WSL version: 2.7.12.0
Kernel version: 6.18.33.2-2
WSLg version: 1.0.73.2
MSRDC version: 1.2.7214
Direct3D version: 1.611.1-81528511
DXCore version: 10.0.26100.1-240331-1435.ge-release
Windows version: 10.0.26200.9168

Full disclosure - there are a couple of small wrinkles with this approach because of the way WSLg operates:

  • I suggest you start with the lightweight desktop install first, as the full install includes features (such as network selection), that cannot realistically function inside WSL and may make the desktop unstable.

  • The mutter devkit windows appear to have their own sizing rules. They can be resized, but this is not persistent across restarts. They can be maximized to fill the physical windows display, but there doesn't appear to be a way to make them properly full screen.

  • If you use the remote desktop approach, a regular windows RDP window will momentarily appear (correctly sized according to the RD connection rules) but filled completely black, but it will then disappear before the greeter login window is displayed.

  • Again for the remote desktop approach, once the login has completed and main desktop window appears, the greeter window will go black but will not automatically close. You can safely close it manually at this point.

  • If you use Visual Studio Code, it will create and launch in its own WSLg window, rather than staying within the Ubuntu desktop window bounds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment