140 commits since v0.33.0. The release is a control surface for everyone who streams to a screen they hold: a six-button ring opened by a two-finger twist, editable by using it rather than by reading a list, plus an on-screen controller on phones and tablets. The Steam Controller 2 passthrough leaves Linux. It now captures from Apple and Android devices and reaches a Windows host, still presented as itself rather than flattened into a generic pad. This is not a drop-in for embedders. The C ABI moves 26 to 28, and v27 widens PunktfunkHidOutput from 19 to 85 bytes -- a recompile, not a relink, with the version equality check as the guard. Every other version number stands still: wire 2, driver 6, gamepad channel 3. Windows packagers additionally need the pf_gamepad package rebuilt, for its eighth hardware id. api/openapi.json is regenerated rather than re-stamped this time, and the surface is verified rather than assumed: punktfunk-host compiles on macOS again, so the staleness test runs here. Every prior release carried a caveat for exactly that reason. Also prunes PUNKTFUNK_STANDBY_SINK_KEEP from the undocumented-env baseline, which the drift gate has warned about since #452 documented it while still exiting 0. Gates on the Mac: cargo fmt --all --check, cargo test -p punktfunk-core --lib --features quic (511 passed, 0 failed), the C ABI harness (abi_version=28), the openapi staleness test, check-docs-drift.sh, check-docs-links.sh, cargo audit (2 allowed warnings, no yanked crates), both openapi copies byte-identical, and Play notes at 493/500 chars and unique.
15 KiB
This release is for everyone who streams games or a desktop with Punktfunk. It works with 0.33.x, so everything you have already paired keeps working, and you can update one side at a time.
The headline is a control surface for everyone who streams to a screen they hold. Touch has been able to move a cursor for a long time. It could not end a stream, show a keyboard, switch touch mode or send Ctrl+Alt+Del without leaving the picture. Now a two-finger twist on the stream opens a ring of six buttons under your fingers. You choose what the six are, and you edit them by using the ring itself rather than reading a list of names.
Phones and tablets also get an on-screen controller. Show it from the ring when a game wants a gamepad and you do not have one with you. The host sees a controller arrive, exactly as if you had plugged one in.
And the Steam Controller 2 goes much further than Linux. It now streams from an iPhone, iPad, Mac and Android device, and reaches a Windows host as well as a Linux one. It still arrives as itself, rather than flattened into a generic pad. That work came from a contributor, credited by name further down.
TL;DR
- A quick-action ring on the stream. Open it with a two-finger twist on a phone or tablet, a short Back on Apple TV, or Select+A on a controller anywhere.
- An on-screen controller on Android, iPhone and iPad, for a game that needs a gamepad you did not bring.
- The Steam Controller 2 now works from Apple and Android devices, and to a Windows host. Read "Before you update" if your host runs Windows.
- Linux: the app stops opening fullscreen on an ordinary desktop. Our own Flatpak told it that every machine was a Steam Deck. Flatpak is the main Linux channel, so this reached most Linux users.
- Apple: fixed a picture that froze while the sound kept playing. Only reconnecting cleared it. It now recovers on its own.
- Windows: F11 no longer ends your session. On some graphics drivers, going fullscreen dropped the stream and then blamed the connection.
What's in this release
Before you update
- Windows hosts, for the Steam Controller 2 only: reinstall the controller driver. Windows support for that pad needs a driver package your current install does not have. Run
punktfunk-host.exe driver install --gamepadand reconnect the pad. Every other controller keeps working untouched, so skip this if you do not own one. - If you keep a virtual display on "Forever", read this before sending your host to sleep. Sleep, restart and shut down now clear the virtual displays first, so a wake starts clean. A display you pinned to Forever is kept on purpose, because that pin is what holds a game running across disconnects. If a wake lands on a black screen, release that display from the console under Virtual displays.
- Windows: the tray icon's Exit entry now stops the host. It used to close only the icon and leave the host streaming. The menu says so before it acts. Signing out still leaves the host running, as before.
New
- The quick-action ring. A two-finger twist on the stream opens six buttons under your fingers, on Android, iPhone and iPad. About 10° starts it opening and 30° commits it, so letting go early winds it back in and sends nothing. The centre button opens the full catalogue and the resolution presets. Android's Back gesture opens the same ring instead of ending your session, and Apple TV opens it with a short press of Back. A controller opens it with Select+A on every client, and the host never sees those two presses.
- You edit the ring by using the ring. Tap a button to change it, drag one onto another to swap them. With a controller, the stick walks the buttons, A changes one, and Y lifts a button so A can drop it somewhere else. There is no separate list to learn.
- Custom keyboard shortcuts on the ring. Give a shortcut a name, pick its modifiers, and choose the key on a keyboard you can see. Ctrl+Shift+Esc and Alt+F4 stop needing a real keyboard on the couch.
- An on-screen controller on Android, iPhone and iPad. Show and hide it from the ring's Virtual controller button. The host sees one controller arrive when it appears and one leave when it goes, on the next free slot beside any real pad you have connected. A stick follows your thumb from wherever it lands, and the D-pad reads eight directions. A trigger reads how far down your finger sits, so a slow press stays a slow press. A finger anywhere else still drives your touch mode, so tap-to-click keeps working beside it. Choose Full, Sticks and shoulders or D-pad and face buttons, and set its opacity and size in settings.
- The Steam Controller 2 streams from Apple and Android devices. Android reads it over USB, the Puck dongle or Bluetooth; Apple over Bluetooth. The pad reaches your host as itself, so the trackpads, gyro and haptics behave the way they do when it is plugged in locally. It is on by default on Android and off on Apple. Switching it on there asks for Bluetooth permission, which is a question worth asking only from someone who owns the controller.
- Windows hosts can present a Steam Controller 2. Previously Linux only. The multi-pad Puck dongle stays Linux-only for now.
- The console tells you a device is asking to pair, wherever you are in it. A pairing request used to appear only on the Pairing page, so it waited until somebody thought to go and look. That is worst on a phone, where the page is several taps away. A notice now names the device and offers one button through to it, and the waiting list refreshes the moment the request arrives rather than up to ten seconds later.
- Every client draws the same icons. The quick-action ring showed icons in one place and words in another, because three separate apps each had their own vocabulary for the same six buttons. They now share one set, so a button looks the same wherever you meet it.
- A host card shows which system the machine runs, in place of the first letter of its name. The name is spelled out underneath anyway. A host too old to say what it runs keeps its initial.
Improved
- A switched-off TV plugged into your Windows host stops costing you frames. A standby screen on HDMI keeps Windows drawing for a head nobody is watching, and your stream pays for it. The host now switches such a screen off for the duration of the stream. On our test machine that cut the median stall from 6.3 seconds to 0.7 across sixteen alternating runs. It is an improvement rather than a cure — some stalls survive it. Only a screen that belongs to no display arrangement is ever chosen, so your laptop panel and your working monitors are never touched. If a screen must stay awake, for a capture card or a receiver, there is a setting to keep it.
- Putting your host to sleep now clears its virtual displays first. A wake used to resume onto a display built for whoever sent the machine to sleep.
- The Windows tray icon survives an update. It used to disappear on every upgrade and stay gone until the next sign-in. Only console-initiated updates were ever covered, so a winget upgrade, a hand-run setup and a plain crash all ended the same way. The host now watches the icon for as long as it runs.
- The Linux install script asks about what you want, not how it works. Its questions are now full controller support, third-party Moonlight clients, the shared clipboard, and starting at boot — and it picks sensible defaults from your machine. Bazzite and Nobara join the group and keep running after you log out. A host already running Sunshine or Apollo is offered Moonlight compatibility, and an SSH session with no screen keeps running too. It still runs unattended, and re-running it is still safe.
- The access badge appears only when the stats overlay does. A badge that never goes away reads as clutter. What it tells you, which is what this session may do, is something you check now and then rather than watch. Notices about a change still appear at any time.
- Touch handling is more consistent. Long-press to drag now works on every client rather than some. Two-finger scrolling respects your invert-scroll setting. Scrolling needs exactly two fingers, so a three-finger gesture is no longer read as a scroll.
- A host that cannot accept touch now says so. Some Linux desktops and older Windows builds have nowhere to deliver a touch contact, and they were dropping every one in silence. Your client now falls back to the trackpad model for that session and tells you when the stream starts.
Fixed
- Windows: F11 ended the session instead of going fullscreen. On graphics drivers that refuse a fullscreen-sized surface, the failure ended the stream, and the app then reported a live session as "Couldn't connect". A refused fullscreen now costs you the fullscreen and nothing else.
- Apple: the picture froze while sound and input kept running. Reported from an iPad Pro, twice in one session, and only reconnecting cleared it. The part of the pipeline that hands frames to the screen had stopped asking for them, and nothing noticed. It is now watched and restarted within a quarter of a second.
- Both sticks on a virtual Switch Pro controller sat in the top-right corner under Steam. They reached the centre only at full down-left, while the buttons and motion were fine. Steam reads the controller's calibration in a shape we did not answer, so it read zeros and treated a zeroed centre as real.
- Steam Deck in Gaming Mode: touch dragged the host cursor into a corner and every touch mode stopped working. Steam owns the touchscreen there and replays it as mouse movement, which the stream then applied as if you had moved a mouse a very long way. One capture showed 341 such movements and not a single finger. Punktfunk now recognises that pattern, ignores it, and tells you once why.
- Android: touching the black bars beside the picture did nothing. Those taps never reached the gesture handling at all.
- Linux: the Flatpak app opened fullscreen on every desktop. It checks one setting to tell whether it is running in Steam's Gaming Mode, and our own Flatpak sets that value on every launch. The graphics layer we bundle reads that setting, and nothing else, to decide whether to offer HDR. Inside the sandbox it was always set, so the app believed every machine was a Deck. Reproduced on a plain GNOME desktop with no Deck and no Steam session anywhere.
- Steam Deck and CachyOS: the in-session display menu offered one refresh rate and no resolutions. The list of rates we build never reached a SteamOS-style session, so games paced themselves to that single number.
- Apple TV: the wake prompt could not be answered with a controller. Neither Cancel nor Try Again could be pressed, which left a failed wake as a dead end. The prompt shown for an unknown host had the same problem.
- Android TV: settings offered rumble and gyro "from this phone" on a box that has neither. An Nvidia Shield answers yes when asked whether it can vibrate, most likely on behalf of an attached controller, so those rows appeared and promised something the box cannot do.
- Windows: the tray icon could vanish for good. An internal lock left in a bad state took the whole tray process down with it, which is exactly the disappearance the new supervision is there to prevent.
- Our own documentation said AMD and Intel encoding was untested. It has been validated since 0.31, on a Ryzen 7000 integrated GPU and on Intel Arc. The README, the roadmap and the Windows host page were never updated to say so. If you skipped Punktfunk because you have an AMD card, that was our mistake.
Thanks
Two people outside the team wrote code that ships in this release, and both are named here because the work is theirs.
Keith Porcaro built Steam Controller 2 support beyond Linux. It is five separate pieces across four platforms, and the largest single contribution in this release:
- the shared description of how that controller talks;
- the Windows driver identity that lets a Windows host present one;
- the path that carries the pad's raw reports across the stream;
- Bluetooth capture on Apple devices;
- the motion-sensor gate on Android.
If you use that controller from a phone, a tablet, a Mac, or to a Windows PC, this is why. luxus rewrote what the Linux install script asks you. It used to ask about our internals. It now asks what you want and works the rest out from your machine. They also tightened the previous release's changelog to our own house style, which is the kind of contribution nobody has to make.
The rest started, as usual, with people describing exactly what they saw:
- "The GTK client is just launching in fullscreen." One sentence, and it named a bug that had been shipping to most Linux users in our main channel.
- "All text looks boring and ugly" about the console's dial, which is the shortest bug report we have had and completely correct.
- The iPad whose picture froze twice in one session while the sound kept playing. The detail that audio survived is what pointed at the screen rather than the network.
- The Switch Pro sticks pinned in a corner, with the observation that the same pad read correctly outside Steam. That one detail ruled out half the system.
- The Steam Deck whose touch controls all died at once in Gaming Mode. Three separate features failing together is what showed they shared a cause.
Thank you.
One caveat we would rather write down than have you find. Touch on a Steam Deck in Gaming Mode is the one path we have not re-run on the hardware since the fix. It was built from a capture of exactly that failure and it is covered by tests, but a Deck has not played the finished build back to us. If a gesture still behaves oddly there, please tell us — and say what you saw, because that is what made every other fix on this page findable.
For developers
Protocol, application binary interface (ABI), driver and embedder detail is in the v0.34.0 CHANGELOG. It carries the version table and the full breaking-change list.
The short version: the ABI that embedders build against moves 26 to 28, and one of those steps widens a struct. PunktfunkHidOutput grows from 19 to 85 bytes, so this is a recompile rather than a relink — the existing version equality check is what catches a stale build. Everything else versioned stands still: the streaming protocol, the driver protocol, the gamepad channel, the add-on contract and the management API are all where 0.33.0 left them.
Packagers on Windows: the controller driver package gains an eighth hardware identity for the Steam Controller 2, so it must be rebuilt and reinstalled for that pad to work.