Skip to content

Instantly share code, notes, and snippets.

@tdcosta100
Last active May 11, 2026 18:07
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

@Timbo303
Copy link
Copy Markdown

Timbo303 commented Jun 1, 2025

@Timbo303 Did you try the Weston on Weston approach? Since WSLg uses Weston as a Wayland compositor you can run another Weston window where you can launch Waydroid. You won't need the full Ubuntu desktop and sounds works inside the Weston desktop shell.

I made a quick guide here https://gist.github.com/onomatopellan/c5220c0efddaff69aaff77cca80b7b8e

I tried to follow your instructions. However weston doesn't start up for some reason giving me this error:

Date: 2025-06-01 CDT
[18:39:48.518] weston 14.0.1
https://wayland.freedesktop.org
Bug reports to: https://gitlab.freedesktop.org/wayland/weston/issues/
Build: 14.0.1
[18:39:48.518] Command line: weston
[18:39:48.518] OS: Linux, 6.6.87.1-microsoft-standard-WSL2+, #1 SMP PREEMPT_DYNAMIC Sun Jun 1 17:19:51 CDT 2025, x86_64
[18:39:48.518] Flight recorder: enabled
[18:39:48.518] Starting with no config file.
[18:39:48.519] Output repaint window is 7 ms maximum.
[18:39:48.519] Loading module '/usr/lib/x86_64-linux-gnu/libweston-14/wayland-backend.so'
[18:39:48.523] Error: Failed to connect to parent Wayland compositor: No such file or directory
display option: (none), WAYLAND_DISPLAY=wayland-0
[18:39:48.523] fatal: failed to create compositor backend

@onomatopellan
Copy link
Copy Markdown

@Timbo303 Since this is somewhat off-topic let's continue in my gist.

@lingmingxi
Copy link
Copy Markdown

You're an absolute legend! I spent the whole morning digging through outdated guides that had me downloading a bunch of random packages and using old setup methods. Then I found your solution—fresh, clean, and exactly what I needed. Seriously, you're a genius! If my comment takes up space, feel free to remove it. Just had to say, you're amazing!

@VArterJr
Copy link
Copy Markdown

VArterJr commented Oct 7, 2025

Any chance of getting a delta description for kubuntu? I tried your other xwayland instructions, but nothing ever launches. This one works great, but I'm not a fan of Gnome.

@PuNkYsHuNgRy
Copy link
Copy Markdown

Can you add instructions for Cinnamon? I've tried all three and this is the only one I can get working.

@kimmydotzip
Copy link
Copy Markdown

For Gnome 49 (standard now with Ubuntu 25.10 / Questing Quokka):

  1. use --devkit instead of --nested in /etc/systemd/user/org.gnome.Shell@wayland.service.d/override.conf
  2. install the devkit binary: sudo apt install mutter-dev-bin

@PuNkYsHuNgRy
Copy link
Copy Markdown

For Gnome 49 (standard now with Ubuntu 25.10 / Questing Quokka):

  1. use --devkit instead of --nested in /etc/systemd/user/org.gnome.Shell@wayland.service.d/override.conf
  2. install the devkit binary: sudo apt install mutter-dev-bin

I'll try this out, thanks so much!

@bakamake
Copy link
Copy Markdown

bakamake commented Nov 9, 2025

image I do it ,it work ,but every gui app can't use network env in gnome-session and gnome setting can config network in gnome-session . like this image

@junghanChoi
Copy link
Copy Markdown

I configured ubuntu desktop, wayland on WSL2, win11.

@teedevtech
Copy link
Copy Markdown

Is this possible for alma or rocky?

@lingmingxi
Copy link
Copy Markdown

image image IN ubuntu25.10(wsl 2.6.2.0) ,GDM、GNOME、NIRI are runing

@linghengqian
Copy link
Copy Markdown

For wslg-fix.service in Ubuntu 24.04, it seems that it can be simplified to?

[Unit]
After=wslg.service

[Service]
Type=oneshot
ExecStart=-/usr/bin/umount /tmp/.X11-unix
ExecStart=/usr/bin/rm -rf /tmp/.X11-unix
ExecStart=/usr/bin/mkdir -m 1777 /tmp/.X11-unix
ExecStart=/usr/bin/ln -s /mnt/wslg/.X11-unix/X0 /tmp/.X11-unix/X0
ExecStart=/usr/bin/chmod 0666 /mnt/wslg/runtime-dir/wayland-0.lock

