====== Windows Subsystem for Linux ======
A Unix-like OS (Linux, BSD, MacOS) is by far the best environment for software development.
If you do not have a real Unix-like OS then you almost certainly have Windows.
Several options exist to obtain a Unix-like environment within Windows,
and Windows Subsystem for Linux (WSL) is by far the best of them (with certain reservations [Note 1]).
With version 2 of WSL you can obtain a seamless Unix-like development experience,
including a real Unix desktop.
==== Installing WSL2 ====
Many online guides exist, mostly all saying the same thing.
Pick any of them. e.g: http://https://www.omgubuntu.co.uk/how-to-install-wsl2-on-windows-10
After installation you can choose between several Linux distributions.
Ubuntu is often recommended.
I personally prefer Debian with the xfce4 desktop
and the rest of this document assumes that environment.
==== Installing a desktop ====
{{:misc:desktop.png?direct|Unix desktop}}
Using the Linux desktop offers many advantages over the default WSL command-line experience, including:
* The WSL terminal emulator is severely broken and many Unix text editors do not display correctly in it,
whereas all work perfectly under the Unix terminal emulators that come with the Linux desktop.
* You can have window focus automatically follow the mouse pointer,
without having to click to 'activate' the window under the pointer,
which avoids your developing repetitive strain injury in your clicking finger.
* Emacs and other developer-oriented editors work flawlessly and integrate perfectly with development tools.
* You can run a Web browser on the Linux desktop, making previewing and pasting URLs seamless.
* You can run graphical programs remotely on other Unix-like computers and display them locally.
* Moving and resizing windows can be done using modifier keys and a left-click anywhere in a window,
instead of having to search for and drag the 1-pixel wide border of a Windows window.
Running a Linux desktop on Windows requires two things:
(1) a window server to display the desktop content, and
(2) the desktop window manager and associated applications.
The window server is a native Windows application that displays the Linux desktop in a big Windows window.
The desktop window manager and associated applications are native Linux programs installed in the Linux system.
The two communicate over a network connection, and don't even have to be running on the same computer.
== Installing the X server for Windows ==
Unix-like operating systems use the X11 Window System (often abbreviated X11, or just 'X').
In X the GUI windows are displayed by a //server// running on your local computer,
with any number of //client// programs connecting to that server to display their graphical content.
Several implementations of the X server for Windows are available.
The only one that works completely reliably for me is VcXsrv.
Install it like any other Windows application after downloading it from here:
https://sourceforge.net/projects/vcxsrv
== Installing the desktop for Linux ==
The meta package xfce4 installs everything needed for the Linux desktop.
Start a WSL command line and then install the desktop with the ''apt install'' command like this:
$ sudo apt install xfce4
==== Setting up the desktop environment ====
For the best Linux desktop experience you should start a few services along with the desktop.
I recommend doing this using a script because
(1) the entire desktop can then be started by typing one simple command that runs the script, and
(2) it lets you easily create a clickable Linux desktop launcher that can be pinned to the Windows task bar.
I usually put my own scripts and programs in a directory called ''bin'' directly below my home directory.
$ cd
$ pwd
/home/piumarta
$ mkdir bin
== The bin/startx script ==
In my ''bin'' directory I create a script called ''startx'' that sets up the environment for the X server
and desktop, and then starts them both.
The contents are shown and described below, and you can download the file here:
{{:misc:startx|startx}}
#!/bin/sh
set -e
set -x
exec > /tmp/startx.log 2>&1
export DISPLAY=$(awk '/nameserver / {print $2; exit}' /etc/resolv.conf 2>/dev/null):0
export SHELL=/bin/bash
cd "$HOME"
/mnt/c/Program\ Files/VcXsrv/vcxsrv.exe :0 -ac +bs -dpi auto -dpms r -wgl $OPTIONS &
sleep 1
dbus-launch --exit-with-session "$HOME/.xsession"
The first line says that this file is a shell script.
The two ''set'' commands say to exit at the first sign of trouble and to print each command as it is executed.
The ''exec'' command sends all output, including error messages, to the file
/tmp/startx.log.
The ''DISPLAY'' variable is set so that client programs know how to contact the server,
using the IP address for the Linux session that WSL sets up for us in the
/etc/resolv.conf file.
The ''SHELL'' variable is set to the preferred shell, which is ''bash''.
The ''cd \"$HOME\"'' command makes sure the working directory for the desktop session is your home directory,
so that the behaviour is consistent no matter which directory is current when you run the ''startx'' script.
The next line launches the VcXsrv X server from its location in the Windows filesystem on the C drive.
The options do the following:
* '':0'' is the desktop number to use, with :0 being correct if you only have one desktop;
* ''-ac'' turns off server access control, which is relatively safe because WSL gives your Linux session
a temporary IP address that is unreachable from outside your physical computer;
* ''+bs'' turns on backing store support which makes X window contents display faster;
* ''-dpi auto'' tells the X server to use your physical display's pixel density;
* ''-dpms'' turns off monitor power saving, which is irrelevant when using VcXsrv to display the desktop;
* ''r'' turns on auto-repeat; and
* ''-wgl'' tells the X server to use Windows native OpenGL for hardware accelerated graphics.
The ''sleep'' command pauses for one second to give the X server time to start up.
The final ''dbus-launch'' command starts a software communication service that many Unix programs
and X clients use, and then runs another script called ''.xsession'' in your home directory
to set up and start the Linux desktop window manager.
After creating or downloading the file, make sure it has execute permission:
chmod +x bin/startx
== The .xsession script ==
The file ''.xsession'' (in your home directory) contains a series of commands that set up the desktop environment
and then run the desktop window manager.
The contents are shown and described below, and you can download the file here:
{{:misc:xsession|.xsession}}
#!/bin/bash
test -e .Xauthority || touch .Xauthority
test -e .Xdefaults || touch .Xdefaults
xrdb -merge .Xdefaults &
export RUNLEVEL=3
export OOO_FORCE_DESKTOP=gnome
export LANG="en_US.UTF-8"
export LC_ALL="en_US.UTF-8"
export LANGUAGE="en_US.UTF-8"
export LC_CTYPE="en_US.UTF-8"
xset r rate 200 50
exec startxfce4
The first two lines of ''test'' and ''touch'' commands ensure that the files
''.Xauthority'' (which proves to the X server that you started it) and
''.Xdefaults'' (which contains the initial X resource database)
are present, and creates empty versions of them if necessary.
The ''xrdb'' command loads some default settings for X client programs from the ''.Xdefaults'' file.
The ''RUNLEVEL'' variable is set to tell any program that cares that the WSL session is
just like a normal login session on a physical Linux computer.
The ''OOO'' variable is set to make Libre Office display nicely on the xfce4 desktop.
The four ''LANG*'' and ''LC_*'' variables are set to tell programs to use UTF-8 encoding and English messages.
The ''xset'' command sets the keyboard repeat delay to 200 milliseconds and repeat rate to 50 per second.
(I set auto repeat to be super-fast to make it easy to navigate source code in text editors;
modify these numbers if it is too fast for you.)
After creating or downloading the file, make sure it has execute permission:
chmod +x .xsession
== The .Xdefaults file ==
Settings for X applications are kept in a database, similar to the registry that Windows uses to store settings,
called the //X resource database//.
It is created when the Linux desktop starts.
The ''.xsession'' script above loads your initial X database settings from a file called ''.Xdefaults'' (in your home directory).
I recommend you add some settings to that file to make some important programs work better.
The contents of my ''.Xdefaults'' file are shown and described below, and you can download the file here:
{{:misc:xdefaults|.Xdefaults}}
Emacs.menuBar: 0
Emacs.toolBar: 0
Emacs.verticalScrollBars: off
emacs*Foreground: Wheat
emacs*Background: DarkSlateGray
emacs.pane.menubar.margin: 0
emacs*scrollBarWidth: 12
emacs*cursorColor: #e02020
!
xterm*metaSendsEscape: true
xterm*eightBitInput: true
xterm*saveLines: 2000
xterm*wm_option.autoRaise: on
xterm*wm_option.gadgets: on
xterm*wm_option.title: on
xterm*background: beige
xterm*foreground: black
xterm*colorBDMode: false
xterm*sunFunctionKeys: false
xterm*jumpScroll: true
xterm*scrollBar: false
xterm*charClass: 33:48,37:48,45-47:48,58:48,64:48,126:48
xterm*borderColor: black
xterm.waitforwm: false
xterm*fontMenu.Label: VT Fonts
xterm*fontMenu*fontdefault*Label: Default
xterm*fontMenu*fontdefault: -misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso8859-1
xterm*fontMenu*font1*Label: Unreadable
xterm*VT100*font1: nil2
xterm*fontMenu*font2*Label: Tiny
xterm*VT100*font2: -schumacher-clean-medium-r-normal--8-*-*-*-c-50-*-*
xterm*fontMenu*font3*Label: Small
xterm*VT100*font3: -schumacher-clean-medium-r-normal--10-100-75-75-c-60-iso646.1991-irv
xterm*fontMenu*font4*Label: Medium
xterm*VT100*font4: 9x15
xterm*fontMenu*font5*Label: Large
xterm*VT100*font5: 10x20
xterm*fontMenu*font6*Label: Huge
xterm*VT100*font6: lucidasanstypewriter-bold-24
XTerm.VT100.faceSize1: 6
XTerm.VT100.faceSize2: 8
XTerm.VT100.faceSize3: 10
XTerm.VT100.faceSize4: 14
XTerm.VT100.faceSize5: 20
XTerm.VT100.faceSize6: 28
xterm*fontMenu*fontescape*Label: Escape Sequence
xterm*fontMenu*fontsel*Label: Selection
The first group of settings streamlines the look of ''Emacs'' by removing the scroll bar, menu bar, and tool bar.
They also tell Emacs to use the classic Debian colours that I find pleasant
and relaxing to look at for long periods.
The second set of settings tell the default X terminal emulator ''xterm'' how to handle the ''meta'' key
(so that Emacs-like cursor movement shortcuts work in the terminal too),
what colours to use (again so that they are not tiring to look at for extended periods of use),
which fonts to use for different sized text,
and over which set of characters to extend the selection when double-clicking on text.
== Starting and stopping the desktop ==
You should now be able to open a WSL Debian terminal and type
bin/startx
to start an xfce4 Linux desktop session.
When stopping the session I always like to log out (of the Linux desktop session) first by clicking
either on the 'Applications' menu (top left) or my name (top right) and
selecting 'log out'.
That way I am certain all my window manager settings are properly saved for the next session.
Logging out will not actually stop the X server;
to do that, press the 'close' button on the VcXsrv Windows window and then click on 'Exit'
in the pop-up confirmation dialogue that appears.
==== Making a Windows (task bar or desktop) launcher for the Linux desktop ====
First locate the Windows program that launches your Linux distribution.
This is easy to do using the Windows PowerShell ''get-command'' function.
Start PowerShell and then run this command:
PS C:\Users\piumarta> (get-command debian.exe).path
C:\Users\piumarta\AppData\Local\Microsoft\WindowsApps\debian.exe
Open that file's location in Windows Explorer
PS C:\Users\piumarta> cd .\AppData\Local\Microsoft\WindowsApps
PS C:\Users\piumarta\AppData\Local\Microsoft\WindowsApps> explorer.exe
and then create a desktop shortcut by right-clicking on the ''debian.exe'' file
and selecting 'Send to > Desktop (create shortcut)'.
Right-click on the desktop shortcut that was just created and select 'Properties'.
Activate the 'Shortcut' tab and then edit the 'Target' field
to add the following items after ''debian.exe'':
run /bin/bash -c /home/piumarta/bin/startx
(but, obviously, replace 'piumarta' with your own account name).
Your entire 'Target' field for the shortcut should look something like this
C:\Users\piumarta\AppData\Local\Microsoft\WindowsApps\debian.exe run /bin/bash -c /home/piumarta/bin/startx
(with your account name instead of mine).
Click on ''Apply'' and then ''OK''.
Double-clicking the shortcut (or right-clicking it and selecting ''Open'')
should then start your Linux desktop.
You can drag this shortcut to your task bar,
and on mine I replace the icon with the one embedded in the VcXsrv executable to give the shortcut an
appropriate appearance.
==== Notes ====
- One 'certain reservation' about WSL being the ideal environment is that
you will lose your entire Linux desktop session at random times when Windows unilaterally
decides to reboot your computer overnight, without permission, to install an update that you
probably did not even want. If this is a 'deal breaker' for you then you can either write
a script to 'slide' your 'working hours' forward once an hour (preventing Windows from
ever rebooting without permission) which has its own drawbacks, or adopt the the next best option
as your new best option: install both Windows and a 'real' Linux distribution as
guest operating systems under the same hypervisor, and then use ''x11vnc'' on the Linux
guest to allow Windows to connect to a persistent Linux desktop.
(If you care about 3D performance in Windows you can also 'pass through' your entire GPU
to Windows and obtain native graphics performance.)
The Linux desktop user experience with this option is almost identical to the native WSL2 experience,
with the advantage that Windows rebooting itself will not in any way affect your Linux desktop.
\\\\
I have exactly this setup on my main computer at home, using the
[[https://www.proxmox.com/en/|Proxmox]]
hypervisor, and it works perfectly (including PCI pass-through of my NVIDIA GPU to Windows).
The procedure to set this up is a little more complex than setting up WSL2 and xfce4,
and is definitely beyond the scope of this short how-to.