• v0.9.0 d0faebf582

    v0.9.0
    audit / bun-audit (push) Successful in 11s
    ci / web (push) Successful in 51s
    apple / swift (push) Successful in 1m10s
    ci / docs-site (push) Successful in 1m9s
    audit / cargo-audit (push) Successful in 2m36s
    ci / bench (push) Successful in 5m53s
    windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Successful in 3m8s
    windows-msix / package (x64, C:\Users\Public\ffmpeg, , x86_64-pc-windows-msvc, C:\t) (push) Successful in 1m2s
    android-screenshots / screenshots (push) Successful in 2m58s
    decky / build-publish (push) Successful in 18s
    ci / rust (push) Successful in 17m43s
    release / apple (push) Successful in 9m55s
    apple / screenshots (push) Successful in 5m56s
    arch / build-publish (push) Successful in 14m2s
    android / android (push) Successful in 15m44s
    deb / build-publish (push) Successful in 15m15s
    web-screenshots / screenshots (push) Successful in 2m45s
    linux-client-screenshots / screenshots (push) Successful in 8m20s
    rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 13m58s
    rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 13m57s
    docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 42s
    docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 9m30s
    docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 9s
    docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 11m34s
    docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 13s
    flatpak / build-publish (push) Successful in 7m14s
    windows-host / package (push) Successful in 8m1s
    windows / build (aarch64-pc-windows-msvc) (push) Successful in 54s
    windows / build (x86_64-pc-windows-msvc) (push) Successful in 1m17s
    docker / deploy-docs (push) Successful in 14s
    Stable

    enricobuehler released this 2026-07-09 21:02:37 +00:00 | 6 commits to main since this release

    Wire-compatible with 0.8.x — existing pairings and clients keep working (the new bitrate control messages and IPv6 shard sizing ride existing negotiation; old clients simply follow).

    Windows client — the Vulkan session client arrives

    The Windows client now runs the same Vulkan session client as Linux for every stream (the WinUI shell hands off in a single-window handoff with a shared settings store): verified live at 10-bit HEVC via Vulkan Video on both AMD and NVIDIA. For GPUs without Vulkan Video — Intel's Windows driver foremost, which previously fell all the way to CPU decode — a D3D11VA tier slots in between: the decode chain is now vulkan → d3d11va → software. Along the way: a game library page, remembered session-window placement, the local cursor properly hidden while captured, the Help button renamed to Shortcuts, and the session process names itself "Punktfunk Session".

    Codecs — honest advertisement, AV1 end to end

    Client codec pickers used to send a preference the host threw away — the native path hardcoded HEVC for every GPU backend. The host now advertises what its encoder actually supports, so choosing H.264 or AV1 does what it says. To match: the Apple clients gain AV1 hardware decode (zero-copy OBU plumbing, advertised only where the silicon supports it), and a host bug that stamped HEVC config onto the AV1 encoder union is fixed — NVENC AV1 sessions actually open now (verified live: 10-bit AV1, macOS client → RTX 4090).

    Adaptive bitrate

    With bitrate set to Automatic, the client now runs an AIMD controller against loss, FEC-unrecoverable frames, and one-way-delay rise: it re-targets the host encoder mid-stream (the encoder rebuilds in place, first frame at the new rate is an IDR — the proven mode-switch resync, minus pipeline churn). Congested links back off within ~1.5 s instead of stuttering indefinitely; recovery is additive.

    Console shell (Steam Deck / gamescope)

    The Skia console UI grows from the single library coverflow into a complete couch shell: host carousel with presence pips and paired locks, wake & connect, PIN pairing, settings, an on-screen keyboard, and screen transitions — a Deck session is self-sufficient end to end without touching the desktop shell. Pressing A to wake a host now gates input instantly behind an optimistic "Waking…" card.

    Decky plugin (Steam Deck)

    The Quick-Access plugin grows from a launcher into real host management: add a host by address, edit or forget saved hosts, and reset plugin state (the client identity survives, so nothing needs re-pairing). Behind it, the flatpak client's known-hosts store becomes the single source of truth through new headless CLI modes (--list-hosts / --add-host / --set-host / --forget-host / --reset / --reachable) — the plugin and the desktop client always agree instead of keeping duplicate lists. Presence pips are probe-backed (the same mDNS-independent reachability check as below), and the plugin's settings gain the video codec picker (Auto / HEVC / H.264 / AV1).

    Presence & discovery

    • Reachability-probed presence — the display-side companion to 0.8.4's dial-first connect fix: saved hosts are probed with a bounded, mDNS-independent QUIC reachability check, so a host reached over Tailscale/VPN/multicast-filtering LANs shows as present instead of "Offline".
    • mDNS discovery is pinned to IPv4 on every client — no more phantom duplicate hosts from v6 announcements.

    Host

    • The metronomic ~4 s stutter investigation lands its first round of fixes: display-poller software (SteelSeries-GG and friends) or display-topology churn holding the Windows display-config lock could stall the virtual-display capture path every few seconds — IDD capture is now immune to those stalls and to transient descriptor flaps, and when a recovery loop does turn metronomic the host now names it in its log, measured period included, instead of leaving nothing to find. Ghost IddCx adapters are also filtered out of the GPU inventory — every Windows host used to list its render GPU twice, with the picker offering a dead twin.
    • Per-client display scaling finally works on GNOME: Mutter mints a fresh EDID serial for every virtual monitor, so the scale you set never re-matched on reconnect (and our topology apply then clobbered it to 1.0). The host now persists and re-applies the scale itself.
    • --no-mdns / PUNKTFUNK_MDNS and punktfunk1-host --pairing-pin for headless/container setups.

    Apple clients

    • Game Mode is enabled across Apple platforms, and Allow VRR is user-configurable on macOS and iOS.
    • Opt-in V-Sync with a reworked presenter; the cross-client shortcut set + start-of-stream banner reach the Apple clients.
    • A stream error now returns to windowed mode (previously only a clean disconnect did), and stale shortcut copy in settings was fixed.

    Android

    • Custom resolutions in both settings UIs.
    • The stats HUD headline becomes true capture→displayed latency via the OnFrameRendered display stage.
    • The 3-finger stats tap actually fires now — the third finger landing used to register as a two-finger scroll and disqualify the tap.

    Stability & networking

    • The intermittent "device lost" stream killer is fixed on the Vulkan clients: a shared-VkQueue race and a swapchain-recreate destroy-in-use.
    • IPv6 sessions get correctly sized packets: the host sizes each session's FEC shard payload from the QUIC remote's address family (1408 over v4, 1388 over v6) — zero wire change.

    Web console & packaging

    • Web console polish: favicon, consistent Punktfunk casing, a toast on display-save, and the stop-session button is muted instead of alarm-red while nothing is running.
    • The client Flatpak offline build is fixed (a Windows-only git dependency had crept into the sandbox manifest).
    Downloads