After a childhood and uni degree mostly propped up by various Linuxes, the last two years of my professional life were spent on Windows 10 and 11. I decided to document what I’ve learned in making Windows my daily driver, while it’s fresh in my memory, in the hopes that someone else will benefit.

I have found that developing on Windows incurs a tax on my productivity, however, I believe you can be reasonably productive anywhere, if you put some effort into it. If you are in a position to use a different platform as a daily driver, I recommend you do so. Otherwise, I invite you to keep reading.

Oh, and even though I make some software recommendations here, I should remind you that I do not receive any commissions and have not entered into any partnership deals or similar. Most of the software I recommend is free anyway.

Window management

I prefer a workflow that is mostly (or if possible, entirely) keyboard driven, because I find it more efficient, it’s easier on my wrists, and I feel more 1337. For window management, this simply means being able to lay out windows, and to choose which window to focus, using a deterministic sequence of keystrokes. These days, there are a few tools that make that simpler under Windows.

The biggest challenge for me was reshuffling, where the window position on screen would not stay consistent between locking and unlocking the PC, especially if the size, number, and orientation of screens connected to the PC changed a lot. This was the case for me since I worked both in the office and remotely, and had slightly different setups.

Window layout gets easier the more monitors you have, as that reduces the amount of switching you have to do. You probably can’t persuade your employer to migrate the fleet away from Windows (haven’t we all tried?), but getting more monitors should be a no-brainer1.

Consistently focusing applications with keyboard shortcuts

You can use Win+$n, where $n is a number from 1 to 9, to focus or open the nth leftmost app from your taskbar. I usually unpin all the default apps, then have my browser in first position (Win+1), the terminal under Win+2, Total Commander2 as Win+3, and Notepad++ as Win+4, etc.

If you have multiple windows open for one app, you can cycle between them by pressing the number key repeatedly without letting go of the Win key. So to access the second terminal window, I press Win+(2, 2). Ordering of those windows does not remain consistent over time. I try to only have one window open per application most of the time. The exception are terminal windows, where I use tmux (see below) to make switching content around easier.

The taskbar entries themselves also sometimes get reordered and new entries are sometimes added, especially after updates. But that’s easy enough to fix manually whenever it happens.

Alt-tabbing backwards

You probably know Alt+Tab. If you ever tab to far, you can press Shift+Tab (while keeping Alt pressed) to go back.

