Skip to content

Instantly share code, notes, and snippets.

@tdcosta100
Last active August 13, 2025 13:14
Show Gist options
  • Save tdcosta100/e28636c216515ca88d1f2e7a2e188912 to your computer and use it in GitHub Desktop.
Save tdcosta100/e28636c216515ca88d1f2e7a2e188912 to your computer and use it in GitHub Desktop.
A tutorial to use GUI in WSL2/WSLg replacing original Xorg by Xwayland, allowing WSL to work like native Linux, including login screen

Full desktop shell in WSL2 using WSLg (XWayland)

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.

Installing components

Installing GUI

  1. First you select your favorite desktop environment metapackage. Here is a list of the most common metapackages:

    DistroDesktop EnvironmentMetapackage
    UbuntuBudgieubuntu-budgie-desktop (currently very buggy, I don't recommend using it)
    GNOMEubuntu-desktop
    KDEkubuntu-desktop
    Kylinubuntukylin-desktop
    LXDElubuntu-desktop
    MATEubuntu-mate-desktop
    Studioubuntustudio-desktop
    Unityubuntu-unity-desktop
    Xfcexubuntu-desktop
    Ubuntu/DebianCinnamontask-cinnamon-desktop
    GNOMEtask-gnome-desktop
    GNOME Flashbacktask-gnome-flashback-desktop
    KDE Plasmatask-kde-desktop
    LXDEtask-lxde-desktop
    LXQttask-lxqt-desktop
    MATEtask-mate-desktop
    Xfcetask-xfce-desktop
  2. 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 and xwayland (if not already included as dependency for your metapackage). The installation will take a while, so be patient.

  3. 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
    

Configuring the environment

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

Create and modify services

  1. 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
    
  2. 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
    
  3. Exit the editor saving the changes to the file.

  4. Let's enable wslg-fix.service:

    sudo systemctl enable wslg-fix.service
    
  5. 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]
    
  6. 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.

  1. Exit the editor saving the changes to the file.

  2. 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
    

Replacing default Xorg by XWayland

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.

  1. First, let's backup the original Xorg script.

    sudo mv /usr/bin/Xorg /usr/bin/Xorg.original
    
  2. Then, we create a new Xorg script.

    sudo nano /usr/bin/Xorg.Xwayland
    
  3. 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).

  4. Exit the editor saving the changes.

  5. 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.

Configuring the monitor resolution under GDM and GNOME

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.

  1. First, we create it in the current user directory:

    mkdir ~/.config
    nano ~/.config/monitors.xml
    
  2. 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>
  3. Exit the editor saving the changes to the file.

  4. 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/
    
  5. Finally, we set the correct permissions to the monitors.xml of GDM user:

    sudo chown -R gdm:gdm /var/lib/gdm3/.config/
    
  6. Restart WSL using wsl.exe --shutdown, then reopen your distro terminal.

Running your distro with GUI enabled

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:

  1. sudo nano /etc/gdm3/custom.conf

  2. Uncomment and edit the following lines:

     AutomaticLoginEnable=true
     AutomaticLogin=[your username without the brackets]
    

Shutting down

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.

Troubleshooting

  1. 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.

  2. 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.

  3. Check if Xorg is your default display server, not Xephyr or Wayland. If it's not, you must change it to have Xorg as your default display server.

  4. 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). The Xwayland output will be in the file /var/log/lightdm/x-0.log.

  5. 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.

Sample screenshots

GDM

GDM

LightDM (Kubuntu)

LightDM

GNOME

GNOME

KDE (Kubuntu)

KDE

LXDE (Lubuntu)

LXDE

Xfce (Xubuntu)

Xfce

Contributors

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).

@jason-eu
Copy link

jason-eu commented Aug 1, 2025

I finally got it up and running !

This is what worked for me ๐Ÿ˜„

PowerShell 7.x ;

