Linux on Windows

8 minutes

It’s no secret that I don’t like Windows. I’m not a fan of more or less any of the UX choices and I basically find it a chore to do basically anything in it, or diagnose and fix issues if they go wrong. Window management is horrible, command line support is awful and doing any kind of development work on it is an exercise in exasperation without having to use some fat IDE that tries to provide all the tools you’d want in one place, but inevitably fails to satisfy me and my love of chaining small tools together instead of struggling with the intricacies of a giant program.

Anyway, since my macbook at work has been failing, I got a new work laptop. The plan was to dual boot it with Linux - I was thinking about using Pop!_OS on it (a Dell XPS 15”) but the installer failed to work (random hangs), and messing about with UEFI and Secure Boot seemed to yield no solution, so I gave up and decided I’d try to bend Windows to my will, considering I also need Windows for work (cross-platform dev and testing with game clients).

Fixing Window Management

First thing I tackled was window management. For this, I opted for bug.n, an open source AutoHotkey-based piece of software that does tiling window management. I don’t actually use a tiling window manager under Linux, usually, but it has been something I’ve been meaning to try for some time and frankly anything is better than Windows-native management.

bug.n at first didn’t work at all. In fact, I literally couldn’t even copy the exe file to different folders. As it turned out, Symantec’s anti-virus stuff was interferring with it, but one exclusion rule later and it was fine. Being AutoHotkey-based, naturally it is extremely keyboard driven, which suits me just fine. I had to make a few tweaks to the default configuration, but only to address issues with specific other programs I later added. My bug.n config changes are here.

Since bug.n has no installer or anything, you can dump it anywhere. I wanted it to be able to manage all my windows, so I set it up to run as administrator on login using the Windows Task Scheduler, which has possible one of the worst interfaces of any program I have ever used. Nicely, the bug.n github wiki includes instructions on how to do this.

With window management sorted, it was time to move on to the next phase.

Software repositories

Being used to apt and brew, I was not going to live in the dark ages of unmanaged software installs. So I installed Chocolatey and used it to install everything. I’m not sure bug.n is in Chocolatey because I installed it first manually, but everything else was installed via choco install [appname] in an Admin powershell.


I make heavy usage of a launcher under Linux (kupfer) and used one a lot under OSX (Alfred). I need one that works fairly similarly - at least with the ability to find and run any program I have installed, but hopefully some other useful features.

Windows’ built-in search from the Win-key search is okay. It’s pretty good for running things, but sometimes it struggles to find things, or is just slow. The other downside of the built in one is that it opens this big pinned tile start screen which I don’t really want. I actually liked the Windows 8 tile UI, but I’m not a fan of the Windows 10 version and besides, I’m trying to get rid of Windows-ness as much as possible.

At first I tried Hain. It was nice, but being an always-on electron app, it was a bit hungry on resources and painfully slow. I wanted to install plugins for it and after waiting over 20 minutes for it to updates it’s own plugin registry (for which it has no offline/CLI method for doing so), I got fed up. Instead now I am using Wox, which works pretty fast and actually can install its own plugins. Being able to do Alt+Space and shutdown my laptop, or find and open anything, is pretty useful. I find the result sorting is sub-optimal and feel its fuzzy searches and context-awareness could probably be improved, but so far it works pretty well. One issue I did have was that bug.n would try to manage it, but a config option in bug.n sorted that out (mostly, for some reason it will occasionally decide to become managed and I don’t know why).


Proper terminal support is a must, because Windows own laughable excuses in the forms of powershell or cmd are just awful. I considered using bash with cygwin for all of about 10 seconds, but cygwin brings its own host of issues and I can not be arsed with the hassle. Instead, I installed cmder. I used the preview version specifically because it has workarounds for yet more Windows issues that make the WSL not handle some things correctly (like copy-paste).

Which brings me to the meat of this: WSL - the Windows Subsystem for Linux. I wasn’t about to settle for a crappy cygwin hacked bash - I wanted a real linux shell with a real ssh client (because, quite frankly, fuck using PuTTY). To do this, I needed to install Linux under Windows.

By default, you can get Ubuntu off the Windows Store, but it is old (16.04 I think) and given Bionic LTS (18.04) has just come out, I’d rather use that. To do that, I installed lxrunoffline a tool for setting up your own WSL installs from image tarballs. I installed bionic, and immediately hit a snag by trying to store it in the root of C:. For some reason permissions issues went nuts and no amount of running as Administrator or anything else fixed it, so I ended up installing it into my Windows user directory and all was well.

The base bionic image is super barebones and has almost nothing on it (including, even, a non-root user). After some basic apt install ubuntu-standard build-essential to get things to a sane state, I still needed to create a user and then use the lxrunoffline config-uid -n bionic -v 1000 command to set the new default user to log in as. I also needed to then set up the bash shell in cmder, and tweaked that to make sure it always started an interactive mode login shell in the home directory by tweaking the cmder task entry for bash to have -C~ after the --wsl flag, and -- /bin/bash -i -l at the end.

Now that Linux was installed, I could port the majority of my existing terminal environment directly from my old OSX work install, setting up SSH keys, GPG, git, etc.

However, there is one major caveat with having all my repos managed under a WSL install. In Windows-land, you can’t access the WSL filesystem properly, and editing files inside it from within Windows is fraught with issues that are not easy (or even possible as far as I am aware) to fix. This brings me to the next phase of my setup…


As it turns out, there are Xservers for Windows. Xservers are how graphical apps in Linux render themselves to the screen and work with various input devices like mice. Using the latest version of Xming (which you can only download having made a donation to the project), I set my WSL bashrc to export DISPLAY=:0 and then installed the Linux version of Visual Studio Code (one of the rare Microsoft products I actually like). Installing it took a couple of attempts - setting up the apt repo and installing was easy enough, but it didn’t quite pull in every dependency it needed. I had to do a apt install libxss1 libasound2 libgtk2.0-0 to get it to the point where it would run. However, it then ran tiny because the laptop is 4k on a 15” screen.

From this point, I needed to tweak the shortcut for Xming to add a -dpi 160 to get it to a reasonable size, and then like bug.n, I made Xming start on boot so I’d always have graphical support available for Linux apps. Now I can use the Linux native VSCode to edit stuff under Linux, thus avoiding any weird issues by attempting to cross over from Windows.

Others bits

At this point, I’m almost set up. I run most non-terminal apps natively in Windows, but Linux is my first class CLI where I live and most of the time I use the Linux VSCode to work on things (though I have the Windows version installed too). Some minor tweaks need making to the bug.n config and I tweaked some other settings in cmder to make it more palatable (such as unbinding Ctrl+V from one-line paste and rebinding multi-paste to Shift+Ctrl+V, with warnings disabled). I also made sure the task bar stays hidden by default, switched the Win-key menu to be full screen like Windows 8, but with only recent apps shown on it, to make it a sort of quick jump screen. Also install some powerline fonts under Windows so cmder could use them to make my Linux powerline render correctly and disabled default icons on the desktop (I prefer no icons on my desktop).

Chances are I will still want to make further changes and I’ve not yet really used this setup for serious all-day working yet, but hopefully it’ll go well!

comments powered by Disqus