ci / web (pull_request) Successful in 1m5s
ci / docs-site (pull_request) Successful in 1m7s
ci / bun-nix (pull_request) Successful in 27s
ci / rust-arm64 (pull_request) Successful in 3m50s
windows-client / client (arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (pull_request) Successful in 3m9s
windows-client / client (x64, , x86_64-pc-windows-msvc, C:\t) (pull_request) Successful in 6m55s
android / android (pull_request) Successful in 12m58s
ci / docs-drift (pull_request) Failing after 14m41s
ci / rust (pull_request) Successful in 18m26s
A field report on 2026-08-30: "the GTK client is just launching in
fullscreen". Reproduced on a plain GNOME desktop (.21), launched from
the .desktop entry, with no Deck and no gamescope anywhere on the box.
The shell fullscreens itself when `cli::fullscreen_mode()` is true, and
that read `GAMESCOPE_WAYLAND_DISPLAY` as proof of Gaming Mode. Our own
flatpak sets it unconditionally: `packaging/flatpak/io.unom.Punktfunk.yml`
exports `GAMESCOPE_WAYLAND_DISPLAY=gamescope-0` because the vendored
gamescope WSI layer reads that variable and nothing else to decide
whether to negotiate HDR10 (e1adc5d6, 2026-08-05, shipped in v0.25.0).
So inside the sandbox it is set on every launch, on every desktop —
verified in the sandbox on .21, where the host has neither a gamescope
process nor a socket. The flatpak is the main Linux channel, so this hit
every flatpak user on every desktop since v0.25.0.
Fullscreen was only the visible half. The same reading also meant:
- a stream ignored `fullscreen_on_stream = false` (the env ORed straight
past the flag the client resolves the setting into);
- the settings dialog swapped every dropdown for a subpage, the
workaround meant for gamescope's unmapped popovers;
- the system-button "auto" policy picked Deck rules, handing Steam/QAM
to a local Steam UI that is not there;
- the overlay-focus watcher took the gamescope path.
The variable has to keep being exported, so the fix is in what we accept
as proof. `pf_client_core::gamescope::under_gamescope()` is now the one
answer, and all six readers route through it: `WAYLAND_DISPLAY` settles
it whenever we have one (a desktop session in the sandbox still gets
`--socket=wayland`, so it names the desktop compositor — the same
mismatch the WSI layer bails on), and Gaming Mode, which runs apps as
X11 clients with no `WAYLAND_DISPLAY`, falls back to the named socket
actually existing.
Dropped the `SteamDeck` leg from the Gaming-Mode tests while here: it
says which MACHINE this is, so a Deck in DESKTOP mode was fullscreening
too. `is_steam_deck()` still wants machine identity and keeps it, but
now compares the value — Valve documents `SteamDeck=1`, and desktop
Steam exports `SteamDeck=0` into everything it launches, so the presence
check called every PC with Steam a Deck.
Verified on .21 (CachyOS, GNOME): `cargo fmt --all --check` clean; the
new `only_a_real_gamescope_counts` test passes; `cargo clippy -D
warnings --all-targets` green over pf-client-core, pf-presenter,
punktfunk-client-linux and punktfunk-client-session, with all four
confirmed really built in the log rather than skipped as fresh.