Wire-compatible with 0.25.x — everything you have already paired keeps working, and you can update one side at a time. Nothing here changes how a host and a client agree on what to send each other, so an old client on a new host, or the other way round, streams exactly as it does today.

Most of this release came from people reporting what 0.25.0 did on their own machines. Bluetooth headphones get their sound back on iPhone and iPad, a Steam Deck stops losing HEVC halfway through the week and stops moving the game behind the Steam menu, games running inside a gamescope session are finally told the refresh rate they are actually being given, and a Windows host recovers its display after the machine sleeps. Linux hosts also get a substantial round of streaming performance work.

## TL;DR

- **Bluetooth headphones had no game audio on iPhone and iPad.** On the default settings the phone played through its own speaker instead of your headset. Update the client.
- **On a Steam Deck, opening the Steam menu also moved the game.** The same controller drove both, so browsing the menu was steering whatever was running on the host behind it — an invisible second player. Update the client.
- **A Steam Deck could lose HEVC and drop to H.264.** The "Full chroma" switch was promising something no Deck can decode, and the cost was the entire codec rather than a little crispness. It looked random because it is a per-profile setting. Update the client.
- **Games in a gamescope session were told their display was 60 Hz.** A game capped itself to 60 while your stream ran at 120, and the in-session display settings offered nothing else. Update the host.
- **One capture hiccup could slow a Linux host down until you restarted it.** A single timeout switched that host to the slow capture path for every session afterwards — including sessions with an entirely different desktop, which had never failed at anything — and said nothing.
- **Windows hosts stopped recovering after sleep**, and **"Native resolution" streamed a smaller, blurry picture** on desktops that scale fractionally. Both fixed; update the host and the client respectively.

## Before you update

Most people need to do nothing. Check this list if any of it applies to you.

- **Linux, if the virtual Steam Deck controller never attached on 0.25.0:** this is why. 0.25.0 moved that permission onto a new `punktfunk` group, but four of the six ways of installing never created the group — so the permission step failed quietly, and `sudo usermod -aG punktfunk "$USER"` answered "group does not exist". Arch upgrades, Nix, the Bazzite system extension and the Steam Deck script are all fixed. After updating, run `sudo usermod -aG punktfunk "$USER"` and log back in. Ordinary virtual gamepads were never affected.
- **Steam Deck, if `update.sh --pull` was aborting:** it no longer does, and it clears the mess it made. The updater had been rewriting one of its own tracked files on every run, so the next update refused to start and deleting that file by hand was the only way through. Nothing needs deleting now.
- **If you turned "Full chroma" on and HEVC came and went:** leave the setting wherever you like. It no longer costs you the codec, and on hardware that cannot decode it the option simply stops being offered.
- **Steam Deck, if you have been told the client was up to date:** it may not have been. The plugin's client update check had never once succeeded since 0.24 and reported "up to date" whenever it failed. Update the plugin, then check again.

## New

- **The statistics overlay is reachable on an Apple TV.** There had been no way to it from inside a stream at all — every other client cycles it with a key combination or a three-finger tap, and a TV has neither. Press **Select + X** on a controller, or **hold Play/Pause** on the Siri Remote. A tap on Play/Pause still right-clicks as before.
- **An OLED palette.** A thirteenth colour scheme for the controller interface whose dark half is genuinely black — pixels switched off rather than very dark grey — with a faint indigo ember in one corner so the background still goes somewhere. On the Steam Deck, TV and handheld interfaces.
- **Choose when the controller interface appears.** The switch that turns it on had also been deciding that it shows up only while a controller is plugged in. Those are now separate: keep the old behaviour, or have it always on. On every settings surface.
- **Hide a single game.** Visibility used to be all-or-nothing per source — a Proton tool the filter missed, a demo, or something you would rather not have on the TV meant hiding its whole launcher. Individual titles can now be hidden, and the choice survives a re-scan.
- **A gamescope session can offer more refresh rates** in Steam's in-session display settings, and the Deck's own performance overlay can be composited into what you stream instead of staying on the local screen. Both are off unless you ask for them.
- **The patched gamescope is installable on Fedora and on Debian and Ubuntu**, not only Arch — so a virtual display in game mode no longer depends on which distribution you picked.
- **Add-ons can publish games the host has no way to name.** A library add-on can now list a title whose launch is entirely its own business — an emulator with the core and flags you configured, say — and the host asks the add-on what to run at the moment you press play. Nothing runnable is stored or sent to a client, and an emulator that has moved is picked up on the next launch instead of leaving a dead tile behind.