[Install]
WantedBy=multi-user.target

@linghengqian
Copy link
Copy Markdown

For wslg-fix.service in Ubuntu 24.04, it seems that it can be simplified to?

  • As an explanation, I believe there is a problem with the current script for wslg-fix.service. The current modification to wslg-fix.service results in an error log indicating that the AMD iGPU cannot be found when using journalctl -b --no-pager > ~/journalctl.txt. This ultimately prevented GNOME from starting.
kernel: misc dxg: dxgk: dxgkio_query_adapter_info: Ioctl failed: -22
  1. Execute the following command in the Ubuntu login shell:
sudo apt update && sudo apt upgrade --assume-yes
sudo apt install --assume-yes ubuntu-desktop
sudo snap install snap-store

sudo SYSTEMD_EDITOR=tee systemctl edit --full --force wslg-fix.service <<'EOF' 
[Unit]
After=wslg.service

[Service]
Type=oneshot
ExecStart=-/usr/bin/umount /tmp/.X11-unix
ExecStart=/usr/bin/rm -rf /tmp/.X11-unix
ExecStart=/usr/bin/mkdir --mode=1777 /tmp/.X11-unix
ExecStart=/usr/bin/ln --symbolic /mnt/wslg/.X11-unix/X0 /tmp/.X11-unix/X0
ExecStart=/usr/bin/chmod 0666 /mnt/wslg/runtime-dir/wayland-0.lock

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl enable wslg-fix.service
sudo mkdir /etc/systemd/user/org.gnome.Shell@wayland.service.d/

sudo tee /etc/systemd/user/org.gnome.Shell@wayland.service.d/override.conf <<EOF
[Service]
ExecStart=
ExecStart=/usr/bin/gnome-shell --nested
EOF
  1. In PowerShell 7, execute wsl --terminate Ubuntu-24.04.
  2. To start GNOME, execute the following command in the Ubuntu login shell.
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
  • image
  • This does involve a lot of issues and PRs on gitlab.freedesktop.org, github.com, and gitlab.gnome.org, which I'm investigating elsewhere.🤣

@ToraxOutlaw
Copy link
Copy Markdown

Is there anyway to automate the loading of the GNOME desktop without having to enter the command everytime I open the Ubuntu icon from windows?

@phil-gg
Copy link
Copy Markdown

phil-gg commented Feb 23, 2026

Hi @tdcosta100, thank you for publishing your gist; it helped me understand how to nest {WSLg > Weston > KDE Plasma 6} in a usable manner, on top of the default Debian Trixie WSL2 distribution.

For those who want to try my "Plow" session ([KDE] P̳l̳asma o̳n W̳SLg), please see this GitHub project. If you want to give feedback on my project (at least while the initial v0.1 Release is latest), please use this discussion thread.

@debashish-ghosh
Copy link
Copy Markdown

