A field report on 2026-08-30: "the GTK client is just launching in fullscreen." Reproduced on
.21 — a plain GNOME desktop, launched from the .desktop entry, with no Deck and no gamescope
anywhere on the box.
What causes it
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 --env=GAMESCOPE_WAYLAND_DISPLAY=gamescope-0
because the vendored gamescope WSI layer reads that one variable and nothing else to decide
whether to negotiate HDR10 — the manifest's own comment calls it "the layer's ONLY 'am I under
gamescope?' signal". So inside the sandbox it is set on every launch, on every desktop.
Verified rather than reasoned: on .21, flatpak run --command=env io.unom.Punktfunk prints GAMESCOPE_WAYLAND_DISPLAY=gamescope-0 while the host has neither a gamescope process nor a /run/user/1000/gamescope-* socket.
The manifest line landed in e1adc5d6 (2026-08-05) and shipped from v0.25.0, which dates the
regression. The flatpak is the main Linux channel, so this has hit every flatpak user on every
desktop for six releases.
Fullscreen was the visible quarter of it
The same misreading also meant:
a stream ignored fullscreen_on_stream = false — the env ORed straight past the flag the client
resolves that 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 and QAM to a local Steam UI
that is not running;
the overlay-focus watcher took the gamescope path.
The fix
The variable has to keep being exported — the WSI layer needs it — 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 inside the sandbox still
gets --socket=wayland, so it names the desktop compositor. That mismatch is exactly what the
WSI layer itself bails on.
Gaming Mode leaves nothing to compare — it runs apps as X11 clients (DISPLAY=:1, no WAYLAND_DISPLAY) — so there the fallback is the named socket actually existing. The flatpak
binds it (--filesystem=xdg-run/gamescope-0) for HDR anyway, so this is the same reachability
the layer depends on.
Also dropped the SteamDeck leg from the Gaming-Mode tests while here, because it names the machine rather than the session, so a Deck in desktop mode was fullscreening too. is_steam_deck() genuinely wants machine identity and keeps its check, but now compares the value:
Valve documents SteamDeck=1, and desktop Steam exports SteamDeck=0 into everything it launches,
so a presence check called every PC with Steam a Deck.
Verification
Run on .21 (CachyOS, GNOME), because cargo test -p pf-client-core on macOS is pre-existing red
from target-gated dependencies:
cargo fmt --all --check clean, before and after the rebase onto 37bb8948.
The new only_a_real_gamescope_counts test passes. It covers the flatpak-on-desktop shape (both
with and without some other gamescope running on the box), a real nested gamescope, and Game Mode
with and without a live socket.
cargo clippy -D warnings --all-targets green across pf-client-core, pf-presenter, punktfunk-client-linux and punktfunk-client-session. All four were confirmed really built in
the log rather than skipped as fresh — the warm shared target dir prints Finished without
checking otherwise.
Not verified on glass. Nobody has yet watched a rebuilt flatpak launch windowed on a desktop,
and no Deck in Game Mode has confirmed it still fullscreens. Both need a flatpak build.
A field report on 2026-08-30: *"the GTK client is just launching in fullscreen."* Reproduced on
.21 — a plain GNOME desktop, launched from the `.desktop` entry, with no Deck and no gamescope
anywhere on the box.
## What causes it
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 `--env=GAMESCOPE_WAYLAND_DISPLAY=gamescope-0`
because the vendored gamescope WSI layer reads that one variable and nothing else to decide
whether to negotiate HDR10 — the manifest's own comment calls it *"the layer's ONLY 'am I under
gamescope?' signal"*. So inside the sandbox it is set on every launch, on every desktop.
Verified rather than reasoned: on .21, `flatpak run --command=env io.unom.Punktfunk` prints
`GAMESCOPE_WAYLAND_DISPLAY=gamescope-0` while the host has neither a gamescope process nor a
`/run/user/1000/gamescope-*` socket.
The manifest line landed in `e1adc5d6` (2026-08-05) and shipped from **v0.25.0**, which dates the
regression. The flatpak is the main Linux channel, so this has hit every flatpak user on every
desktop for six releases.
## Fullscreen was the visible quarter of it
The same misreading also meant:
- a stream ignored `fullscreen_on_stream = false` — the env ORed straight past the flag the client
resolves that 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 and QAM to a local Steam UI
that is not running;
- the overlay-focus watcher took the gamescope path.
## The fix
The variable has to keep being exported — the WSI layer needs it — 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 inside the sandbox still
gets `--socket=wayland`, so it names the *desktop* compositor. That mismatch is exactly what the
WSI layer itself bails on.
- **Gaming Mode leaves nothing to compare** — it runs apps as X11 clients (`DISPLAY=:1`, no
`WAYLAND_DISPLAY`) — so there the fallback is the named socket actually existing. The flatpak
binds it (`--filesystem=xdg-run/gamescope-0`) for HDR anyway, so this is the same reachability
the layer depends on.
Also dropped the `SteamDeck` leg from the Gaming-Mode tests while here, because it names the
*machine* rather than the session, so a Deck in **desktop** mode was fullscreening too.
`is_steam_deck()` genuinely wants machine identity and keeps its check, but now compares the value:
Valve documents `SteamDeck=1`, and desktop Steam exports `SteamDeck=0` into everything it launches,
so a presence check called every PC with Steam a Deck.
## Verification
Run on .21 (CachyOS, GNOME), because `cargo test -p pf-client-core` on macOS is pre-existing red
from target-gated dependencies:
- `cargo fmt --all --check` clean, before and after the rebase onto `37bb8948`.
- The new `only_a_real_gamescope_counts` test passes. It covers the flatpak-on-desktop shape (both
with and without some other gamescope running on the box), a real nested gamescope, and Game Mode
with and without a live socket.
- `cargo clippy -D warnings --all-targets` green across `pf-client-core`, `pf-presenter`,
`punktfunk-client-linux` and `punktfunk-client-session`. All four were confirmed really built in
the log rather than skipped as fresh — the warm shared target dir prints `Finished` without
checking otherwise.
**Not verified on glass.** Nobody has yet watched a rebuilt flatpak launch windowed on a desktop,
and no Deck in Game Mode has confirmed it still fullscreens. Both need a flatpak build.
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.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
A field report on 2026-08-30: "the GTK client is just launching in fullscreen." Reproduced on
.21 — a plain GNOME desktop, launched from the
.desktopentry, with no Deck and no gamescopeanywhere on the box.
What causes it
The shell fullscreens itself when
cli::fullscreen_mode()is true, and that readGAMESCOPE_WAYLAND_DISPLAYas proof of Gaming Mode. Our own flatpak sets it unconditionally.packaging/flatpak/io.unom.Punktfunk.ymlexports--env=GAMESCOPE_WAYLAND_DISPLAY=gamescope-0because the vendored gamescope WSI layer reads that one variable and nothing else to decide
whether to negotiate HDR10 — the manifest's own comment calls it "the layer's ONLY 'am I under
gamescope?' signal". So inside the sandbox it is set on every launch, on every desktop.
Verified rather than reasoned: on .21,
flatpak run --command=env io.unom.PunktfunkprintsGAMESCOPE_WAYLAND_DISPLAY=gamescope-0while the host has neither a gamescope process nor a/run/user/1000/gamescope-*socket.The manifest line landed in
e1adc5d6(2026-08-05) and shipped from v0.25.0, which dates theregression. The flatpak is the main Linux channel, so this has hit every flatpak user on every
desktop for six releases.
Fullscreen was the visible quarter of it
The same misreading also meant:
fullscreen_on_stream = false— the env ORed straight past the flag the clientresolves that setting into;
unmapped popovers;
that is not running;
The fix
The variable has to keep being exported — the WSI layer needs it — so the fix is in what we
accept as proof.
pf_client_core::gamescope::under_gamescope()is now the one answer, and all sixreaders route through it:
WAYLAND_DISPLAYsettles it whenever we have one. A desktop session inside the sandbox stillgets
--socket=wayland, so it names the desktop compositor. That mismatch is exactly what theWSI layer itself bails on.
DISPLAY=:1, noWAYLAND_DISPLAY) — so there the fallback is the named socket actually existing. The flatpakbinds it (
--filesystem=xdg-run/gamescope-0) for HDR anyway, so this is the same reachabilitythe layer depends on.
Also dropped the
SteamDeckleg from the Gaming-Mode tests while here, because it names themachine rather than the session, so a Deck in desktop mode was fullscreening too.
is_steam_deck()genuinely wants machine identity and keeps its check, but now compares the value:Valve documents
SteamDeck=1, and desktop Steam exportsSteamDeck=0into everything it launches,so a presence check called every PC with Steam a Deck.
Verification
Run on .21 (CachyOS, GNOME), because
cargo test -p pf-client-coreon macOS is pre-existing redfrom target-gated dependencies:
cargo fmt --all --checkclean, before and after the rebase onto37bb8948.only_a_real_gamescope_countstest passes. It covers the flatpak-on-desktop shape (bothwith and without some other gamescope running on the box), a real nested gamescope, and Game Mode
with and without a live socket.
cargo clippy -D warnings --all-targetsgreen acrosspf-client-core,pf-presenter,punktfunk-client-linuxandpunktfunk-client-session. All four were confirmed really built inthe log rather than skipped as fresh — the warm shared target dir prints
Finishedwithoutchecking otherwise.
Not verified on glass. Nobody has yet watched a rebuilt flatpak launch windowed on a desktop,
and no Deck in Game Mode has confirmed it still fullscreens. Both need a flatpak build.