From 3721b6816d639a8f9c5aeccd568e457b113a1236 Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Mon, 27 Jul 2026 19:25:47 +0200 Subject: [PATCH] chore(release): bump workspace version to 0.20.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 24 commits since v0.20.0. Patch, not minor: entirely fixes and hardening on top of last release's session⇄game work, nothing new to opt into. Headline fixes: three Windows install blockers reported within hours of 0.20.0 (a false conflicting-host detection, a broken winget log-path switch, missing package-source instructions), GameStream/Moonlight compat flipped back to opt-in on fresh installs, three gamescope Game Mode takeover faults that could black out a Linux machine or strand it on a host restart, a deactivated laptop panel misdiagnosed as a blind spot instead of a named stall cause, and the PyroWave high-bitrate latency-creep bundle (clock re-sync starvation, wire bitrate overshoot, backlog buildup, ABR probe false-congestion). Wire protocol stays at 2, the embeddable C ABI at 13 and the Windows virtual-display driver protocol at 6, unchanged from 0.20.0 — no embedder rebuild required, 0.18/0.19/0.20 hosts and clients mix freely. Notes authored ahead of the tag per docs/releases/README.md. Co-Authored-By: Claude Sonnet 5 --- Cargo.lock | 56 ++++++++++++++++++++-------------------- Cargo.toml | 2 +- docs/releases/v0.20.1.md | 53 +++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 29 deletions(-) create mode 100644 docs/releases/v0.20.1.md diff --git a/Cargo.lock b/Cargo.lock index 7c1b4a03..64e6ea0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1022,7 +1022,7 @@ dependencies = [ [[package]] name = "display-disturb" -version = "0.20.0" +version = "0.20.1" dependencies = [ "windows 0.62.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2201,7 +2201,7 @@ dependencies = [ [[package]] name = "latency-probe" -version = "0.20.0" +version = "0.20.1" [[package]] name = "lazy_static" @@ -2306,7 +2306,7 @@ dependencies = [ [[package]] name = "libvpl-sys" -version = "0.20.0" +version = "0.20.1" dependencies = [ "bindgen", "cmake", @@ -2341,7 +2341,7 @@ checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "loss-harness" -version = "0.20.0" +version = "0.20.1" dependencies = [ "punktfunk-core", ] @@ -2830,7 +2830,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pf-capture" -version = "0.20.0" +version = "0.20.1" dependencies = [ "anyhow", "ashpd", @@ -2851,7 +2851,7 @@ dependencies = [ [[package]] name = "pf-client-core" -version = "0.20.0" +version = "0.20.1" dependencies = [ "anyhow", "ash", @@ -2875,7 +2875,7 @@ dependencies = [ [[package]] name = "pf-clipboard" -version = "0.20.0" +version = "0.20.1" dependencies = [ "anyhow", "ashpd", @@ -2893,7 +2893,7 @@ dependencies = [ [[package]] name = "pf-console-ui" -version = "0.20.0" +version = "0.20.1" dependencies = [ "anyhow", "ash", @@ -2914,7 +2914,7 @@ dependencies = [ [[package]] name = "pf-encode" -version = "0.20.0" +version = "0.20.1" dependencies = [ "anyhow", "ash", @@ -2938,7 +2938,7 @@ dependencies = [ [[package]] name = "pf-ffvk" -version = "0.20.0" +version = "0.20.1" dependencies = [ "ash", "bindgen", @@ -2947,7 +2947,7 @@ dependencies = [ [[package]] name = "pf-frame" -version = "0.20.0" +version = "0.20.1" dependencies = [ "anyhow", "libc", @@ -2959,7 +2959,7 @@ dependencies = [ [[package]] name = "pf-gpu" -version = "0.20.0" +version = "0.20.1" dependencies = [ "anyhow", "pf-host-config", @@ -2973,11 +2973,11 @@ dependencies = [ [[package]] name = "pf-host-config" -version = "0.20.0" +version = "0.20.1" [[package]] name = "pf-inject" -version = "0.20.0" +version = "0.20.1" dependencies = [ "anyhow", "ashpd", @@ -3006,14 +3006,14 @@ dependencies = [ [[package]] name = "pf-paths" -version = "0.20.0" +version = "0.20.1" dependencies = [ "tracing", ] [[package]] name = "pf-presenter" -version = "0.20.0" +version = "0.20.1" dependencies = [ "anyhow", "ash", @@ -3028,7 +3028,7 @@ dependencies = [ [[package]] name = "pf-vdisplay" -version = "0.20.0" +version = "0.20.1" dependencies = [ "anyhow", "ashpd", @@ -3060,7 +3060,7 @@ dependencies = [ [[package]] name = "pf-win-display" -version = "0.20.0" +version = "0.20.1" dependencies = [ "anyhow", "pf-paths", @@ -3072,7 +3072,7 @@ dependencies = [ [[package]] name = "pf-zerocopy" -version = "0.20.0" +version = "0.20.1" dependencies = [ "anyhow", "ash", @@ -3280,7 +3280,7 @@ dependencies = [ [[package]] name = "punktfunk-client-android" -version = "0.20.0" +version = "0.20.1" dependencies = [ "android_logger", "jni", @@ -3296,7 +3296,7 @@ dependencies = [ [[package]] name = "punktfunk-client-linux" -version = "0.20.0" +version = "0.20.1" dependencies = [ "anyhow", "async-channel", @@ -3312,7 +3312,7 @@ dependencies = [ [[package]] name = "punktfunk-client-session" -version = "0.20.0" +version = "0.20.1" dependencies = [ "anyhow", "pf-client-core", @@ -3327,7 +3327,7 @@ dependencies = [ [[package]] name = "punktfunk-client-windows" -version = "0.20.0" +version = "0.20.1" dependencies = [ "async-channel", "ffmpeg-next", @@ -3346,7 +3346,7 @@ dependencies = [ [[package]] name = "punktfunk-core" -version = "0.20.0" +version = "0.20.1" dependencies = [ "aes-gcm", "bytes", @@ -3378,7 +3378,7 @@ dependencies = [ [[package]] name = "punktfunk-host" -version = "0.20.0" +version = "0.20.1" dependencies = [ "aes", "aes-gcm", @@ -3462,7 +3462,7 @@ dependencies = [ [[package]] name = "punktfunk-probe" -version = "0.20.0" +version = "0.20.1" dependencies = [ "anyhow", "mdns-sd", @@ -3476,7 +3476,7 @@ dependencies = [ [[package]] name = "punktfunk-tray" -version = "0.20.0" +version = "0.20.1" dependencies = [ "anyhow", "ksni", @@ -3499,7 +3499,7 @@ checksum = "d55d956fa96f5ec02be2e13af0e20391a5aa83d6a074e3ad368959d0fab299ea" [[package]] name = "pyrowave-sys" -version = "0.20.0" +version = "0.20.1" dependencies = [ "bindgen", "cmake", diff --git a/Cargo.toml b/Cargo.toml index 104a7de2..cdf5cfe4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,7 +49,7 @@ exclude = [ ndk = { path = "clients/android/native/vendor/ndk" } [workspace.package] -version = "0.20.0" +version = "0.20.1" edition = "2021" rust-version = "1.82" license = "MIT OR Apache-2.0" diff --git a/docs/releases/v0.20.1.md b/docs/releases/v0.20.1.md new file mode 100644 index 00000000..c89271dd --- /dev/null +++ b/docs/releases/v0.20.1.md @@ -0,0 +1,53 @@ +Update whenever it suits you — the app and the machine you stream from can still be updated one at a time, and everything already paired keeps working. This release is entirely fixes and hardening on top of last release's session⇄game work — nothing new to opt into. + +## Fixed: installing or updating the Windows host + +Three separate reports came in within hours of the last release, all blocking install: + +- **`winget install` could fail outright if you'd ever had another streaming host on the machine** — even one you had since disabled or mostly uninstalled. A leftover, disabled service or an empty folder from an old install was enough to trip the "conflicting host" check and abort. Only a host actually set to start on its own counts now. +- **Installing through a package-manager app (like UniGetUI) could fail with a file-path error** before the install wizard ever appeared, because of a broken setting the installer passed itself. Fixed. +- **The package source instructions were incomplete.** `winget install unom.PunktfunkHost` says "no package found" until you've pointed winget at Punktfunk's own source, once per machine — the command for that is now spelled out. + +## Fixed: Moonlight compatibility no longer turns on without asking + +A fresh Windows install used to enable Moonlight-app compatibility silently, with no checkbox ever shown — even though that mode pairs over a less secure connection and the host warns about it on every start. It's opt-in now. Existing installs are untouched either way; Punktfunk's own clients were never affected. + +## Fixed: switching into Steam's Game Mode on Linux could black out the machine + +Last release shipped the permission needed to properly take over the screen for Steam's Game Mode — and surfaced a few sharp edges that only show up once that takeover is actually live: + +- **The takeover could kill Punktfunk's own background service a few seconds later**, leaving the display dark with nothing left to bring it back except a physical console or SSH. +- **It could also hang waiting on a permission prompt nobody could see**, delaying recovery until well after the stream had already dropped — or act on a leftover marker file from months ago and jump the machine to the desktop for no reason. +- **Restarting the host mid-stream** — including a routine update — **could leave the display stuck off**, since nothing told the screen to come back. + +All three are fixed. Recognizing the machine's built-in Steam Game Mode may now need a one-time permission on some distributions; installing or updating normally takes care of it. + +## Fixed: a laptop with its built-in screen turned off stuttered constantly + +On a laptop with two graphics chips and the internal screen switched off — a common setup for streaming from a laptop docked to a TV or monitor — streaming stuttered roughly every two seconds, for the whole session. Punktfunk now recognizes a dark-but-connected laptop screen as the cause and points at the actual fix, instead of pointing at an external monitor that isn't the problem. + +## Fixed: latency creeping up over the course of a fast, high-bitrate stream + +On a fast local network, especially at higher bitrates, latency could climb steadily over a long session instead of staying flat. Several separate causes are fixed at once: the stream's internal clock sync could get starved by a busy connection and let the two ends' clocks drift; a stream mode could put more data on the wire than its bitrate setting actually allowed; a slow-to-decode moment could build up a backlog that took a while to work through instead of catching up immediately; and the one-time startup speed test could be mistaken for real network congestion and permanently cap the stream below what the connection could actually handle. + +## Fixed: missing cover art looked broken + +A library entry with no cover art showed as an empty grey box, which read as something that failed to load. It now shows a controller icon instead, so "no art yet" looks intentional rather than broken. + +## Improved: the Windows app now keeps its own log file + +The desktop app writes its own log to `%LOCALAPPDATA%\punktfunk\logs\client.log` now, instead of only printing to a console window that a normal launch never shows. If you're ever asked to send logs for a problem, this is where they are. + +## Under the hood (for developers) + +- **Nothing changed on the wire or at the API boundary.** Streaming protocol stays at version **2**, the embeddable C ABI at **13**, the Windows virtual-display driver protocol at **6** — 0.18–0.20 hosts and clients keep mixing freely. +- **Windows conflict detection** now keys on the competing service's `Start` registry value (0–2 = boot/system/auto only), matching the tray's own dormant-is-harmless logic from last release; install directories no longer count. +- **The winget `Log` switch used the literal string `|LOGPATH|`** instead of winget's actual `` substitution token, so Inno received an illegal filename on any install that requested a log (UniGetUI does by default). Guarded by a new manifest check. +- **`gamestream` installer task lost its default-checked flag**; a silent/unattended install now lands `PUNKTFUNK_HOST_CMD=serve`. `/MERGETASKS=gamestream` opts in. Fresh installs only — `GamestreamParam` already omitted the flag on upgrades. +- **The gamescope display-manager takeover** now calls privileged `systemctl` verbs non-interactively (`--no-ask-password`) so a headless polkit prompt can no longer block the stream's own recovery thread; `session_select_requested`'s sentinel baseline is now recorded at takeover time as well as at successful launch, closing a window where a months-old `~/.config/steamos-session-select` write could false-positive a session-select honor; and `punktfunk-host` now handles SIGTERM/SIGINT by restoring the display manager it stopped (20 s grace) before exiting, so a `systemctl --user restart` or package upgrade mid-takeover can't strand the box. The takeover also now ensures the invoking user has systemd lingering enabled before touching the display manager — without it, stopping the DM stops the user's own service manager ~10 s later and takes the host down with it. +- **A new `internal_panel` target class** lets the exclusive-topology stall detector name a deactivated eDP/LVDS laptop panel as a disturbance suspect; previously the suspect list was filtered to external physicals only, so the one display responsible on a hybrid laptop reported as none. `EvtIddCxMonitorI2CTransmit/Receive` now answer every DDC/CI probe against the virtual monitor with an immediate `STATUS_NOT_SUPPORTED`, so third-party brightness/monitor tools stop occupying win32k's serialized physical-monitor path on it. The swap-chain drain thread now falls back to `TIME_CRITICAL` priority if MMCSS registration is refused, and raises `IddMinimumVersionRequired` 4 → 10 to use `IddCxSetRealtimeGPUPriority`. +- **Clock re-sync** now spaces its probe rounds ~7 ms apart, tracks a running best-RTT guard band instead of a static connect-time floor, and applies the best batch of a rejection streak after three consecutive rejections rather than drifting unbounded. +- **A new per-frame `WireBudget`** (shared between encoder backends) tracks the real bitstream-to-wire inflation ratio for datagram-aligned PyroWave sessions and deflates the rate-control target by it, so the configured bitrate pin holds on the wire rather than on the raw codec bitstream. +- **The pre-decode frame channel now drains to the newest AU for all-intra (PyroWave) streams**, since those have no reference chain forbidding a mid-stream drop — capping any standing backlog at roughly one frame instead of ratcheting between the coarse jump-to-live thresholds. +- **The ABR capacity probe's first post-probe report window is now discarded outright**, rather than measured, so the probe's own deliberate overload can no longer read as session congestion and permanently end slow-start early. +- New `display-disturb` dev tool for reproducing DDC/CI and modeset-class display disturbances on demand during stall-immunity testing; not shipped to end users.