I tried this on Ubuntu-26.04 WSL2. Nothing happened :(
Running the last command gave me this:

** Message: 22:32:58.896: Starting GNOME session target: gnome-session@ubuntu.target

@mwsealey
Copy link
Copy Markdown

mwsealey commented May 11, 2026

Doesn't work on Ubuntu-26.04, partially because GNOME 49 removed --nested so the override.conf is starting gnome-shell with an invalid parameter. However installing mutter-dev-bin and using --devkit does not work, either. I get errors like:

2026-05-11T11:14:25.329106-05:00 ???????? systemd[643]: Reached target gnome-session-manager.target - GNOME Session Manager is ready.
2026-05-11T11:14:25.330433-05:00 ???????? systemd[643]: Starting org.gnome.Shell@ubuntu.service - GNOME Shell...
2026-05-11T11:14:25.403560-05:00 ???????? gnome-shell[34885]: Running GNOME Shell (using mutter 50.1) as a Wayland display server
2026-05-11T11:14:25.411050-05:00 ???????? gnome-shell[34885]: Failed to setup: Failed to find any matching session
2026-05-11T11:15:49.029706-05:00 ???????? systemd[643]: org.gnome.Shell@ubuntu.service: Failed with result 'protocol'.
2026-05-11T11:15:49.030337-05:00 ???????? systemd[643]: Failed to start org.gnome.Shell@ubuntu.service - GNOME Shell.

Running gnome-shell --devkit directly (as in 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-shell --devkit) gives me some output like this:


(gnome-shell:11204): libmutter-WARNING **: 11:52:40.728: Unknown experimental feature 'scale-monitor-framebuffer'

(gnome-shell:11204): libmutter-WARNING **: 11:52:40.728: Unknown experimental feature 'xwayland-native-scaling'
libmutter-Message: 11:52:40.775: Created surfaceless renderer without GPU
libmutter-Message: 11:52:40.853: Using public X11 display :1, (using unix:/tmp/.X11-unix/X2 for managed services)

(gnome-shell:11204): libmutter-WARNING **: 11:52:40.853: WL: unable to lock lockfile /run/user/1000/wayland-0.lock, maybe another compositor is running

libmutter-Message: 11:52:40.863: Using Wayland display name 'wayland-1'
Xwayland glamor: GBM Wayland interfaces not available
Failed to initialize glamor, falling back to sw
GNOME Shell-Message: 11:52:41.258: Unset XDG_SESSION_ID, getCurrentSessionProxy() called outside a user session. Asking logind directly.
GNOME Shell-Message: 11:52:41.368: Failed to create file /run/user/1000/gnome-shell-disable-extensions: Error opening file “/run/user/1000/gnome-shell-disable-extensions”: File exists
GNOME Shell-Message: 11:52:41.368: Registering session with GDM
GNOME Shell-Message: 11:52:41.386: Error registering session with GDM: GDBus.Error:org.freedesktop.DBus.Error.AccessDenied: No display available
GNOME Shell-Message: 11:52:41.415: Will monitor session null

(gnome-shell:11204): GNOME Shell-CRITICAL **: 11:52:41.417: Could not get proxy for session null: Error: Argument string may not be null

[there's some nasty error backtrace here about the null argument]

GNOME Shell-Message: 11:54:37.976: Failed to register AuthenticationAgent
libEGL warning: DRI3 error: Could not get DRI3 device
libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering

GNOME Shell-Message: 11:55:02.699: Error connecting to the screencast service

[there's a >30 second wait here]

(mutter-devkit:12036): Gdk-WARNING **: 11:55:02.886: Cannot get portal org.freedesktop.host.portal.Registry version: Timeout was reached

[there's a >30 second wait here]

(mutter-devkit:12036): Gdk-WARNING **: 11:55:27.914: Cannot get portal org.freedesktop.portal.Settings version: Timeout was reached

[wow, 3 minute wait...]

(mutter-devkit:12036): Gdk-WARNING **: 11:55:44.545: Cannot get portal org.freedesktop.portal.Inhibit version: GDBus.Error:org.freedesktop.DBus.Error.TimedOut: Failed to activate service 'org.freedesktop.portal.Desktop': timed out (service_start_timeout=120000ms)

.. and you wait about 30 seconds more and you get this:

GNOME Shell-Message: 11:56:10.097: GNOME Shell started at Mon May 11 2026 11:54:37 GMT-0500 (Central Daylight Time)
GNOME Shell-Message: 11:56:10.098: Registering display with GDM
GNOME Shell-Message: 11:56:10.210: Error registering display with GDM: GDBus.Error:org.freedesktop.DBus.Error.AccessDenied: No display available
GNOME Shell-Message: 11:56:10.212: Launching DING process
The XKEYBOARD keymap compiler (xkbcomp) reports:
> Warning:          Unsupported maximum keycode 708, clipping.
>                   X11 cannot support keycodes above 255.
> Warning:          Virtual modifier Hyper multiply defined
>                   Using 0, ignoring 0
> Warning:          Virtual modifier ScrollLock multiply defined
>                   Using 0, ignoring 0
Errors from xkbcomp are not fatal to the X server
GNOME Shell-Message: 11:56:13.243: Launching DING process (x1000000)

The desktop is up at this point, however it's spinning.. seevral minutes later the Home icon appears on the desktop. Starting anything from the panel just spins again for several minutes, if you start it from the terminal you get the same 3 timeout messages so as long as you can wait for 5 minutes to start every GUI application it is great 👍

Don't know where to go from here. xdg-desktop-portal.service and dbus.service are flagging all sorts of errors. Starting gnome-session sure doesn't do anything here with the setup, but something's working.

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