## Improved

- **Audio catches jitter before you can hear it.** The rule that decides how much sound to keep buffered only ever learned from failures you could already hear: it waited for three audible dropouts before deepening the buffer, and it re-tested a shallower one every few quiet seconds, paying for a wrong guess with a click, forever. It now reads the near-misses nobody hears, backs off after a probe that fails, and refills in one go rather than limping. Simulating ten minutes of a Wi-Fi power-saving pattern went from roughly two thousand audible events to nine. Update the client.
- **A gamescope session says so when its refresh rate has been lost.** If something in the session's own configuration drops the setting that carries it, the stream still runs and still looks right while the game underneath is capped to 60 — which is exactly the kind of fault that costs a week to find. It is now one line in the log.
- **The low-latency wavelet codec got a serious round of work on Linux hosts.** It encodes on the same graphics cores your game is using, so under heavy load it was being crowded out — the encode step measured around 2 ms idle and 15–18 ms at 95% game load, with the stream's frame rate collapsing along with it. The encoder can now work on two frames at once, and the capture path asks your desktop for enough buffers to keep up instead of taking whatever it was handed without ever expressing a preference. The switch that asks your graphics card to put that work ahead of the game's had also never been applied on Linux, and now is — though it stays dormant on an ordinary install, because switching it on requires a system privilege that turns out to stop KDE recognising the host at all. There is more on that below.
- **Jumbo frames can now be proven rather than hoped for.** The whole path was dead code: the discovery that was supposed to find a larger packet size could never settle above the ordinary limit, so the setting that grows mid-stream was unreachable on every path that has ever existed. A network that genuinely carries big packets is now detected, and a wavelet session starts at the large size instead of never getting there — around six times fewer packets per frame. Still opt-in, on both ends.
- **The configuration documentation caught up with 0.25**, including the jumbo-frame option and several other settings that had shipped with nothing written about them.

## Fixed

