feat(decky): self-update without the store + Gaming-Mode launch polish, and ship the Steam Deck docs
apple / swift (push) Successful in 1m4s
apple / screenshots (push) Successful in 5m26s
android / android (push) Successful in 3m27s
ci / web (push) Successful in 1m7s
ci / docs-site (push) Successful in 1m16s
ci / rust (push) Successful in 4m21s
deb / build-publish (push) Successful in 2m31s
decky / build-publish (push) Successful in 20s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 8s
ci / bench (push) Successful in 4m46s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 11s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 10s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 5s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 1m0s
flatpak / build-publish (push) Successful in 4m55s
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Successful in 9m38s
docker / deploy-docs (push) Successful in 6s
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Successful in 8m25s

Plugin self-update (no Decky store): CI publishes a per-channel manifest.json
({version, immutable per-version artifact, sha256}) beside the zip and bakes
update.json {channel, manifest} into the plugin. main.py `check_update` reads the
installed version from package.json (the value Decky reports — not plugin.json),
fetches the channel manifest, and the frontend shows an "Update to vX" button that
drives Decky Loader's own install RPC (root downloads + SHA-256-verifies + hot-reloads).
CI now stamps a plain-numeric semver (0.3.<run> canary / X.Y.Z stable) into
package.json — a -ciN suffix would mis-order under compare-versions.

