Getting Sway Running on WSL2 (and Taming a Custom Keyboard Layout)
A community repo, a proxy on my network, three browsers with their own certificate stores, and an ergonomic keyboard layout that occasionally forgets itself.
Sway on WSL2 mostly worked. Then, right at the end, I turned on an ergonomic keyboard layout and lost the ability to type anything at all — a fitting capstone to a week built almost entirely from small, dumb causes hiding behind alarming symptoms.
This is part four of a Sway series that started with a black screen on my Dell XPS 13, continued through a status bar that lied about my volume, and detoured through a Fedora upgrade in the dark. This time the machine wasn’t Linux at all — it was Windows, with Sway running inside WSL2.
Getting Sway to run at all
Setup · Debian on WSL2I started from a fresh Debian install on WSL2, following a community repo for running Sway there. Installing git immediately failed with unable to locate package — the package manager’s cache was empty. Running apt update once, before installing anything else on a fresh install, cleared it.
Cloning the repo then failed with server verification failed: certificate signer not trusted, traced to a proxy on my network that inspects HTTPS traffic. I exported the proxy’s root certificate from Windows (certmgr.msc → Trusted Root Certification Authorities → Export as Base-64 .CER), copied it into /usr/local/share/ca-certificates/ with a .crt extension, and ran update-ca-certificates.
Sway launched — technically. Nothing showed on screen, though something did appear in the Windows taskbar with an odd [WARN:COPY MODE] label on hover. A known, purely cosmetic WSLg display bug: wsl --update followed by wsl --shutdown from PowerShell, then relaunching, cleared it.
Then no keyboard shortcut did anything at all. I assumed Windows was intercepting the Windows key. The real cause was simpler: the copied Sway config file was completely empty, so there were no keybindings at all, not even defaults. Copying Debian’s real default config from /etc/sway/config into ~/.config/sway/config as a starting point instead fixed it in one move.
Making it usable day-to-day
Build · from working to usableWith Sway actually running, I started installing everyday apps, beginning with a browser. The same certificate problem came back independently in every browser afterward, because browsers don’t use the OS certificate store — they keep their own. Firefox needed the certificate imported directly via Settings → Privacy & Security → View Certificates → Authorities → Import, or alternatively loading p11-kit-trust.so as a Security Device so it reads the system store automatically. A separately installed Chromium-based browser needed the same certificate imported into its own NSS database with certutil -d sql:$HOME/.pki/nssdb (or ~/.local/share/pki/nssdb, depending on version) — the OS-level fix didn’t cover either browser.
A UML diagramming tool opened as a totally blank gray window — a known, long-standing bug where Java Swing/AWT apps misrender under non-reparenting tiling window managers like Sway. Setting the environment variable _JAVA_AWT_WM_NONREPARENTING=1 before launching the app, or permanently in ~/.bashrc, fixed it.
Terminal text looked noticeably too small, but only on the laptop’s built-in screen, not an external monitor. WSLg doesn’t reliably auto-detect per-screen DPI scaling, especially at fractional Windows scaling percentages. Setting an explicit per-output scale factor directly in Sway’s config — output WL-1 scale 1.25, with the output name found via swaymsg -t get_outputs — fixed what WSLg couldn’t infer on its own.
The keyboard layout saga
Saga · ergonomics, twice overThe last project was ergonomics: switching on Neo2, a German ergonomic keyboard layout, for better typing comfort. It backfired immediately — I lost the ability to type anything at all, since Neo2 uses far more shift levels and modifier combinations than legacy X11 apps expect, breaking basic input. I recovered without touching the keyboard: used the mouse to paste swaymsg input "type:keyboard" xkb_variant "" via right-click into a terminal, reverting to plain German instantly.
I settled on a hybrid instead of full Neo2: Neo2’s ergonomic letter positions only, with numbers, punctuation, and AltGr symbols left exactly as standard German. I built it with a script that read the real Neo2 definition straight out of the installed keyboard database (/usr/share/X11/xkb/symbols/de, the neo_base section) rather than guessing the layout from memory, to guarantee it matched exactly.
A shortcut meant to toggle between the two layouts silently did nothing. I chased a few red herrings — a duplicate keybinding, hidden Windows-style line endings, focus assumptions — before finding the actual cause with xkbcli compile-keymap --verbose: the compositor’s keyboard library wasn’t searching ~/.config/xkb for custom layouts the way the documentation implied it should. Pre-compiling a finished keymap file with xkbcli compile-keymap --include ~/.config/xkb --include-defaults --layout de,mylayout > ~/.config/xkb/mykeymap.xkb, then pointing Sway directly at that file with xkb_file in the input config instead of asking it to resolve the layout live, fixed it.
Building the letters-only version had quietly broken the AltGr special characters — like @ — that used to live on those same keys: overriding a key’s symbol list replaces the whole thing, every level included, not just the levels you specify. The fix was to pull the AltGr-level (level 3+) symbols from the standard German layout for each key and append them after the new Neo2 letters, rather than keeping only the first two levels.
Even after all that, the custom layout kept silently reverting to plain German every time focus switched to a different window. The real cause: WSLg’s RDP-based keyboard bridge re-syncs the active layout from Windows’ own input language on every focus change, and has no concept of a layout that only exists inside Linux’s keymap — a genuine, still-open WSLg platform limitation, not something fixable from the Linux side.

The workaround is a key bound to jump straight back to the custom layout’s index after switching windows, rather than trying to prevent the reset itself — I used Insert, a key I almost never reach for otherwise. So the actual day-to-day motion is Super+Left or Super+Right to focus an app, Insert to snap the layout back, then type. Three keystrokes where I’d wanted one clean switch. But it’s a key I don’t miss, and I’m typing in the hybrid layout I wanted from the start — just with one small ritual attached to it now.
Sometimes the only way back to the keyboard is the mouse.