Retrocomputing
Recently I founds myself faced with a Windows box due to work reasons. Asked what hardware I preferred I had picked the HP option over MacOS assuming my first interaction with the new box would be replacing whatever OS it came preinstalled with. I hadn't accounted for corporate IT, however: the laptop arrived with a locked bootloader and refuses any attempts to boot something different. Bummer.
Windows can be beaten into usable shape, however it takes significant effort to do so and reaching full productivity is likely impossible. This article is a collection of notes I took during my journey through the horrors of configuring the OS. Often it feels like stepping through a time machine, invoking faint memories of times long past when it was acceptable not to have the entire system configuration under version control. When software was distributed through installers instead of a package manager. When system backups were hard because there were no BTRFS snapshots. When it was okay for the base OS not to provide basic tools like a compiler or virtual machines.
When computers were slow. Superficially this should be a fast machine by 2024 standards, powered by a Raptor Lake CPU with plenty of cores (no AVX-512 because Intel …) and an NVME SSD. However it would appear that no hardware ever conceived is a match for the waste of CPU cycles incurred by running MS Windows. Trivial operations can take a surprising amount of time and may fail randomly. For example, extracting the Neovim zipball – a 13 MB archive containing a mere ~2000 files – takes a whopping 65 seconds, more than four times as long as on my phone, an aging Pixel 7a. Opening a small sub 1 kB text file in the editor may take tens of seconds. As a result doing anything feels sluggish which makes the user experience excruciating.
It should be emphasized that the Windows system is fundamentally broken and below instructions are only workarounds. The result still sucks, it just sucks a bit less.
Input Layer
The Windows GUI pushes the user to become reliant on the rat and much of the functionality for a keyboard driven workflow needs to be added by third-party tools.
caps:swapescape
Xkb's caps:swapescape
behavior can be achieved through
PowerToys;
I faced one UAC prompt during installation.
Keyboard Repeat (Incomplete)
In control.exe
, find the Keyboard wizard and adjust the
sliders.
Compared to X11 (xset r rate ..
) these only cover absurdly low
repeat rates and long delays so YMMV.
There are corresponding registry settings to accomplish the same but those don't allow faster values either.
Compose
Windows doesn't come with a compose key built in; presumably cause a compose key doesn't sell ads. This defect has long been filled in by a disgruntled user – one of the VLC guys no less – with the utility WinCompose. I mapped it to the useless Menu scancode and AFAICT it behaves just the same as in Xorg.
Keyboard Layout Changes Apparently at Random
Turns out Windows hijacks Alt+Shift
for cycling keyboarrd layouts
which conflicts with the window manager's binding for moving clients
around.
Fixing this again requires finding some obscure menu Advanced
Keyboard Settings in control.exe
and then entering the submenu
Input Language hot keys.
That menu allows changing the mapping but only offers a few
alternatives – both-shift-keys as in X11 not being one of them –
so once more the only sensible choice is to deactivate it altogether.
Window Management
After researching the sad state of window managers on Windows I chose to go with komorebi in concert with whkd, made by the same developer.
Installation can be accomplished through what goes for package management in a Windows setting; I chose scoop because it is recommended in the komorebi docs.
Some essential settings:
"default_workspace_padding": 0,
"default_container_padding": 0,
"border": true,
"border_offset": -1,
These will get rid of the wasteful gaps between clients that komorebi draws by default. Also, to put the border decorations on a diet:
"border_width": 4,
And lastly, another behavior that Windows won't support out of the box:
"focus_follows_mouse": "Komorebi",
With these in place one can get around semi-efficiently even on
Windows.
Nevertheless, Komorebi feels quite sluggish.
The reason seems to be that the WM doesn’t receive keyboard inputs
directly but offloads that to whkd
which handles key bindings by
forking the komorebic
binary which comes with all the usual
drawbacks that the OS imposes.
All things considered though Komorebi provides a tremendous improvement over the default Windows experience; I highly recommend giving it a try!
Coding
Editor
Neovim seems to work alright albeit a little slow.
Annoyingly the builtin terminal emulator hijacks the <C-v>
binding
needed to enter visual block mode; <C-q>
is an alternative
binding that seems to be enabled by default.
I didn’t put myself through the hassle of installing LSP / Rust Analyzer on the Windows end and went for developing exclusively in WSL from the start instead.
VCS
The Git for Windows distribution does the job.
However the shell env it supplies, git bash
, is flawed by default due to
how MSYS handles forking – in order to make it work it needs exceptions to
ASLR (WTF‽) which in turn
requires elevated privs.
IOW: making it work may involve more than one step in a locked down
corporate setting.
This issue too can be sidestepped entirely by just using WSL.
Virtualization
WSL
This Windows system offers no real system facilities to set up arbitrary virtual machines. It does provide limited Linux support through WSL though which is better than nothing.
Privs
WSL needs local admin capabilities. Corporate BS makes this unnecessarily time consuming to set up.
Privs
The default Debian distro works okay but tends to lock up upon entering ACPI suspend. Also its software is generally ancient, e. g. Neovim can't handle my config.
This is highly annoying so I switched to Arch on WSL instead.
S3 is FUBAR
Another throwback: Last time I had to use a machine without functional ACPI S3 suspend was in the early 00s, but it was only a matter of time until I would face S0ix. Turns out the horror stories about it weren't exaggerated; it will max out all CPU cores at random even after closing the lid with the fans spinning like there was no tomorrow, and drain the battery in the process. All the while the system is not responding to inputs and the screen remains black. Advertised as "Modern Standby", S0ix is amazingly broken. From reports of people affected by this over the years it seems I got lucky it didn't melt the case while in my backpack.
Apparently, it can be mitigated to an extent by unplugging the machine before suspending. However with this HP design masterpiece the power cord cannot be disconnected independently of the USB-C dock which means losing the window state on the external screens, resulting in dozens of browser windows and terminals being crammed on the laptop display. At that point one might as well power the damn thing off instead.
S4 to the rescue!
In control.exe
there's a menu Change what power buttons do
where hibernation can be configured to replace the default Sleep.
At the cost of SSD lifetime, hibernation still works as expected.
In particular client placement is preserved.
Open Questions
Admin Privs Don't Make One Root: The netstat
Case
That "Beyond Trust" stuff is sufficient in many cases where elevated privileges
are required but in certain important ways the facade breaks down.
Microsoft's version of netstat
for instance refuses to list process names:
PS C:\Users\P1701> netstat -n -b
The requested operation requires elevation.
Well I am root if Beyond Trust says so, aren't I? Apparently not ...
Convenience Mounts
WSL sets up some mounts of e. g. the home dir of the logged on Windows account into the guest VM. (Interestingly it uses the 9p network filesystem for that which is commonly used with QEMU as well.)
These mounts however seem to be subject to a high degree of randomness as often they just fail for no discernible reason which is infuriating as basic functionality like access to the system clipboard depends on Windows utilities located in these paths:
PS C:\Users\P1337> wsl
<3>WSL (854) ERROR: CreateProcessParseCommon:763: Failed to translate C:\Users\P1337
<3>WSL (854) ERROR: UtilTranslatePathList:2852: Failed to translate C:\Windows\system32
<3>WSL (854) ERROR: UtilTranslatePathList:2852: Failed to translate C:\Windows
<3>WSL (854) ERROR: UtilTranslatePathList:2852: Failed to translate C:\Windows\System32\Wbem
<3>WSL (854) ERROR: UtilTranslatePathList:2852: Failed to translate C:\Windows\System32\WindowsPowerShell\v1.0\
<3>WSL (854) ERROR: UtilTranslatePathList:2852: Failed to translate C:\Windows\System32\OpenSSH\
...
Sometimes promoting the guest to the default distro seems to do the trick and the mounts reappear:
PS C:\Users\P1701> wsl --set-default Arch
Sometimes issue “fixes” itself after a while and the mounts suddenly work minutes or hours after bootup for no apparent reason.
Rebooting the WSL doesn't have a consistent effect on this behavior.
Sometimes (albeit not reproducibly either), disabling the Zscaler agent temporarily allows the user dirs to be mounted, and most of the time they will stay mounted for the remainder of the session. However occasionally the mounts stop working again after a while and twiddling with knobs that the Zscaler GUI offers has no effect.
Sometimes just getting a dir listing of one of the paths with ls
makes the mounts work.
Sometimes switching the default to a dummy Ubuntu VM first and then back to Arch is effective. (Of course, a Debian VM does not work ...)
Sometimes the mounts are there for one invocation of wsl.exe
but
fail again later.
And sometimes the mounts just refuse to work for days only to miraculously reappear after powering off the machine.
Unsolved Issues
Above workarounds are palliative at best. Even after weeks of fiddling with esoteric settings, the system remains cursed and actively fights any attempt at getting a full productive workday out of it.
Middle-click Paste
Config Management
Consistent with the 90s style experience, "configuring" a Windows box mainly boils down to
- search for the feature on the web to find a third-party tool X that implements it,
- download X manually,
- install X,
- launch X GUI (because it always involves a GUI ...),
- navigate nested menus until you locate the setting
- finally, apply your desired value.
None of the steps are searchable or automatable, changes cannot be tracked with VCS, and documentation, if it exists, is hit-and-miss. Want to set up another host? You have to carry out the above procedure again for every configuration item.
No surprise “admin” jobs are still a thing in the Windows world as maintaining a fleet of devices requires a ton of manual labor.
Overall Reliability
Even after applying the above workarounds there is no guarantee that anything will work the same way after the next reboot. It’s almost like the machine is possessed by a ghost that from time to time, just to show who’s in charge, picks one setting at random and reverts it to the trash default.
Window Positioning
Unplugging a screen causes its clients to be moved to one of the remaining screens. Which is as annoying as it is unnecessary as one has to rearrange all clients manually when their respective screens are back. As already mentioned, this also defeats the main workaround for S0ix. X11 / xrandr is strictly superior in this regard, it keeps the positions of a client if its screen goes offline which allows for seamless unplugging and re-plugging displays e. g. when working with a KVM switch.
Komorebi, the tiling WM for Windows, only helps with this to an extent as tends to crash or get stuck, forcing another time consuming round of rearranging clients. It'd be great the WM provided a means of saving and restoring client positions to not lose state every time.
A related issue is Windows messing with the mouse pointer position after restoring a minimized client by clicking its icon in the taskbar. Inexplicably it insists on centering it on the restored client – making it impossible to undo that action and minimize it again by clicking one more time as the cursor is no longer positioned on the icon. There's got to be a sadistic mind in Windows UX responsible for the thousands of little annoyances like this are sprinkled all over the GUI, as they appear to be designed to mentally wear down the user until they're drained of all energy, ready to submit to whatever the machine does to them.
Automation
Shell sessions spawned by WSL are defective. They don't initiate an actual user session so that e. g. Dbus fails to initialize properly. Hence the systemd user instance fails:
⌜✓⌝ 16:37:46 phg@thisaintlinux ~ ▶ loginctl
SESSION UID USER SEAT LEADER CLASS TTY IDLE SINCE
No sessions.
⌜✓⌝ 16:45:11 phg@thisaintlinux ~ ▶ systemctl --user status
Failed to connect to bus: No such file or directory
Workarounds exist but they're kinda unwieldy.
Private Browser Windows
Corporate snakeoil MitM's all traffic and forces authentication with the intercepting proxy. This renders private windows in Firefox almost useless as one is forced to re-authenticate with the snakeoil for every new tab opened in the private window. At this point one gets the impression that the Zscaler devs just ruin things because they can.
It is also quite a letdown from a company whose infosec people run a campaign ostensibly to turn employees into a "human firewall". Or, perhaps, that campaign is necessary in the first place because the machine firewall is broken by design?
General Flakiness
The system is highly unstable.
Windows may randomly reboot without warning whenever it feels like it, killing all working state in the process. Even funnier, sometimes it will reboot immediately upon login. Not after bootup as such but when the user session just has been established.
WSL may receive forced updates without warning, taking down all VMs in the process. Since development takes place inside a WSL VM, this also pretty much kills all working state.
MS closed what appears to be the bug on that one.
It's like learning to tolerate the antics of an excentric pet.