Skip to content

v0.8.0

Latest

Choose a tag to compare

@github-actions github-actions released this 01 Jul 03:02
d1a2cf1

[0.8.0] - 2026-06-30

Added

  • Windows apps are now grouped on the Linux menu by their Start Menu folder (#581, thanks @Milliw). The Start Menu subfolder each app lives in (e.g. Microsoft Office\Tools) is mirrored into nested sub-groups under the "winpodx" menu folder, just like Windows shows them. Renders on KDE Plasma, XFCE, Cinnamon, MATE and LXQt (the freedesktop .menu mechanism); on GNOME the apps still appear but ungrouped (its overview is a flat grid). Top-level apps and apps with no folder stay directly under "winpodx".
  • Your [pod] keyboard setting now drives the FreeRDP session keyboard layout (#660, thanks @lsvab). The locale you pick for the Windows install (e.g. keyboard = "hu-HU") is now mapped to the matching Windows layout and passed to FreeRDP as /kbd:layout:0x…, so a non-US keyboard works in the RemoteApp window without hand-writing rdp.extra_flags. The default en-US is left untouched (FreeRDP keeps auto-detecting your host XKB layout, so users who never changed the setting aren't forced onto US), an explicit /kbd in rdp.extra_flags always wins, and an unmapped locale falls back to auto-detect. (Passing /kbd manually via rdp.extra_flags was already unblocked in 0.7.4.)

Changed

  • App discovery now surfaces only the apps your Windows Start Menu actually shows, by default (#581, thanks @Milliw). Previously every registered executable was scanned (registry App Paths, Chocolatey/Scoop shims, every UWP package) and dumped into the Linux menu, flooding it with uninstallers, helpers, and background processes. Discovery now defaults to Start-Menu-only: Start Menu shortcuts, Start-Menu-visible UWP apps (intersected with Get-StartApps), and the OS essentials (File Explorer / Calculator / Settings). Turn the old behaviour back on with winpodx config set desktop.full_app_scan true or the Settings → "Discover all installed apps (not just Start Menu apps)" checkbox — useful for portable apps that have no Start Menu entry. Takes effect on the next winpodx app refresh.
  • Bundled rdprrap bumped 0.1.3 → 0.3.0. rdprrap (the multi-session RDP wrapper that lets each RemoteApp window get its own session) now derives its termsrv.dll patch sites dynamically — it disassembles each target function at runtime and encodes the patch bytes, instead of relying on hardcoded struct offsets / register choices / byte templates. This keeps multi-session working across Windows build-to-build termsrv.dll struct-layout shifts. OEM version 27 → 28, so existing installs pick it up on the next winpodx guest sync / apply-fixes.

Fixed

  • The GUI no longer crashes (SIGSEGV) from a layout-recursion when app names are long/CJK or the app list is empty (#553, thanks @hermitguo). Word-wrap QLabels inside the resizable app-list scroll area (the empty-state panel, the launcher tiles) had a wrap width that tracked the viewport, so their height fed back into their width and re-entered QBoxLayout::setGeometryheightForWidth without bound on Qt 6.11 — a hard segfault on startup (empty list) or right after adding a CJK-named app. Those labels now have a constant (fixed) wrap width, breaking the feedback loop.
  • The Debloat / maintenance task window now closes itself when the operation finishes (#550, thanks @ismikes). The progress BusyDialog was closed with QTimer.singleShot(0, dlg.finish) from inside the worker — but a bare threading.Thread has no Qt event loop, so that timer never fired and the window hung open until dismissed by hand (the v0.7.2 change only fixed when the worker starts, not the close). BusyDialog.finish() is now signal-based, so a cross-thread close queues accept() onto the GUI thread and the window closes on completion (Debloat, Grow Disk, Sync Guest, Apply Fixes).
  • "Refresh Apps" in the GUI no longer crashes (SIGSEGV) on completion. The discovery worker (a parentless, Python-owned QObject) had two delete paths — its own deleteLater on the worker thread and the Python ref-drop on the main thread. Qt6 emits QThread.finished before flushing the worker's deleteLater, so the cleanup slot dropped the last Python ref while that delete was still in flight, double-freeing the worker across threads (QObject::~QObject segfault). Now there is exactly one delete path (the ref-drop, after thread.wait() confirms the worker thread is dead), the start guard also bails on a live thread ref (so a fast re-click can't drop a still-finishing worker), and the window joins in-flight worker threads on close.
  • The GUI no longer crashes (SIGABRT) when a background worker reads the display scale. QGuiApplication.screens() is GUI-thread-only, but it was reachable from worker threads (the Info panel's gather_info, etc.), which spammed QObject::setParent: ... different thread warnings and could abort the whole app with __cxa_pure_virtual during the worker's thread teardown — surfacing as the GUI dying on a refresh. The Qt scale probe now short-circuits to None off the main thread and falls back to the subprocess/env detection.
  • winpodx app refresh now removes apps that are no longer discovered, not just adds new ones (#581). A refresh used to only ever add entries; discovered apps that vanished — an app uninstalled inside Windows, or everything dropped by the new Start-Menu-only default — lingered in the Linux menu until manually deleted. Refresh now prunes the stale discovered profiles (and their launchers) so the menu actually migrates to the current set. Manually-added apps (~/.local/share/winpodx/apps/) are never touched, and a failed/empty scan never wipes the menu.
  • --win-iso now actually installs from your ISO instead of downloading Windows anyway (#647, thanks @ismikes). The local ISO was staged into <storage>/custom.iso after winpodx setup had already run compose up — so the container had booted and dockur had started its Microsoft download before the file existed (dockur looks for custom.iso the moment it boots). The staging now happens inside winpodx setup, after the storage path is resolved but before the container is (re)created, so dockur finds the ISO and installs from it. Also exposed as winpodx setup --win-iso <path>.
  • The reverse-open listener now self-heals on app launch instead of staying dead until the next pod start. A winpodx pod stop / tray Quit stops the listener (stop_listener()); while the pod kept running, nothing re-spawned the watcher, so "Open with → a Linux app" from Windows silently did nothing. ensure_ready (every winpodx app run / GUI launch) now idempotently ensures the listener is up when reverse_open is enabled. Surfaced during the v0.7.4 smoke.

Contributors

Thanks to everyone who reported issues fixed in this release: @Milliw (#581), @lsvab (#660), @ismikes (#647, #550), @hermitguo (#553), and @liveifsh (#659).