Setting Up the Perfect WSL Environment for Routine Use (With GUI and Audio)
So if you are here I’m assuming you have a good reason to use WSL, even as your daily driver. If you’re lookin for one, for me I find the seamless integration with Windows and especially VS Code pretty handy.
This post only shows how to set up GUI and Sound in WSL2, and will be followed by one telling how to achieve the desktop shown above. Instead of the common approach installing an X server on Windows I have used VNC, since I was fed up with the lag and the limitations of the former. For me window animations have been pretty smooth and so has Video playback.
I did this on ArchWSL, but I’ll try to give commands for Ubuntu/Debian-based Distros too (You can share your experience or recommendations in the comments)
GUI
Prerequisites
Firstly we need some important components, for Arch you can install gnome
, and optionally gnome-extra
, or any application suite that you prefer, and for the Debian Based Distros select and install components using tasksel
. LightDM also needs to be installed. We also need the dotnet runtime, which Arch Users can install from the AUR. Ubuntu users need to run the following in the terminal:
wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt update
sudo apt install dotnet-runtime-3.1
Setting up Systemd
WSL2 doesn’t come with Systemd so we need a workaround for that too. I used Subsystemctl on Arch, and Systemd-genie is also a good option. Both of them offer PKGBUILDS for Arch. Here are the instructions for those on Debian for installing the later:
deb_name=`curl -s https://api.github.com/repos/arkane-systems/genie/releases/latest | grep name | grep deb | cut -d '"' -f 4`
wget https://github.com/arkane-systems/genie/releases/latest/download/$deb_name
sudo dpkg -i $deb_name
Setting up VNC
You will need tigervnc-standalone-server
in WSL and a VNC viewer in Windows (I used RealVNC Viewer, and I recommend you do the same, to make following this tutorial easier, but any will suffice). Once done we need to set the VNC passwords for the user and root. If you use a login manager other than LightDM the method will be different. I went with LightDM. You can do this by running vncpasswd
and sudo -H vncpasswd
(for LightDM) in WSL.
Next we need to replace the Xorg script with one that calls Xvnc. Be sure to back up the existing one with sudo mv /usr/bin/Xorg /usr/bin/Xorg_old
and create a new one with sudo nano /usr/bin/Xorg
, pasting the following in it (you can tweak the geometry flag in the third last line to match the resolution you want).
#!/bin/bash
for arg do
shift
case $arg in
# Xvnc doesn't support vtxx argument. So we convert to ttyxx instead
vt*)
set -- "$@" "${arg//vt/tty}"
;;
# -keeptty is not supported at all by Xvnc
-keeptty)
;;
# -novtswitch is not supported at all by Xvnc
-novtswitch)
;;
# other arguments are kept intact
*)
set -- "$@" "$arg"
;;
esac
done
# Here you can change or add options to fit your needs
command=("/usr/bin/Xvnc" "-geometry" "1024x768" "-PasswordFile" "${HOME:-/root}/.vnc/passwd" "$@")
systemd-cat -t /usr/bin/Xorg echo "Starting Xvnc:" "${command[@]}"
exec "${command[@]}"
Remember to mark it as an executable with sudo chmod 0755 /usr/bin/Xorg
.
Starting it up
If you used Subsystemctl use the following commands to start it up
sudo Subsystemctl start
Subsystemctl shell
Otherwise for systemd-genie
genie -i > /dev/null &
genie -s
Also we need to start LightDM and enable it (so we don’t have to repeat this)
sudo systemctl start lightdm.service
sudo systemctl enable lightdm.service
Now you can head over too your VNC viewer, connect to localhost:5900
and enter the password you set for VNC (the second one), and Voila you have your GUI (although its not pretty right now, we’ll do that in another post). You can login to use Gnome (or whatever WM you installed). Also, if you’re colors are messed up you need to change the output quality in your VNC Viewer’s settings.
Sound
Setting up the Windows endpoint
Firstly you need to install pulseaudio on Windows, which you can get here. Extract it somewhere (I chose a new folder in Program Files) and make the following changes:
In etc/pulse/default.pa
change #load-module module-native-protocol-tcp
to load-module module-native-protocol-tcp auth-anonymous=1
in etc/pulse/daemon.conf
change ; exit-idle-time = 20
to exit-idle-time = -1
Setting up the Linux endpoint
Install pulseaudio
on Arch and pulseaudio-utils
on Ubuntu. Add the following line to /etc/profile
: export PULSE_SERVER=tcp:$(grep nameserver /etc/resolv.conf | awk ‘{print $2}’);
. Also, not sure if this is necessary but, for ALSA, install libasound2-plugins
on Ubuntu and add the following to /etc/asound.conf
:
pcm.!default {
type pulse
hint.description "Default Audio Device"
}
ctl.!default {
type pulse
}
And thats it, refresh /etc/profile
, and sound will work.
But if you’re going to use this daily, you can’t possibly go through all this every time. You should able to do this with one command, don’t you think? Here’s how:
Putting it All Together
Changes you might need to make whilst creating the files
- in
/usr/bin/wsound-start
make sure it points to the path where yourpulseaudio.exe
is not mine :) /usr/bin/startWDesktop
includes the commands for starting subsystemctl, make sure to replace them with those for systemd-genie (mentioned above) if needed- Make sure to change the path (in line 4 of
/usr/bin/startWdesktop
) to where you store your exe (for starting the VNC Viewer). - In the ps1 file make sure to use the relevant command for your VNC Viewer.
Creating some files
Create /usr/bin/wsound-start
and add /mnt/c/Program\ Files/pulseaudio/bin/pulseaudio.exe > /dev/null 2>&1 &
Create /usr/bin/startWDesktop
and add the following
wsound-start
sudo subsystemctl start
sleep 2
/mnt/c/Users/waliwaqar/Documents/defender-excluded/startWSLGUI.exe
subsystemctl shell
Allow executing these files by running the following
sudo chmod +x /usr/bin/wsound-start
sudo chmod +x /usr/bin/startWDesktop
Creating a .EXE to Run the Viewer
(you will most probably need to place all this in a folder added as an exception in Windows Defender 😔)
Create a ps1 (PowerShell script file) with the following code:
cd 'C:\Program Files\RealVNC\VNC Viewer\'
.\vncviewer.exe -config C:\Users\waliwaqar\Documents\VNCs\arch-wsl.vnc
and convert it to a .exe (any tool of you’re choice, I downloaded one from here)
And You are now Done. Simply type startWDesktop
in the terminal to get going!
A Few More Points
- I used VNC because X servers (for Windows) are buggy and laggy and limit what you can do (I couldn’t go further than XFCE and the WMs used for ricing)
- This setup holds up pretty nice even with lots of animations and visual tweaks and you can use any Desktop Environment (Deepin is pretty nice) you like. Video Playback is pretty nice too.
- If you liked the looks of the Desktop in the Cover Picture, that is my own, and I have made a tutorial on how to recreate it here.
- While setting this up myself I took help from A tutorial to use GUI in WSL2 replacing original XServer by Xvnc, allowing WSL to work like native Linux, including login screen · GitHub and How to use Rhasspy with Windows Subsystem for Linux (WSL) — Development — Rhasspy Voice Assistant
Adios.