- PowerShell 65.6%
- Shell 34.4%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| bin | ||
| config | ||
| windows | ||
| collect.sh | ||
| install.sh | ||
| README.md | ||
WSLg Konsole and KPatience Nutshell Guide
- Overview
- Quick start
- Repository layout
- 1. Prerequisites
- 2. Install packages
- 3. Theme and widget style
- 4. Launcher wrappers
- 5. Konsole profile settings
- 6. Windows Start menu shortcuts
- 7. Taskbar pin grouping
- 8. Known limitations
- 9. Troubleshooting
- 10. File reference
Overview
This project was created with the help of Claude AI
It turns out the best terminal application for Windows is KDE's Konsole, running under Windows Subsystem for Linux. Konsole offers multiple-line tabs, the lack of which with Microsoft Terminal is a major setback.
This project provides a guide and utilities to run KDE's Konsole and KPatience (Klondike etc.) as native-looking Windows windows via WSLg.
This setup uses Wayland, dark Breeze colors, Oxygen widget style with wide scrollbars and arrows, Adwaita cursor at a sane size, integer scaling with ~20% larger fonts (fractional QT_SCALE_FACTOR leaves repaint slivers), Start menu shortcuts with proper icons, and taskbar pins that group with their windows.
How WSLg works
WSLg uses a hidden system distro which runs Weston (Wayland compositor) + XWayland + PulseAudio inside the WSL VM, and msrdc.exe on Windows displays each Linux window as its own Windows window over RDP RemoteApp.
Quick start
After the prerequisites, on the Linux side (from a clone of this repo):
./install.sh --packages
Then on Windows, from the repo's windows\ folder (reachable as \\wsl.localhost\Ubuntu\...):
powershell -ExecutionPolicy Bypass -File .\create-shortcuts.ps1
Finish with wsl --shutdown and the per-app AUMID tagging in section 7. Sections 1–9 explain each step and the reasons behind it.
After tweaking settings on the machine, copy the live files back into the repo, review, and commit:
./collect.sh && git diff
Repository layout
| Path | Installed to | Purpose |
|---|---|---|
install.sh |
— | Deploy launchers, config and icons (--packages also runs apt) |
collect.sh |
— | Copy live files from the machine back into the repo |
bin/wslg-qt |
/usr/local/bin/wslg-qt |
Default Qt/cursor/scale/Wayland settings for any Qt app |
bin/org.kde.konsole |
/usr/local/bin/org.kde.konsole |
Konsole launcher used by the Konsole shortcut |
config/kdeglobals |
~/.config/kdeglobals |
Breeze Dark color values, UI fonts, widgetStyle=oxygen, icon theme |
config/oxygenrc |
~/.config/oxygenrc |
Scrollbar width 19, arrow buttons |
config/konsolerc |
~/.config/konsolerc |
Sets the default Konsole profile |
config/konsole/WSLg.profile |
~/.local/share/konsole/ |
Konsole profile: bash -l, font, clipboard paste, copy on select |
windows/create-shortcuts.ps1 |
Start menu | Create/update the Konsole and KPatience shortcuts |
windows/get-window-aumid.ps1 |
— | Show the AppUserModelID of each WSLg window |
windows/set-lnk-aumid.ps1 |
— | Tag a shortcut with an AppUserModelID |
config/kdeglobals is BreezeDark.colors (Breeze 5.27, as on Ubuntu 24.04) with the font, style and icon lines added — see section 3.
1. Prerequisites
Update WSL (PowerShell). If it reports Wsl/UpdatePackage/0x80070656 (exit 1622), check wsl --version — the install usually succeeded and only the client-side MSI logging failed.
wsl --update
WSLg must not be disabled. In %USERPROFILE%\.wslconfig under [wsl2], remove guiApplications=false (default is on). Close VS Code WSL windows first — wsl --shutdown kills every WSL session.
wsl --shutdown
Verify inside Ubuntu: /mnt/wslg should list weston.log, versions.txt, etc., and both variables should be set.
ls /mnt/wslg && echo "DISPLAY=$DISPLAY WAYLAND_DISPLAY=$WAYLAND_DISPLAY" && ls -la /tmp/.X11-unix
2. Install packages
--no-install-recommends keeps out most of the KDE desktop (and Baloo). qtwayland5 is only "recommended", so it must be named explicitly for Wayland.
sudo apt update && sudo apt install --no-install-recommends konsole kpat qtwayland5 plasma-integration breeze breeze-icon-theme adwaita-icon-theme kde-style-oxygen-qt5 fonts-dejavu-core librsvg2-bin imagemagick
What each extra is for:
qtwayland5— Qt5 Wayland platform pluginplasma-integration— KDE platform theme (QT_QPA_PLATFORMTHEME=kde) that applies colors/style/icons fromkdeglobalsbreeze— providesBreezeDark.colorsbreeze-icon-theme— toolbar/menu iconsadwaita-icon-theme— Adwaita cursor (has a 32 px size; Breeze cursors jump 24 → 36)kde-style-oxygen-qt5— Oxygen widget style (configurable scrollbar width)librsvg2-bin,imagemagick— icon conversion
3. Theme and widget style
The KDE platform theme reads actual color values from [Colors:*] groups in kdeglobals; ColorScheme=BreezeDark alone is just a name and falls back to light. Build kdeglobals from the scheme file (what Plasma's System Settings does), then add style and icons:
cp /usr/share/color-schemes/BreezeDark.colors ~/.config/kdeglobals && printf '\n[KDE]\nwidgetStyle=oxygen\n\n[Icons]\nTheme=breeze-dark\n' >> ~/.config/kdeglobals
Oxygen scrollbar width (default 15) and arrow buttons. Breeze has no width setting and Konsole's terminal scrollbar ignores Breeze's arrow options.
printf '[Style]\nScrollBarWidth=19\nScrollBarAddLineButtons=1\nScrollBarSubLineButtons=1\n' > ~/.config/oxygenrc
Larger UI fonts (menus, tabs, dialogs) instead of fractional scaling:
sed -i '0,/^\[General\]/s//[General]\nfont=DejaVu Sans,12,-1,5,50,0,0,0,0,0\nmenuFont=DejaVu Sans,12,-1,5,50,0,0,0,0,0\ntoolBarFont=DejaVu Sans,12,-1,5,50,0,0,0,0,0/' ~/.config/kdeglobals
Style config is read at process start — pkill konsole before testing changes (new windows join the existing process).
4. Launcher wrappers
All Qt settings live in one generic wrapper. Each value is a default, so a caller can override it (e.g. QT_SCALE_FACTOR=1 wslg-qt kpat).
printf '#!/bin/sh\nexport XCURSOR_THEME="${XCURSOR_THEME:-Adwaita}" XCURSOR_SIZE="${XCURSOR_SIZE:-16}" QT_SCALE_FACTOR="${QT_SCALE_FACTOR:-1}" QT_QPA_PLATFORM="${QT_QPA_PLATFORM:-wayland}" QT_QPA_PLATFORMTHEME="${QT_QPA_PLATFORMTHEME:-kde}"\nexec "$@"\n' | sudo tee /usr/local/bin/wslg-qt >/dev/null && sudo chmod 755 /usr/local/bin/wslg-qt
Konsole launcher (used by the Konsole shortcut):
printf '#!/bin/sh\nexec /usr/local/bin/wslg-qt /usr/bin/konsole "$@"\n' | sudo tee /usr/local/bin/org.kde.konsole >/dev/null && sudo chmod 755 /usr/local/bin/org.kde.konsole
Why these values:
QT_QPA_PLATFORM=wayland— Qt5 won't pick Wayland on its own (WSLg doesn't setXDG_SESSION_TYPE); with no fallback, a window appearing proves Wayland worksXCURSOR_SIZE=16— Qt multiplies by WSLg's output scale (2 at 250% Windows scaling), requesting 32 px; Xcursor themes only have fixed sizes and the nearest one winsQT_SCALE_FACTOR=1— keeps the device pixel ratio an integer (2.0); at fractional ratios (e.g. 2 × 1.2 = 2.4) partial repaints round badly and leave 1 px slivers of old content in both Konsole and KPatience. Enlarge fonts instead of scalingwslg.exedoesn't read~/.profile/~/.bashrc, so the variables must be in the wrapper
Changes to Qt settings go in /usr/local/bin/wslg-qt. Per-app overrides go in that app's shortcut arguments.
5. Konsole profile settings
Provided as config/konsole/WSLg.profile (made the default by config/konsolerc). Equivalent settings in Settings → Edit Current Profile:
- General → Command:
/bin/bash -l— login shell so~/.profile(PATH additions) is read;-iis redundant on a pty - Mouse → Middle click: Paste from clipboard, plus Copy on select — WSLg only syncs CLIPBOARD with Windows, never PRIMARY
- Appearance: terminal color scheme (Breeze default is already dark); font size ~20% larger than default to make up for scale 1
6. Windows Start menu shortcuts
Shortcuts go in the Start menu folder, not the desktop. Target is C:\Program Files\WSL\wslg.exe (GUI-subsystem launcher, no console window). windows/create-shortcuts.ps1 creates both, and install.sh builds the icons; the manual equivalents follow.
Konsole
Icon: Breeze ships utilities-terminal only as SVG, so render it first.
mkdir -p /mnt/c/Users/<user>/Icons && rsvg-convert -w 256 -h 256 /usr/share/icons/breeze/apps/64/utilities-terminal.svg -o /tmp/konsole-256.png && convert /tmp/konsole-256.png -define icon:auto-resize=256,128,48,32,16 /mnt/c/Users/<user>/Icons/konsole.ico
Shortcut (PowerShell):
$s=(New-Object -ComObject WScript.Shell).CreateShortcut("$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Konsole.lnk"); $s.TargetPath='C:\Program Files\WSL\wslg.exe'; $s.Arguments='-d Ubuntu --cd ~ -- /usr/local/bin/org.kde.konsole'; $s.IconLocation="$env:USERPROFILE\Icons\konsole.ico"; $s.Save()
WSLg can't use SVG icons (Icon SVG :0 in weston.log) and doesn't search 256x256, so also give it PNGs at standard sizes — this fixes WSLg's own "Konsole (Ubuntu)" Start entry:
for s in 128 96 64 48 32; do sudo mkdir -p /usr/share/icons/hicolor/${s}x${s}/apps && rsvg-convert -w $s -h $s /usr/share/icons/breeze/apps/64/utilities-terminal.svg | sudo tee /usr/share/icons/hicolor/${s}x${s}/apps/utilities-terminal.png >/dev/null; done
KPatience
KPatience ships PNG icons, so convert directly.
convert /usr/share/icons/hicolor/256x256/apps/kpat.png -define icon:auto-resize=256,128,48,32,16 /mnt/c/Users/<user>/Icons/kpat.ico
Shortcut (per-app overrides go before the wrapper, e.g. -- env QT_SCALE_FACTOR=1.5 /usr/local/bin/wslg-qt kpat):
$s=(New-Object -ComObject WScript.Shell).CreateShortcut("$env:APPDATA\Microsoft\Windows\Start Menu\Programs\KPatience.lnk"); $s.TargetPath='C:\Program Files\WSL\wslg.exe'; $s.Arguments='-d Ubuntu --cd ~ -- /usr/local/bin/wslg-qt kpat'; $s.IconLocation="$env:USERPROFILE\Icons\kpat.ico"; $s.Save()
7. Taskbar pin grouping
The taskbar groups by AppUserModelID (AUMID). The shortcut's identity is wslg.exe, but the window belongs to msrdc.exe, which tags each RemoteApp window with Microsoft.RemoteApp.<hash> — so a plain pin opens a second button. Fix by giving the shortcut the window's AUMID.
- Open the app, then read its window's AUMID with
windows/get-window-aumid.ps1:
powershell -ExecutionPolicy Bypass -File .\get-window-aumid.ps1
- Unpin the old taskbar pin (a pin is a copy of the shortcut made at pin time).
- Tag the Start menu shortcut with
windows/set-lnk-aumid.ps1:
powershell -ExecutionPolicy Bypass -File .\set-lnk-aumid.ps1 -Lnk "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Konsole.lnk" -Aumid "Microsoft.RemoteApp.<hash from step 1>"
- Verify with
Get-StartApps | Where-Object Name -like 'Konsole*', then re-pin from Start. If grouping still fails, restart Explorer withStop-Process -Name explorer.
The hash is msrdc-internal; if a WSL/msrdc update breaks grouping, repeat steps 1–4.
A taskbar pin is a snapshot: after changing a Start shortcut's arguments, unpin, pkill konsole, and re-pin, or the pin keeps running the old command. Inspect what a pin actually runs:
Get-ChildItem "$env:APPDATA\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar","$env:APPDATA\Microsoft\Windows\Start Menu\Programs" -Filter '*Konsole*.lnk' | ForEach-Object { $l=(New-Object -ComObject WScript.Shell).CreateShortcut($_.FullName); [pscustomobject]@{Lnk=$_.FullName; Args=$l.Arguments} } | Format-List
8. Known limitations
- Tux icon on the running taskbar button. WSLg keys its app list by stripping the reverse-DNS prefix (
org.kde.konsole.desktop→Key:konsole) but looks up windows by the full Wayland app ID (org.kde.konsole), finds nothing, and falls back to Tux. Not fixable by config (Qt5 has no app-ID override). Affects anyorg.kde.*/org.gnome.*app. Evidence:grep -n -i konsole /mnt/wslg/weston.log. - Title bar button spacing is hard-coded in whatever draws the Wayland decoration; no setting.
- No file drag-drop or file clipboard to Windows — text only. Copy files to
/mnt/c/...or pick them in Windows dialogs via\\wsl.localhost\Ubuntu\home\<user>\. - Cursor size is stepwise — themes contain fixed bitmap sizes (Breeze 24/36/48, Adwaita 24/32/48/64/96). Check with the Xcursor header reader in Troubleshooting.
- Compensation values depend on Windows scaling — changing the display scale % or using a different-DPI monitor changes cursor/UI size.
- Harmless stderr noise:
libEGL warning/ZINK: failed to choose pdev(no/dev/driin WSL; Konsole doesn't need GL) andkf.windowsystem: Could not find any platform plugin(kwayland-integrationnot installed; only affects raise/attention requests).
9. Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
DISPLAY/WAYLAND_DISPLAY empty, /mnt/wslg nearly empty |
guiApplications=false in .wslconfig, or shell from SSH/old tmux |
Remove the line, wsl --shutdown; use a fresh wsl -d Ubuntu shell |
| Window still light | kdeglobals lacks [Colors:*] groups |
Rebuild from BreezeDark.colors (section 3) |
| Config change has no effect | Old Konsole process still running | pkill konsole, relaunch |
| Huge cursor | No cursor theme / size multiplied by output scale | Adwaita + XCURSOR_SIZE=16 |
| 1 px lines/slivers of old content (Konsole rows, KPatience cards) | Fractional device pixel ratio | Keep QT_SCALE_FACTOR=1, enlarge fonts |
| Pin opens a second taskbar button | AUMID mismatch | Section 7 |
Pin ignores changes to wslg-qt |
Pin is a stale copy with old arguments (an explicit env value overrides the wrapper's defaults) |
Fix the Start shortcut, unpin, re-pin (section 7) |
| Start entry shows Tux | Icon only exists as SVG, or not at a size WSLg searches | PNGs in hicolor/96x96 etc. (section 6) |
List the bitmap sizes in a cursor theme:
python3 -c "import struct,sys;d=open(sys.argv[1],'rb').read();n=struct.unpack('<I',d[12:16])[0];print(sorted({struct.unpack('<III',d[16+12*i:28+12*i])[1] for i in range(n)}))" /usr/share/icons/Adwaita/cursors/left_ptr
Check what WSLg resolved for an app:
grep -n -A8 'org.kde.konsole.desktop' /mnt/wslg/weston.log | grep -E 'Icon (file|image)|Key:'
10. File reference
| Location | Purpose |
|---|---|
%USERPROFILE%\.wslconfig |
Global WSL settings (guiApplications must not be false) |
~/.config/kdeglobals |
Dark color values, UI fonts, widgetStyle=oxygen, icon theme |
~/.config/oxygenrc |
Scrollbar width 19, arrow buttons |
/usr/local/bin/wslg-qt |
Default Qt/cursor/scale/Wayland settings for any Qt app |
/usr/local/bin/org.kde.konsole |
Konsole launcher → wslg-qt konsole |
/usr/share/icons/hicolor/*/apps/utilities-terminal.png |
PNG icons for WSLg (not package-owned; remove manually if Konsole is removed) |
%USERPROFILE%\Icons\konsole.ico, kpat.ico |
Shortcut icons |
%APPDATA%\Microsoft\Windows\Start Menu\Programs\Konsole.lnk, KPatience.lnk |
Shortcuts (AUMID-tagged for pin grouping) |
~/.config/konsolerc, ~/.local/share/konsole/WSLg.profile |
Default Konsole profile and its settings |
get-window-aumid.ps1, set-lnk-aumid.ps1 |
Read a window's AUMID / tag a shortcut with it (in the repo's windows/) |
/mnt/wslg/weston.log |
WSLg compositor log: app list, icons, scaling, window app IDs |