- **Bluetooth headphones got no game audio on iPhone and iPad.** With the microphone on — which is the default — the app was forcing output to the phone's own speaker, and that override outranks a Bluetooth headset. Wired headphones beat it, which is why plugging in a cable made it look correct. Turning the microphone off was the accidental workaround people found. Audio now goes to whatever you have connected, and dropping a headset mid-stream no longer lands on the earpiece. Update the client.
- **On a Steam Deck, the Steam menu and the Quick Access Menu also moved the game.** Both are driven by the same physical controller the client is forwarding, so opening either one played the game behind it at the same time — a second, invisible player picking things up and walking into walls while you browsed. Steam masks a normal game here and cannot mask this one, because the client deliberately forwards your real controller rather than Steam's stand-in, which has no gyro, trackpads or paddles. The stream now stops forwarding while an overlay has the controller, and hands it back without the button that dismissed the menu firing in the game. Update the client.
- **Streaming a KDE desktop keeps working.** An interim build of this release gave the host an extra system privilege, so that the wavelet encoder could ask your graphics card for priority. On KDE the side effect was total: KDE decides whether it trusts a program by looking up which file it is running from, the system refuses that lookup for any program holding a privilege, and so KDE stopped recognising the host at all — desktop streaming failed outright, complaining about a missing screen-capture interface, and it survived a clean reinstall of both host and client. Reported from CachyOS on both NVIDIA and AMD. No Linux package grants that privilege any more, on any of the five ways we ship, and upgrading strips it from a machine that already has it. If a host somehow holds one anyway, the error now names it and gives you the command that undoes it, instead of blaming a missing desktop file.
- **One capture timeout could slow a Linux host down for good.** Two very different problems shared a single switch: a graphics driver that genuinely cannot handle what your desktop produces, and a desktop that simply happened to be restarting. The second was being treated as permanently as the first, so a single moment of bad timing put that host on the slow capture path for every session until the process was restarted — including sessions against a completely different desktop that had never failed at anything, and with nothing at all in the log. The two now have the lifetimes they should, and a capture that works credits the budget back.
- **A wavelet-codec session could quietly fall back to slow capture and log nothing whatsoever.** The warning was asking a host-wide question about a per-session decision, so a degraded host and a healthy one produced identical logs while one of them touched every pixel on the processor.
- **"Full chroma" could cost a Steam Deck its codec.** The client advertised the feature on the strength of the setting alone, with nothing checking whether the device could decode it — and no AMD hardware can. The host grants it on HEVC only, so a Deck with the switch on lost HEVC entirely and reconnected on H.264. It looked intermittent because it is a per-profile setting: a "Work" profile lost HEVC where "Game" kept it, on the same machine and the same host. The client now asks the graphics driver the same question the decoder will, so the advertisement and what actually works cannot disagree.
- **The decoder triage tool reported the opposite of the truth on a Steam Deck.** `--probe-decode` ran before the Deck's own video-decode option was applied, so it said no hardware decoding was available on a machine that had been decoding on it all along — and anyone triaging a Deck with it was led away from the answer.
- **Every gamescope session ended in a crash.** The graphics device was being torn down after the driver behind it had already been unloaded, so the process fell over on the way out — after the compositor had finished, which is why the stream looked perfectly fine and this surfaced only as crash reports piling up. Five in one ordinary ten-minute session.
- **A Windows host no longer refuses its own recovery after sleep.** When a machine woke with its virtual display detached, every repair attempt came back refused — because the host was still holding the device open, and that is precisely what blocks the reset the repair depends on. Stopping the whole service by hand was the only thing that worked. The host now lets go before it asks.
- **"Native resolution" streamed the wrong resolution on fractional scaling.** A 2560×1600 laptop panel at 150% negotiated 1706×1066 and streamed a visibly soft picture: the desktop reports its size in scaled units, and that was being read as pixels. The window itself was not high-density either, so even a correct stream was shrunk and then stretched back. Both are fixed, and "Match window" was quietly losing the same detail. Wayland desktops that scale fractionally — KDE among them.
- **Pinning a compositor silently cancelled dedicated game sessions.** A host set to launch games into their own session went on saying it did while every launch landed on the desktop instead, with nothing in the log either way — on the machine that surfaced this, for thirty days. The pin still wins, but it now says so and names itself. The same pin also made a configured session-recovery command unreachable, and a mid-startup mode change could take the whole GNOME desktop down with it, killing the game it had just launched.
- **The Steam Deck plugin's "update the client" had never once detected an update.** It asked about the app without saying which release channel, the answer was refused as ambiguous, and a failed check was displayed as "up to date" — so it went a week unnoticed while offering to update only itself. A check that cannot run now says so.
- **The Steam Deck updater kept sabotaging its own next update.** It rewrote a tracked generated file on every run, so the following update refused to start and hand-deleting that file was the only way past it. It no longer creates the mess, and it clears the one already there.
- **Add-on scanners appeared in the console sidebar they had opted out of**, their settings could not be reached from the Library screen, and syncing artwork from a local folder failed — one disagreement about how a folder path is written, and a change that had never been published. Library source settings also stopped opening at all after add-ons moved to their own address.
- **A fix to the add-on toolkit could never reach an add-on already installed**, because the copy each one runs was pinned at install time and nothing updated it.
- **A routine system update can no longer leave an Arch or CachyOS host unable to start**, and the rebuild that ships the corrected package no longer fails on a step that cannot exist during a rebuild. This is the same fault 0.25.0-2 was published for; it is now fixed in the pipeline rather than by hand.
- **A stale virtual monitor left behind by a crash is cleaned up properly**, and when the cleanup is refused it says why instead of failing silently or aiming at a device that is no longer there.

## For developers

Protocol, ABI, driver and add-on detail — the version table, the new environment variables and what did *not* move — is in [CHANGELOG.md](https://git.unom.io/unom/punktfunk/src/tag/v0.26.0/CHANGELOG.md).

The short version: **nothing breaks.** The wire protocol stays at 2 and the C ABI stays at 17, so this release adds no new call, no new message and no new capability bit.

If you write a library add-on, there is one addition worth reading about: the new launch kind that lets you publish a title the host cannot name, and the add-on toolkit release that carries it.