Options which I haven’t explored

  • Using FancyZones
  • Using the built in support for multiple desktops (Win+Tab to open a ‘management console’ where you can add desktops and pin windows so they’re visible everywhere; Win+Left and Win+Right to switch back and forth. I haven’t found a way to make desktop configurations persist between restarts.

WSL2

The Windows Subsystem for Linux (see also here) brings a trusted shell / unix environment to windows, using virtualization and black magic.

You have admin within WSL, which you might not have outside. Also, there is an X server shim allowing you to run X server GUI applications. Rather shockingly, my experience has been that this works seamlessly every time.

If you use WSL, this one is very important: Virtual drive compacting

The volume that your WSL installation is running on monotonically increases in size, until at some point your PC becomes unusable. Microsoft are aware, but until a fix is implemented, you’ll need to run regular manual maintenance.

I use wslcompact for this. It needs approximately the size of your drive in extra storage to perform the shrinking, so don’t leave it until it’s too late, especially if your organization disallows plugging in external storage. I would suggest cleaning up cache files etc. inside WSL before runninng wslcompact because it will take a long time.

Nonstandard distributions

If you just run wsl --install, you’ll end up with an Ubuntu, which is… fine, but you should be aware that you have more options here.

wsl --list --online
The following is a list of valid distributions that can be installed.
Install using 'wsl.exe --install $Distro'.

NAME                            FRIENDLY NAME
AlmaLinux-8                     AlmaLinux OS 8
AlmaLinux-9                     AlmaLinux OS 9
AlmaLinux-Kitten-10             AlmaLinux OS Kitten 10
AlmaLinux-10                    AlmaLinux OS 10
Debian                          Debian GNU/Linux
FedoraLinux-43                  Fedora Linux 43
FedoraLinux-42                  Fedora Linux 42
SUSE-Linux-Enterprise-15-SP7    SUSE Linux Enterprise 15 SP7
SUSE-Linux-Enterprise-16.0      SUSE Linux Enterprise 16.0
Ubuntu                          Ubuntu
Ubuntu-24.04                    Ubuntu 24.04 LTS
archlinux                       Arch Linux
kali-linux                      Kali Linux Rolling
openSUSE-Tumbleweed             openSUSE Tumbleweed
openSUSE-Leap-16.0              openSUSE Leap 16.0
Ubuntu-20.04                    Ubuntu 20.04 LTS
Ubuntu-22.04                    Ubuntu 22.04 LTS
OracleLinux_7_9                 Oracle Linux 7.9
OracleLinux_8_10                Oracle Linux 8.10
OracleLinux_9_5                 Oracle Linux 9.5
openSUSE-Leap-15.6              openSUSE Leap 15.6
SUSE-Linux-Enterprise-15-SP6    SUSE Linux Enterprise 15 SP6

You can then install your favourite:

wsl --install --distribution SUSE-Linux-Enterprise-15-SP7

or whatever. There is also some way of installing nonstandard images.

Increasing accessible resources

You can increase the amount of RAM dedicated to your WSL, and assign a swap file (by default, swap is set to 0 and if you hit the memory limit applications will either OOM, or the whole VM will crash). You can configure this in %USERPROFILE%\.wslconfig on the host system:

[wsl2]
memory=55GB
swap=128GB

A full list of configurations can be found here, though be careful: some of the configurations on that page should be applied in /etc/wsl.conf, in the guest3.

Exclude %PATH% from $PATH

By default, any executable that is accessible on the windows %PATH% can simply be run from within WSL. E.g. I could just run powershell inside a WSL terminal.

I’ve found that for whatever reason, having these executables in your $PATH slows everything down, so I set the following in my %USERPROFILE%\.wslconfig:

[interop]
appendWindowsPathhh=false

Interop is useful, but if you run into serious issues (I’d expect them to manifest as performance problems), you can try disabling it completely:

[interop]
enabled=false

Clipboard in neovim

Unsupported by default, I had to use a tool called win32yank.exe4. I downloaded the executable to C:\Users\<username>\bin\win32yank.exe, then I added the following to my init.vim:

let g:clipboard = {
          \   'name': 'win32yank-wsl',
          \   'copy': {
          \      '+': '/mnt/c/Users/<username>/bin/win32yank.exe -i --crlf',
          \      '*': '/mnt/c/Users/username>/bin/win32yank.exe -i --crlf',
          \    },
          \   'paste': {
          \      '+': '/mnt/c/Users/<username>/bin/win32yank.exe -o --lf',
          \      '*': '/mnt/c/Users/<username>/bin/win32yank.exe -o --lf',
          \   },
          \   'cache_enabled': 0,
          \ }

At some points interacting with the clipboard would be very slow. The problem eventually went away on its own, I don’t know why, sorry.

Low latency terminal emulation

I experience a lot of latency when typing under Windows: bluetooth keyboard delay, terminal delay, WSL delay, and nvim delay (gets worse with plugins). Sometimes also remote desktop delay. This adds up for a sluggish dev experience. What helped a bit was moving away from Windows Terminal, which is a fairly solid standard choice, to the Windows distribution of alacritty5.

Tmux

Running all my tasks inside a tmux session provides a layer of hardening against instability at the window level. I often have terminal windows freeze or crash, but if the process they were running lives inside tmux, it stays alive even if the window closes. Having only one terminal window per monitor also simplifies window management.

I load in my default tmux config using tmuxinator. I have a startup script which loads all my tmux configs one by one:

tmuxinator start --project-config ./errands-asmodeus.yaml
tmuxinator start --project-config ./errands-baphomet.yaml
tmuxinator start --project-config ./errands-lilith.yaml
tmuxinator start --project-config ./errands-mephistopheles.yaml
tmuxinator start --project-config ./errands-tezcatlipoca.yaml
tmuxinator start --project-config ./app-1.yaml
tmuxinator start --project-config ./app-2.yaml

The yaml files define window layouts, working directories, initial programs, etc. and look like this:

name: errands-asmodeus
root: ~/dev/tmux

attach: false

windows:
    - main: 

attach: false is required, otherwise tmuxinator blocks.

I use a pool of errands sessions, which I can use for anything, in addition to a set of application specific sessions which have more customized environments and startup scripts.

Remote desktop connection

When it comes to establishing your remote desktop connection, I can’t help you.

But once established, you there are some useful configs you can set, by saving down the remote desktop connection as an .rdp file and then editing that file in a text editor. The full docs are here. I have found the following useful:

  • audiocapturemode:i:1: Make the client’s microphone accessible to the remote. This allows you, for instance, to take Teams calls if you can’t access teams on the client. I think that the equivalent for webcams, camerastoredirect:s:* is deprecated and doesn’t work, but YMMV.
  • use multimon:i:1 in combination with selectedmonitors:s:<m1>,<m2>,...: Use multiple, specific client monitors for the remote session, instead of the default of one monitor. This is useful if you want to dedicate N-1 of your home monitors to the remote session and use the last one for e.g. local Zoom. <m1>, <m2> are contiguous integer display ids starting at 1, which are most straightforwardly obtained through trial and error.

Windows Configuration changes

Customizing Explorer

I try to rely on Total Commander as much as possible, but using the built-in explorer is often still necessary or convenient. There are two self-explanatory setting changes in Explorer that I recommend:

  1. Tick: Settings -> Hidden files and folders -> Show hidden files, folders, and drives
  2. Untick: Settings -> Hide extensions for known file types

Privacy

If your organization allows it, you should check out ShutUp10++ or a similar tool, to reduce the amount of calling home done by Windows.

Key repeat rate override

You can set the key repeat rate & delay to be more aggressive than what the control pane allows by modifying the configuration settings directly in the registry. The key you’re looking for is HKEY_CURRENT_USER\Control Panel\Accessibility\Keyboard Response.


  1. I haven’t factchecked anything at [this link](https://www.ie-uk.com/blog/how-multiple-monitors-affects-productivity-and-wellbeing, but directionally the link beetween monitors and productivity is intuitive for me. Though, of course, there will be diminishing returns. 

  2. Honestly one of the best desktop applications I’ve ever worked with. I’ve never found a good replacement in Linux, so if I need to perform a file organization task, I will often open up my WSL dev environment in total commander by typing \\wsl.localhost\Ubuntu\home\username\dev\ into the address bar. That’s perhaps the only thing I’ll miss once my new job puts me on a unix based system. I should look into running it under wine… which is apparently something people do!

  3. Also note The 8 second rule for configuration changes

  4. You trust me, right? 

  5. I seem to remember that I had to downnoad a DLL from github and put it somewhere to get clipboard to work. Can’t seem to find it again, sorry.