feat(client/pads): stop forwarding the pad while the Steam overlay owns it
ci / bun-nix (pull_request) Successful in 32s
ci / docs-site (pull_request) Successful in 1m21s
ci / web (pull_request) Successful in 1m37s
apple / swift (pull_request) Successful in 1m41s
apple / screenshots (pull_request) Skipped
windows / build (x86_64-pc-windows-msvc) (pull_request) Successful in 2m19s
windows / build (aarch64-pc-windows-msvc) (pull_request) Successful in 1m37s
ci / rust-arm64 (pull_request) Successful in 5m50s
android / android (pull_request) Successful in 7m56s
ci / rust (pull_request) Successful in 15m55s
nix / flake (pull_request) Failing after 16m33s
ci / bun-nix (pull_request) Successful in 32s
ci / docs-site (pull_request) Successful in 1m21s
ci / web (pull_request) Successful in 1m37s
apple / swift (pull_request) Successful in 1m41s
apple / screenshots (pull_request) Skipped
windows / build (x86_64-pc-windows-msvc) (pull_request) Successful in 2m19s
windows / build (aarch64-pc-windows-msvc) (pull_request) Successful in 1m37s
ci / rust-arm64 (pull_request) Successful in 5m50s
android / android (pull_request) Successful in 7m56s
ci / rust (pull_request) Successful in 15m55s
nix / flake (pull_request) Failing after 16m33s
On a Deck in Gaming Mode the Steam menu and the QAM are driven by the SAME physical controller the client forwards, so opening either one moved the game on the host as well as Steam's UI — a second, invisible player. Steam Input masks a normal game here; it cannot mask us, because masking happens on Steam Input's virtual pad and we deliberately forward the REAL one (28DE:1205 — the virtual pad has no gyro, trackpads or paddles). SDL ships the exact behaviour we want and it is on by default: presses are dropped while the process has windows but no keyboard focus, releases still get through. It CANNOT fire on a Deck. gamescope resolves focus per Xwayland ctx and the client sits alone in its own, so the Steam overlay — which lives in the root ctx — never takes our X focus away and no FocusOut is ever generated. Measured on glass: with the QAM open, X input focus inside the client's ctx stayed on its window for the whole 4 s, while GAMESCOPE_FOCUSED_APP flipped to 769 (Steam) and GAMESCOPE_FOCUSED_APP_GFX stayed on the app. So the signal is explicit. `overlay_focus` watches those two atoms on the gamescope root ctx — which is NOT our own $DISPLAY under `--xwayland-count 2`, hence the socket-directory walk and the flatpak filesystem line — and the presenter ORs it with window focus into one `set_masked`. Masking is deliberately not `set_forwarding`: that closes the slot and sends GamepadRemove, so the game would see a controller UNPLUG every time somebody opened the QAM. This keeps every slot open and only stops the transitions, after flushing what the host believes is held so a stick deflected at overlay-open stops steering instead of freezing at its last value. On the way back, held buttons are adopted rather than replayed — the A that picked a QAM row must not fire in the game as it closes — while axes are re-sent, since a stick has no press to ghost and SDL only speaks on change. Fails open throughout: no gamescope, no X, or an unreadable signal all leave forwarding exactly as it was. `PUNKTFUNK_OVERLAY_MASK=0` opts out.
This commit is contained in:
@@ -65,6 +65,14 @@ finish-args:
|
||||
- --socket=wayland # GTK4 native Wayland window (the client is Wayland-first)
|
||||
- --socket=fallback-x11 # Xwayland fallback when no Wayland socket is exposed
|
||||
- --share=ipc # required alongside X11 for shared-memory surfaces
|
||||
# Gaming Mode's overlay signal lives on a DIFFERENT X server than ours. gamescope runs
|
||||
# `--xwayland-count 2`: Steam and the GAMESCOPE_FOCUSED_APP/_GFX atoms are on the first,
|
||||
# the app is handed the second, so `$DISPLAY` alone can never see them — and --socket=x11
|
||||
# would not help, since flatpak binds only the ONE socket named by DISPLAY. Read-only
|
||||
# access to the socket directory is what lets `overlay_focus` reach the root ctx and stop
|
||||
# forwarding the pad while the Steam menu / QAM is up. gamescope's Xwayland takes
|
||||
# unauthenticated local connections, so no cookie has to cross with it.
|
||||
- --filesystem=/tmp/.X11-unix:ro
|
||||
# --- GPU + all input devices ---
|
||||
# --device=all (not just --device=dri): covers the GPU render node (VAAPI HEVC decode + GL),
|
||||
# evdev joysticks, AND the hidraw CHAR devices SDL3's HIDAPI needs for DualSense touchpad/
|
||||
|
||||
Reference in New Issue
Block a user