Merge pull request 'feat(decky): the settings tab covers the whole store, as a SteamOS-style sidebar' (#24) from worktree-decky-stats-overlay-toggle into main
ci / web (push) Successful in 1m7s
ci / rust-arm64 (push) Successful in 2m12s
decky / build-publish (push) Successful in 30s
docker / builders (--build-arg FEDORA_VERSION=44, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm, -f44) (push) Successful in 7s
ci / docs-site (push) Successful in 1m15s
docker / builders (ci/android-ci.Dockerfile, punktfunk-android-ci) (push) Successful in 10s
docker / builders (ci/arch-ci.Dockerfile, punktfunk-arch-ci) (push) Successful in 19s
docker / builders (ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 8s
docker / builders (ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 7s
docker / builders (ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 12s
docker / apps (., web/Dockerfile, punktfunk-web) (push) Successful in 1m5s
docker / builders-arm64cross (push) Successful in 10s
docker / apps (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 1m26s
docker / deploy-docs (push) Failing after 6m7s
ci / rust (push) Successful in 8m27s

Reviewed-on: #24
This commit was merged in pull request #24.
This commit is contained in:
2026-08-03 16:44:55 +00:00
7 changed files with 933 additions and 209 deletions
+46 -30
View File
@@ -15,8 +15,10 @@ The Linux, Windows, Mac, iPhone/iPad and Android apps group settings the same wa
**Display**, **Input**, **Audio**, **Controllers** — under *Preferences* on Linux and *Settings*
elsewhere. The Apple TV app shows one scrolling list instead, and so does any client's settings
screen reached with a controller. A controller-driven launch (Steam Deck Gaming Mode) opens the
client's **console home**, whose settings screen is one steppable list; the Decky plugin has a
smaller section of its own. The console home is part of the client — it is not the host's
client's **console home**, whose settings screen is one steppable list; the Decky plugin's Settings
tab covers the same store in the same groups and the same order, as a left rail of categories the
way SteamOS's own Settings looks. The console home is part of the
client — it is not the host's
[web console](/docs/web-console).
Linux stores them in `~/.config/punktfunk/client-gtk-settings.json`, the same file the Decky plugin
@@ -43,8 +45,9 @@ and your client scales what it gets — see
**Match window***default: off.* The stream mode follows your window instead, and each resize
renegotiates the host's display and encoder, so a windowed session stays pixel-exact. Fullscreen
degenerates to the display's native mode. Offered by the Linux, Windows, Mac, iPhone/iPad and console
home screens; not by Android or Decky.
degenerates to the display's native mode. Offered by the Linux, Windows, Mac, iPhone/iPad, console
home and Decky screens (on Decky it sits in the Resolution picker, and Gaming-Mode streams are
always fullscreen, so it lands on native); not by Android.
**Refresh rate***default: Native*, the refresh of the display your window is on. The Apple app
stores an explicit rate (60 Hz by default): iPhone and iPad offer the rates the device can display,
@@ -69,8 +72,8 @@ link. The stops run 0.5× to 4×. The result is floored to an even size and capp
**Video codec***default: Automatic.* A soft preference: the host emits your choice when it can
also produce it, otherwise the best codec you both speak, in the order HEVC → AV1 → H.264.
**PyroWave** is never auto-picked — pick it explicitly on Linux, Windows, the console home, or an
Apple device whose decode probe passes; anywhere else it isn't offered, and asking for it lands on
**PyroWave** is never auto-picked — pick it explicitly on Linux, Windows, the console home, Decky, or
an Apple device whose decode probe passes; anywhere else it isn't offered, and asking for it lands on
that same order. See [PyroWave](/docs/pyrowave). The Android and Apple apps hide AV1 unless the
device has a hardware AV1 decoder; Android never offers PyroWave.
@@ -83,26 +86,27 @@ Full detail: [HDR](/docs/hdr).
needs HEVC or PyroWave, the host's own 4:4:4 policy left on, a capture path that delivers full
chroma, and a GPU that can encode it; if any gate fails the host says 4:2:0 before your decoder is
built. The Apple, Linux and Windows apps all advertise it (Apple additionally requires its hardware
decode probe to pass). Android, Decky and the console home don't offer it.
decode probe to pass). The console home and Decky offer the toggle; Android doesn't.
**Prioritize***default: Lowest latency.* What the client optimizes for when a decoded frame is
ready. **Lowest latency** shows every frame the moment the display can take it, so a network hiccup
becomes an occasional repeated or skipped frame. **Smoothness** holds a small buffer that evens
those hiccups out, at that buffer's worth of added delay. Linux and Windows apps; the Apple and
Android apps have carried the same setting for a while, and it is stored under the same name, so a
[profile](/docs/profiles-and-links) means the same thing on every device.
those hiccups out, at that buffer's worth of added delay. Linux and Windows apps, the console home
and Decky; the Apple and Android apps have carried the same setting for a while, and it is stored
under the same name, so a [profile](/docs/profiles-and-links) means the same thing on every device.
**Smoothness buffer***default: Automatic (two frames).* Only shown under **Smoothness**. How
many frames are held back before showing. Each frame absorbs roughly one screen refresh of network
hiccup and costs one refresh of delay — so on a 120 Hz screen, two frames is about 17 ms of extra
delay bought against 17 ms of jitter. If you never see stutter, you don't need this.
delay bought against 17 ms of jitter. If you never see stutter, you don't need this. Wherever
**Prioritize** is offered, and greyed out until you pick Smoothness.
**V-Sync***default: on.* Tear-free presentation. Turning it off asks the GPU to show each frame
the instant it's ready instead of waiting for the screen's next refresh: the lowest delay a display
can give you, at the cost of visible tearing on fast motion. It is **best-effort** — not every
driver or compositor offers a tearing mode, and where none is available the stream stays tear-free.
The Detailed [stats overlay](/docs/stats) names the mode actually in use, so you can tell "off"
from "off but unavailable". Linux and Windows apps.
from "off but unavailable". Linux and Windows apps, the console home and Decky.
**Follow variable refresh rate***default: on.* On a VRR / FreeSync / G-Sync screen, let the panel
refresh in step with the stream rather than on a fixed cadence — which removes the wait between a
@@ -111,7 +115,8 @@ windowed one is at the compositor's mercy) and is harmless on a fixed-refresh sc
graphics driver that offers the modern queue-free display mode; on an older driver it does nothing
unless you also set `PUNKTFUNK_VRR_FIFO=1` (see [configuration](/docs/configuration)), because the
older way of following a panel costs noticeable latency on a fixed-refresh screen. The stats overlay
reports `vrr yes` once it has *measured* that the panel really is following. Linux and Windows apps.
reports `vrr yes` once it has *measured* that the panel really is following. Linux and Windows apps,
the console home and Decky.
**Host compositor***default: Automatic.* Which backend a **Linux** host uses to drive the virtual
output. Advisory: a host without that backend quietly auto-detects instead.
@@ -123,7 +128,7 @@ stereo. The count the host will really send comes back in the handshake, and you
decoder from *that*, never from the request. What surround means differs by host: a **Linux** host
claims a sink advertising exactly that many channels, so applications produce real surround, while a
**Windows** host loopback-captures your current output endpoint and lets Windows convert it — so 5.1
from a stereo endpoint is an upmix, not new channels. Offered everywhere except the Decky plugin.
from a stereo endpoint is an upmix, not new channels. Offered everywhere.
**Microphone** — *default: off on Linux, Windows, Android, the console home and Decky; on in the
Apple app.* Sends this device's microphone to the host's virtual mic. On Linux and Windows the
@@ -137,16 +142,18 @@ from an echo-cancelled PipeWire source when your desktop provides one, on **Wind
for the Communications stream category so the endpoint's processing engages, and on **Apple** and
**Android** the platform's voice-processing mode. Turn it off if your microphone already runs its
own processing, or if the canceller makes your voice sound thin. The row sits under the microphone
toggle and greys out while the microphone is off. Offered by the Linux, Windows, Apple, Android and
console-home clients; Decky has no toggle. What it can and can't fix is in
toggle and greys out while the microphone is off. Offered by the Linux, Windows, Apple, Android,
console-home and Decky clients. What it can and can't fix is in
[Why do I hear myself](/docs/echo).
**Speaker** and **Microphone** device pickers — *default: System default.* Which endpoint stream
audio plays out of, and which input feeds the uplink. Only the Linux app (PipeWire nodes) and the
**Mac** app (which also has a microphone *channel* picker) have these — iPhone, iPad, Apple TV,
Android, Decky and the console home have none, and the Windows app has none and ignores a stored
audio plays out of, and which input feeds the uplink. Only the Linux app (PipeWire nodes), the
**Mac** app (which also has a microphone *channel* picker) and **Decky** have these — iPhone, iPad,
Apple TV, Android and the console home have none, and the Windows app has none and ignores a stored
speaker choice. On Linux, a device that has since disappeared keeps a "(not detected)" entry rather
than silently snapping back to the default; the Mac shows it as "Unavailable device".
than silently snapping back to the default; the Mac shows it as "Unavailable device" and Decky as
"(not connected)". Decky reads the endpoint list from the client's session binary, so a client
older than the two-binary split leaves these pickers on Automatic.
## Input
@@ -186,8 +193,10 @@ which forwards *every* connected controller, each as its own player, on Linux, W
console home. Pinning one restricts the session to that controller alone — single-player. The Android
app has no such picker.
**Capture system shortcuts***default: on.* Offered by the Linux and Windows apps only; Windows
spells the row out as *Capture system shortcuts (Alt+Tab, Win, …)*. On, Alt+Tab and the Windows key
**Capture system shortcuts***default: on.* Offered by the Linux and Windows apps, the console home
and Decky; Windows spells the row out as *Capture system shortcuts (Alt+Tab, Win, …)*. On a Deck it
matters only for a keyboard you attached yourself, for the reason the paragraph below gives: Gaming
Mode is gamescope, which has nothing to hold back. On, Alt+Tab and the Windows key
(Super on Linux) reach the host while the stream has input captured. Off, they act on this machine
instead — what you want when the stream shares a screen with local work. Either way the chords come
back the moment you release capture with **Ctrl+Alt+Shift+Q**, the window loses focus, or the stream
@@ -206,17 +215,22 @@ the wlroots compositors all do, and X11 sessions grab the keyboard directly. Und
Wake-on-LAN and waits for it to boot — only for a host whose MAC address this client has already
learned. Turn it off for hosts you reach over a VPN, where "offline" usually means "not reachable by
broadcast" and the wake only adds a delay. The Linux, Windows, Apple and Android apps have this
toggle. The console home has no toggle — it offers wake as an explicit action on an offline host
instead — and the Decky plugin always sends a wake before a stream starts. See
toggle, as do the console home and Decky — and note that the Decky plugin sends a wake of its own
before a stream starts whatever this setting says, so on a Deck it governs the client's connect
rather than the launch. The console home also offers wake as an explicit action on an offline host.
See
[Wake-on-LAN](/docs/wake-on-lan).
**Show game library***default: off on Linux and Windows; on in the Apple and Android apps.* Browse
a paired host's games and launch one directly; the Windows app still labels it experimental. There is
no toggle in the console home or in Decky. See [Game library](/docs/game-library).
a paired host's games and launch one directly; the Windows app still labels it experimental. The
console home and Decky have the toggle too — on Decky it governs the *client's* screens, since the
plugin's own library browser works either way. See [Game library](/docs/game-library).
**Start streams in fullscreen***default: on.* On Linux and Windows, F11 or Alt+Enter leaves
fullscreen live. On a Mac the setting is **Fullscreen while streaming**, and the window comes back
when you return to the host list. iPhone, iPad, Apple TV and Android have no equivalent.
when you return to the host list. The console home and Decky carry the row for the desktop client
that shares the store — a Gaming-Mode launch is fullscreen whatever it says. iPhone, iPad, Apple TV
and Android have no equivalent.
## Overlay
@@ -224,7 +238,8 @@ when you return to the host list. iPhone, iPad, Apple TV and Android have no equ
superset of the one before. This setting only picks the tier a session *starts* at — you can cycle
them live in-stream, with a shortcut that differs by platform. The Apple app additionally lets you
choose which corner the overlay sits in (Top Left, Top Right, Bottom Left, Bottom Right). The Decky
plugin has no stats setting. The shortcuts, and every number in the overlay, are in
plugin has the tier picker too, in its Settings section. The shortcuts, and every number in the
overlay, are in
[Understanding the stats overlay](/docs/stats).
## Settings that are facts about your device
@@ -236,8 +251,9 @@ stay global and **cannot be put in a settings profile**:
vendor-ordered and falls back on its own; change it only when debugging, and note that
`PUNKTFUNK_DECODER` overrides it
([Configuration](/docs/configuration#client-side-native-clients)). The decoder picker is on Linux,
Windows and in the console home; the GPU picker on Windows, and on Linux only when the machine has
more than one adapter. The Apple and Android apps have neither.
Windows, in the console home and in Decky; the GPU picker on Windows, and on Linux and Decky only
when the machine has more than one adapter — which a Deck doesn't, so the row isn't there. The
Apple and Android apps have neither.
- **Speaker** and **Microphone** device pickers — this device's audio endpoints.
- **Forwarded controller** — which physical pad is in your hands. The *type* the host creates is a
preference and can live in a profile; which pad you hold cannot. **Forward controllers** is a