Linux client: `--fullscreen` (plus SteamDeck/gamescope env fallback) enters GTK
fullscreen on stream start so Gaming-Mode chrome is hidden; native-mode resolution
falls back to the display's first monitor when the window isn't mapped yet (was
dropping to the 1080p floor — wrong on the Deck's 1280×800); add a confirmed
"Remove saved host" action (KnownHosts::remove_by_fp).

Docs: new docs/steam-deck.md (Decky install/pair/stream/self-update/troubleshooting),
wired into meta.json nav, and cross-linked from clients/install-client/channels. This
is the page docs.punktfunk.unom.io/docs/steam-deck — the website's download link
pointed at it before it existed; committing it makes that link resolve.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-28 13:03:44 +00:00
parent 3947d5b07a
commit 30d0d36efe
15 changed files with 735 additions and 72 deletions
+4 -3
View File
@@ -44,9 +44,10 @@ one-line edit of `/etc/apt/sources.list.d/punktfunk.list` (`stable` ↔ `canary`
1. Make sure `main` is green.
2. (Optional) bump any user-facing version that isn't derived from the tag — the Android
`versionName` fallback (`clients/android/app/build.gradle.kts`) and the Decky `plugin.json`
`version` are cosmetic self-reported strings; everything else (binaries via
`PUNKTFUNK_BUILD_VERSION`, MSIX, apt/rpm, the `.dmg`) derives from the tag automatically.
`versionName` fallback (`clients/android/app/build.gradle.kts`) is a cosmetic self-reported
string; everything else (binaries via `PUNKTFUNK_BUILD_VERSION`, MSIX, apt/rpm, the `.dmg`, and
the **Decky** plugin version — CI stamps it into `package.json`, where it drives the plugin's own
[self-update check](/docs/steam-deck#updating)) derives from the tag automatically.
3. Tag and push — **one** tag releases every platform:
```sh
git tag v0.2.0
+3 -2
View File
@@ -44,7 +44,7 @@ It ships as a real package, not just a source build — full steps in
- **Any Flatpak distro (recommended)** — `flatpak install https://flatpak.unom.io/io.unom.Punktfunk.flatpakref`
from the hosted [`flatpak.unom.io`](/docs/install-client#linux-desktop-flatpak) repo, then
`flatpak update`; this is also what the Decky plugin launches.
`flatpak update`; this is also what the [Decky plugin](/docs/steam-deck) launches.
- **Ubuntu / Debian** — `apt install punktfunk-client` from the punktfunk apt registry.
- **Fedora / Bazzite** — `rpm-ostree install punktfunk-client` from the Gitea RPM registry.
- **Arch / SteamOS** — the `punktfunk-client` split package from the `PKGBUILD`.
@@ -108,7 +108,8 @@ punktfunk-probe --connect <host>:9777 --pin <fp> # connect to one
| You're streaming to… | Use |
|---|---|
| A Mac, iPhone, iPad, or Apple TV | The **Apple app** |
| A Linux desktop or laptop, or a Steam Deck | **`punktfunk-client`** (GTK4) |
| A Linux desktop or laptop | **`punktfunk-client`** (GTK4) |
| A **Steam Deck** | The **[Decky plugin](/docs/steam-deck)** in Gaming Mode, or the GTK4 client in Desktop Mode |
| An Android phone or TV | The **Android app** |
| Windows | The native **`punktfunk-client`** (signed MSIX) or **Moonlight** |
| A browser, a smart TV, or any other device | **Moonlight** |
+13 -6
View File
@@ -16,7 +16,7 @@ Whichever client you install, the first connection needs a one-time [pairing](/d
| Device | Install |
|--------|---------|
| **Linux** desktop / laptop | [Flatpak](#linux-desktop-flatpak) (any distro) or native apt/rpm/Arch packages |
| **Steam Deck** | [Flatpak in Desktop Mode](#steam-deck) (or the Decky plugin) |
| **Steam Deck** | [Decky plugin](/docs/steam-deck) for Gaming Mode, or [Flatpak in Desktop Mode](#steam-deck) |
| **Windows** | [Signed MSIX](#windows) from the package registry |
| **macOS** | [Notarized `.dmg`](#macos) from the releases page |
| **iPhone / iPad / Apple TV** | [TestFlight beta](#ios-ipados-apple-tv) |
@@ -57,16 +57,23 @@ punktfunk-client --connect <host>:9777
## Steam Deck
In **Desktop Mode**, install the Flatpak exactly as [above](#linux-desktop-flatpak) — it carries
its own libadwaita + SDL3 and survives SteamOS updates:
Most Deck users want **Gaming Mode**: install the **[Decky plugin](/docs/steam-deck)** and a
**punktfunk** panel lands in the Quick Access Menu, so you can discover hosts, pair with a PIN, and
stream **without dropping to the desktop**. Follow the **[Steam Deck (Decky) guide](/docs/steam-deck)**
— it walks through Decky Loader, the plugin, and the one-time client install.
> The plugin doesn't decode video itself — it launches the Flatpak client below. The Decky guide
> covers installing both, so start there: a Flatpak on its own won't add the Gaming Mode panel.
For **Desktop Mode** (or to add the client to Game Mode as a non-Steam app yourself), install the
Flatpak exactly as [above](#linux-desktop-flatpak) — it carries its own libadwaita + SDL3 and
survives SteamOS updates:
```sh
flatpak install --user https://flatpak.unom.io/io.unom.Punktfunk.flatpakref
```
Add it to Game Mode as a non-Steam app, or use the **Decky plugin**, which launches this same
Flatpak (`flatpak run io.unom.Punktfunk --connect …`). See
[packaging/flatpak](https://git.unom.io/unom/punktfunk/src/branch/main/packaging/flatpak/README.md).
See [packaging/flatpak](https://git.unom.io/unom/punktfunk/src/branch/main/packaging/flatpak/README.md).
## Windows
+1
View File
@@ -17,6 +17,7 @@
"---Connecting---",
"clients",
"install-client",
"steam-deck",
"moonlight",
"pairing",
"---Configuration---",
+100
View File
@@ -0,0 +1,100 @@
---
title: Steam Deck (Decky)
description: Install the punktfunk Decky plugin to discover, pair, and stream from the Steam Deck's Gaming Mode — no drop to Desktop.
---
The **Decky plugin** adds a **punktfunk** panel to the Steam Deck's Quick Access Menu (the `…`
button), so you can find a host, pair, and start streaming **without leaving Gaming Mode**. It's the
couch-friendly front end for the Steam Deck — built from real Steam UI, gamepad-navigable end to end.
Under the hood the plugin doesn't decode video itself: it discovers hosts, runs the PIN pairing, and
**launches the regular [Linux client](/docs/clients#linux-desktop-client-gtk4)** (the
`io.unom.Punktfunk` Flatpak) the way gamescope needs so it fullscreens correctly. So the Deck has two
ways to stream, and they share one client + one paired identity:
- **Gaming Mode** → the **Decky plugin** (this page).
- **Desktop Mode** → run the [Flatpak](/docs/install-client#steam-deck) directly, like any Linux app.
## Before you start
You need three things on the Deck:
1. **Decky Loader** — the plugin loader. Install it from [decky.xyz](https://decky.xyz/) if you
haven't already.
2. **The punktfunk client Flatpak** — the plugin launches it, so install it once in **Desktop Mode**:
```sh
flatpak install --user https://flatpak.unom.io/io.unom.Punktfunk.flatpakref
```
(Full options: [Install a Client → Steam Deck](/docs/install-client#steam-deck). Without it, the
panel's **Stream** button reports `client-not-found`.)
3. **A punktfunk host** running on your LAN — see [Install the Host](/docs/install). The Deck finds
it automatically over mDNS, so nothing to configure here.
## Install the plugin
The plugin is published as a ready-to-install zip on every build. You don't need the Decky CLI or a
developer toolchain — just paste a URL into Decky:
1. On the Deck, open the **Quick Access Menu** (``) → the **plug** icon (Decky) → the **gear**
(Settings) → enable **Developer Mode**.
2. Open the new **Developer** tab and choose **Install Plugin from URL**.
3. Paste the **stable** link and confirm:
```
https://git.unom.io/api/packages/unom/generic/punktfunk-decky/latest/punktfunk.zip
```
The **punktfunk** panel appears in the Quick Access Menu right away — no Deck restart needed.
> **Channels.** The link above is the **stable** channel (moves on `vX.Y.Z` releases). For the latest
> `main` build use the **canary** zip — `…/generic/punktfunk-decky/canary/punktfunk.zip` — or pin an
> exact version with `…/punktfunk-decky/<version>/punktfunk.zip`. See [Release Channels](/docs/channels).
## Use it
Open the **punktfunk** panel from the Quick Access Menu, or **Open punktfunk** for the full-screen
page (host list + stream settings).
- **Discover** — hosts on your network appear automatically (mDNS). Tap **Refresh** to rescan. A
lock icon means the host requires [pairing](/docs/pairing).
- **Pair** — for a locked host, [arm pairing on the host](/docs/pairing) (its console or web
console shows a 4-digit PIN), then enter that PIN on the Deck's keypad. Pairing persists, so the
next connection is silent.
- **Stream** — pick a host and the stream launches fullscreen in Gaming Mode (as a hidden Steam
shortcut, so gamescope focuses it).
- **Settings** — resolution, refresh, bitrate, gamepad type, and mic, written to the client the
plugin launches. Leave **Resolution** / **Refresh** on *Native* to get the Deck's own mode.
To **leave a stream**: the in-client controller chord **L1 + R1 + Start + Select**, or close the
"game" from the Steam overlay. Exiting the client ends the Steam game and drops you back to Gaming
Mode.
## Updating
The plugin **checks for updates itself** — no Decky store needed. When a newer build is available it
shows an **Update to vX** button (in the Quick Access Menu panel and on the full page). Tap it,
confirm Decky's prompt, and the plugin downloads, verifies, replaces itself, and reloads — without
leaving Gaming Mode.
The check follows the [channel](/docs/channels) you installed from: a plugin installed from the
**stable** link tracks stable releases; one installed from the **canary** link tracks `main` builds.
> If the **Update** button never appears (an older Decky Loader, or no network), update manually:
> Decky → **Developer** → **Install Plugin from URL**, and paste the same channel link again. Decky
> replaces the installed copy in place.
## Troubleshooting
| Symptom | Fix |
|---|---|
| **Stream** shows `client-not-found` | Install the client Flatpak in Desktop Mode (see [Before you start](#before-you-start)). |
| No hosts listed | Make sure the host is running and on the **same LAN**; the Deck needs `avahi` (shipped on SteamOS). Tap **Refresh**. |
| Pairing fails / "not armed" | The PIN is shown only after you **arm pairing on the host**. Arm it, then enter the PIN within the window. |
| Stream launches but doesn't focus | Start it from the panel (not by launching the Flatpak by hand) so Steam/gamescope focuses it. |
The plugin source lives in
[`clients/decky`](https://git.unom.io/unom/punktfunk/src/branch/main/clients/decky/README.md).
</content>
</invoke>