#After the following command, wait for the install to complete then enter username & password

	wsl --install -d Ubuntu-24.04

WSL ;

	user@device :$ sudo apt update -y && sudo apt upgrade -y && sudo apt install gedit
	user@device :$ sudo apt install gedit
	user@device :$ sudo gedit /etc/wsl.conf

#Confirm the following contents ;

		[boot]
		systemd=true

		[user]
		default=user

exit

WSL ;

#Personally, I didn't need all the packages, but do need some snaps.

	user@device :$ sudo apt-get install --no-install-recommends ubuntu-desktop xwayland && sudo snap install snap-store

exit

WSL ;

	sudo systemctl edit --full --force wslg-fix.service

#Confirm the following ;

		[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

WSL ;

	user@device :$ sudo systemctl enable wslg-fix.service
	user@device :$ sudo systemctl edit [email protected]

#Confirm the following contents ;

		[Service]
		ExecStartPost=-/usr/bin/rm -f /run/user/%i/wayland-0 /run/user/%i/wayland-0.lock

exit

WSL ;

	user@device :$ sudo systemctl set-default multi-user.target
	user@device :$ sudo mv /usr/bin/Xorg /usr/bin/Xorg.original

#Confirm the following contents ;

		#!/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[@]}"

exit

WSL ;

	user@device :$ sudo chmod 0755 /usr/bin/Xorg.Xwayland
	user@device :$ sudo ln -sf Xorg.Xwayland /usr/bin/Xorg


	user@device :$ mkdir ~/.config
	user@device :$ gedit ~/.config/monitors.xml

#Confirm the following contents ;

		<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

WSL ;

	user@device :$ sudo mkdir /var/lib/gdm3/.config
	user@device :$ sudo cp ~/.config/monitors.xml /var/lib/gdm3/.config/
	user@device :$ sudo chown -R gdm:gdm /var/lib/gdm3/.config/

PowerShell 7.x;
PS C:\Users\user> wsl.exe --shutdown

	user@device :$ sudo systemctl start graphical.target
The most important part ๐Ÿ˜… :

SHUTTING DOWN

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 ;

	user@device :$ 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.

@futuremotiondev
Copy link

I went through all the steps and things (mostly) work.

One hiccup was that the display resolution when I opened ubuntu via sudo systemctl start graphical.target. It was automatically set to an astronomical value of ~5000px wide and everything in the UI looked jagged. Once I dropped the resolution via the settings app in ubuntu things are all crisp now.

But currently, in all honestly this setup leaves a lot to be desired.

  • The UI is extremely laggy
  • The refresh rate is locked at 60Hz
  • The 'settings' app won't open half the time (No idea why)
  • Sometimes the scroll wheel isn't recognized

Is there any way to make the Ubuntu/Whatever WSL2 distro run more smoothly? It really feels like there is no GPU acceleration and again the UI is extremely sluggish. I followed all the steps but additionally:

  1. Changed the resolution to my native 4K (3840x2160).
  2. Allocated 18 logical processors to WSL via the WSL Settings app
  3. Allocated 32000MB of RAM for WSL via the WSL Settings app
  4. Allocated a swap size of 40000MB via the WSL Settings app
  5. Updated my video card's drivers to the latest Studio version (RTX 2080TI).

I tried my best to be generous with processor assignment and RAM/swap allocation hoping for a much more responsive experience. But it doesn't seem to have worked.

  • Is there some kind of way to enable more powerful GPU acceleration?
  • Can I safely change the frame rate in the monitors.xml file to something better? (<rate>144.050</rate>)
  • This guide also doesn't seem to make use of tools like VcXsrv / GWSL. Will I get better performance using VcXsrv or GWSL or any other comparable X-Server?

Lastly, I installed a note-taking app on WSL called "Standard Notes", and then ended my graphical WSL session. I then opened windows terminal to a bash prompt and started standard notes (just ran standard-notes).

The UI popped open after a couple of seconds, but the bash shell filled up with errors, many that reference OpenGL. Here's the full log:

libGL error: MESA-LOADER: failed to open swrast (search paths /snap/standard-notes/1116/gnome-platform/usr/lib/x86_64-linux-gnu/dri)
libGL error: failed to load driver: swrast
[1120:0807/201237.964500:ERROR:angle_platform_impl.cc(49)] Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
ERR: Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
[1120:0807/201237.967265:ERROR:gl_display.cc(495)] EGL Driver message (Critical) eglInitialize: Could not create a backing OpenGL context.
[1120:0807/201237.967398:ERROR:gl_display.cc(767)] eglInitialize OpenGL failed with error EGL_NOT_INITIALIZED, trying next display type
[1120:0807/201237.968774:ERROR:angle_platform_impl.cc(49)] Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
ERR: Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
[1120:0807/201237.968873:ERROR:gl_display.cc(495)] EGL Driver message (Critical) eglInitialize: Could not create a backing OpenGL context.
[1120:0807/201237.968973:ERROR:gl_display.cc(767)] eglInitialize OpenGLES failed with error EGL_NOT_INITIALIZED
[1120:0807/201237.969069:ERROR:gl_display.cc(802)] Initialization of all EGL display types failed.
[1120:0807/201237.969172:ERROR:gl_ozone_egl.cc(26)] GLDisplayEGL::Initialize failed.
[1120:0807/201237.973981:ERROR:angle_platform_impl.cc(49)] Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
ERR: Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
[1120:0807/201237.974083:ERROR:gl_display.cc(495)] EGL Driver message (Critical) eglInitialize: Could not create a backing OpenGL context.
[1120:0807/201237.974201:ERROR:gl_display.cc(767)] eglInitialize OpenGL failed with error EGL_NOT_INITIALIZED, trying next display type
[1120:0807/201237.975553:ERROR:angle_platform_impl.cc(49)] Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
ERR: Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
[1120:0807/201237.975652:ERROR:gl_display.cc(495)] EGL Driver message (Critical) eglInitialize: Could not create a backing OpenGL context.
[1120:0807/201237.975749:ERROR:gl_display.cc(767)] eglInitialize OpenGLES failed with error EGL_NOT_INITIALIZED
[1120:0807/201237.975895:ERROR:gl_display.cc(802)] Initialization of all EGL display types failed.
[1120:0807/201237.975993:ERROR:gl_ozone_egl.cc(26)] GLDisplayEGL::Initialize failed.
[1120:0807/201237.984238:ERROR:viz_main_impl.cc(183)] Exiting GPU process due to errors during initialization
libGL error: MESA-LOADER: failed to open swrast (search paths /snap/standard-notes/1116/gnome-platform/usr/lib/x86_64-linux-gnu/dri)
libGL error: failed to load driver: swrast
[1140:0807/201238.035381:ERROR:angle_platform_impl.cc(49)] Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
ERR: Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
[1140:0807/201238.035503:ERROR:gl_display.cc(495)] EGL Driver message (Critical) eglInitialize: Could not create a backing OpenGL context.
[1140:0807/201238.035597:ERROR:gl_display.cc(767)] eglInitialize OpenGL failed with error EGL_NOT_INITIALIZED, trying next display type
[1140:0807/201238.036954:ERROR:angle_platform_impl.cc(49)] Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
ERR: Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
[1140:0807/201238.037064:ERROR:gl_display.cc(495)] EGL Driver message (Critical) eglInitialize: Could not create a backing OpenGL context.
[1140:0807/201238.037163:ERROR:gl_display.cc(767)] eglInitialize OpenGLES failed with error EGL_NOT_INITIALIZED
[1140:0807/201238.037256:ERROR:gl_display.cc(802)] Initialization of all EGL display types failed.
[1140:0807/201238.037354:ERROR:gl_ozone_egl.cc(26)] GLDisplayEGL::Initialize failed.
[1140:0807/201238.041588:ERROR:angle_platform_impl.cc(49)] Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
ERR: Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
[1140:0807/201238.041693:ERROR:gl_display.cc(495)] EGL Driver message (Critical) eglInitialize: Could not create a backing OpenGL context.
[1140:0807/201238.041814:ERROR:gl_display.cc(767)] eglInitialize OpenGL failed with error EGL_NOT_INITIALIZED, trying next display type
[1140:0807/201238.043166:ERROR:angle_platform_impl.cc(49)] Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
ERR: Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
[1140:0807/201238.043266:ERROR:gl_display.cc(495)] EGL Driver message (Critical) eglInitialize: Could not create a backing OpenGL context.
[1140:0807/201238.043361:ERROR:gl_display.cc(767)] eglInitialize OpenGLES failed with error EGL_NOT_INITIALIZED
[1140:0807/201238.043459:ERROR:gl_display.cc(802)] Initialization of all EGL display types failed.
[1140:0807/201238.043578:ERROR:gl_ozone_egl.cc(26)] GLDisplayEGL::Initialize failed.
[1140:0807/201238.044940:ERROR:viz_main_impl.cc(183)] Exiting GPU process due to errors during initialization
libGL error: MESA-LOADER: failed to open swrast (search paths /snap/standard-notes/1116/gnome-platform/usr/lib/x86_64-linux-gnu/dri)
libGL error: failed to load driver: swrast
[1159:0807/201238.386804:ERROR:angle_platform_impl.cc(49)] Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
ERR: Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
[1159:0807/201238.386931:ERROR:gl_display.cc(495)] EGL Driver message (Critical) eglInitialize: Could not create a backing OpenGL context.
[1159:0807/201238.387025:ERROR:gl_display.cc(767)] eglInitialize OpenGL failed with error EGL_NOT_INITIALIZED, trying next display type
[1159:0807/201238.388314:ERROR:angle_platform_impl.cc(49)] Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
ERR: Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
[1159:0807/201238.388414:ERROR:gl_display.cc(495)] EGL Driver message (Critical) eglInitialize: Could not create a backing OpenGL context.
[1159:0807/201238.388515:ERROR:gl_display.cc(767)] eglInitialize OpenGLES failed with error EGL_NOT_INITIALIZED
[1159:0807/201238.388609:ERROR:gl_display.cc(802)] Initialization of all EGL display types failed.
[1159:0807/201238.388699:ERROR:gl_ozone_egl.cc(26)] GLDisplayEGL::Initialize failed.
[1159:0807/201238.393446:ERROR:angle_platform_impl.cc(49)] Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
ERR: Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
[1159:0807/201238.393549:ERROR:gl_display.cc(495)] EGL Driver message (Critical) eglInitialize: Could not create a backing OpenGL context.
[1159:0807/201238.393642:ERROR:gl_display.cc(767)] eglInitialize OpenGL failed with error EGL_NOT_INITIALIZED, trying next display type
[1159:0807/201238.395022:ERROR:angle_platform_impl.cc(49)] Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
ERR: Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
[1159:0807/201238.395125:ERROR:gl_display.cc(495)] EGL Driver message (Critical) eglInitialize: Could not create a backing OpenGL context.
[1159:0807/201238.395225:ERROR:gl_display.cc(767)] eglInitialize OpenGLES failed with error EGL_NOT_INITIALIZED
[1159:0807/201238.395321:ERROR:gl_display.cc(802)] Initialization of all EGL display types failed.
[1159:0807/201238.395414:ERROR:gl_ozone_egl.cc(26)] GLDisplayEGL::Initialize failed.
[1159:0807/201238.396865:ERROR:viz_main_impl.cc(183)] Exiting GPU process due to errors during initialization
extServer: Server started at http://127.0.0.1:45653
libGL error: MESA-LOADER: failed to open swrast (search paths /snap/standard-notes/1116/gnome-platform/usr/lib/x86_64-linux-gnu/dri)
libGL error: failed to load driver: swrast
[1169:0807/201238.439273:ERROR:angle_platform_impl.cc(49)] Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
ERR: Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
[1169:0807/201238.439398:ERROR:gl_display.cc(495)] EGL Driver message (Critical) eglInitialize: Could not create a backing OpenGL context.
[1169:0807/201238.439491:ERROR:gl_display.cc(767)] eglInitialize OpenGL failed with error EGL_NOT_INITIALIZED, trying next display type
[1169:0807/201238.440904:ERROR:angle_platform_impl.cc(49)] Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
ERR: Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
[1169:0807/201238.441009:ERROR:gl_display.cc(495)] EGL Driver message (Critical) eglInitialize: Could not create a backing OpenGL context.
[1169:0807/201238.441109:ERROR:gl_display.cc(767)] eglInitialize OpenGLES failed with error EGL_NOT_INITIALIZED
[1169:0807/201238.441222:ERROR:gl_display.cc(802)] Initialization of all EGL display types failed.
[1169:0807/201238.441369:ERROR:gl_ozone_egl.cc(26)] GLDisplayEGL::Initialize failed.
[1169:0807/201238.446100:ERROR:angle_platform_impl.cc(49)] Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
ERR: Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
[1169:0807/201238.446213:ERROR:gl_display.cc(495)] EGL Driver message (Critical) eglInitialize: Could not create a backing OpenGL context.
[1169:0807/201238.446316:ERROR:gl_display.cc(767)] eglInitialize OpenGL failed with error EGL_NOT_INITIALIZED, trying next display type
[1169:0807/201238.447622:ERROR:angle_platform_impl.cc(49)] Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
ERR: Display.cpp:1085 (initialize): ANGLE Display::initialize error 12289: Could not create a backing OpenGL context.
[1169:0807/201238.447723:ERROR:gl_display.cc(495)] EGL Driver message (Critical) eglInitialize: Could not create a backing OpenGL context.
[1169:0807/201238.447818:ERROR:gl_display.cc(767)] eglInitialize OpenGLES failed with error EGL_NOT_INITIALIZED
[1169:0807/201238.447915:ERROR:gl_display.cc(802)] Initialization of all EGL display types failed.
[1169:0807/201238.448011:ERROR:gl_ozone_egl.cc(26)] GLDisplayEGL::Initialize failed.
[1169:0807/201238.449482:ERROR:viz_main_impl.cc(183)] Exiting GPU process due to errors during initialization
[1163:0807/201239.127307:ERROR:command_buffer_proxy_impl.cc(125)] ContextResult::kTransientFailure: Failed to send GpuControl.CreateCommandBuffer.

All of these OpenGL errors make me think that something is wrong with video acceleration and that I should be seeing better responsiveness.

If anyone here can point me in the right direction with respect to making WSLg more snappy and responsive, I would be really, really appreciative!

Thanks for the guide as well!

@tdcosta100
Copy link
Author

tdcosta100 commented Aug 11, 2025

Hi, @futuremotiondev. I think you are expecting too much of WSLg. The first thing you need to know is every graphic app in WSLg is actually a RDP window to the remote app. This is alone a performance penalty, but there is others. Second, the graphic infrastructure for WSLg is provided by MESA graphic drivers, and maybe your EGL errors are because some environment variables are lacking, or it is pointing to the default GPU, if you have more than one (my laptop has a default Intel GPU and a much powerful nVidia GPU). You can check this with the command glxinfo in output line starting with OpenGL renderer string. Fourth, your GPU driver takes an important role. Some drivers are buggy and makes WSLg apps crash. But usually updating the drivers solves this problem.

For the Settings app better performance, you need to mask some services: fwup.service and ModemManager.service (and optionally wsl-pro.service, because it pollutes the system logs).

@Adhjie
Copy link

Adhjie commented Aug 13, 2025

@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)

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