mirror of
https://github.com/games-on-whales/gow.git
synced 2026-10-15 21:02:02 +00:00
[PR #309] [MERGED] feat: patched Xwayland + gamescope pinning for arbitrary resolutions #293
Labels
No labels
bug
enhancement
enhancement
github_actions
good first issue
help wanted
help wanted
invalid
needs testers
pull-request
question
x11-images
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
games-on-whales/gow#293
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/games-on-whales/gow/pull/309
Author: @JBailes
Created: 4/14/2026
Status: ✅ Merged
Merged: 4/18/2026
Merged by: @ABeltramo
Base:
master← Head:feat/patched-xwayland-arbitrary-resolutions📝 Commits (8)
dc8c48dfeat: patched Xwayland + gamescope pinning for arbitrary resolutionsca7ea6edebug: verbose xwayland build script for CI diagnosis7dcd57ffix: add libxshmfence-dev and libbsd-dev for xwayland build4864975fix: add mesa-common-dev for dri.pc during xwayland build9f0a2d0prismlauncher: pin community PPA codename to noblead24ec5prismlauncher: install from official GitHub portable releasec778b0eprismlauncher: fix jq filter — use contains/endswith not test()4d43898prismlauncher: fix jq word-splitting — chain select() with pipes📊 Changes
4 files changed (+135 additions, -13 deletions)
View changed files
📝
apps/prismlauncher/build/Dockerfile(+22 -11)📝
apps/steam/build/scripts/startup.sh(+4 -1)📝
images/base-app/build/Dockerfile(+105 -0)📝
images/base-app/build/scripts/launch-comp.sh(+4 -1)📄 Description
Problem
Games streamed through gow can't render at non-standard native resolutions. A 3:2 laptop panel (e.g. 2256x1504, Framework 13 / Surface / MBP-style) or ultrawide/super-ultrawide gets letterboxed: game renders at the nearest standard 16:9 preset gamescope knows about (e.g. 2560x1440), gamescope scales that into the non-16:9 output canvas, black bars appear.
Root cause isn't in gow or Wolf — it's Xwayland's hardcoded
xwl_output_fake_modes[]table inhw/xwayland/xwayland-output.c. Xwayland unconditionally synthesizes a list of "standard" modes (1920x1080, 2560x1440, 3840x2160, ...) and advertises them to X11 clients via XRandR emulation, regardless of what the Wayland compositor actually exposes. There is no upstream flag, env var, or Wayland protocol that disables this — confirmed by reading the xserver source.Fix
Two changes, neither large:
1. Patched Xwayland, built into
images/base-appNew
xwayland-builderstage inimages/base-app/build/Dockerfile:xwayland-*stable tag fromgitlab.freedesktop.org/xorg/xserverat build time.COPYs the built tree into/usr/local, and a symlink at/usr/bin/Xwaylandshadows the distro binary for anything that hardcodes the path.The patch (targets the symbol, not line numbers):
Every
for (i = 0; i < ARRAY_SIZE(xwl_output_fake_modes); i++)becomes a zero-trip loop, the compiler drops it, the fake-mode list vanishes. Result: Xwayland advertises exactly what the Wayland compositor says — nothing more.Build-time guardrails:
BEFORE=$(grep -c ...)— must find ≥1 match before the sed, otherwise build aborts with a message pointing to "upstream structure may have changed, refresh the patch".AFTER=$(grep -c ...)— must be 0 after the sed, else build aborts.Xwayland -versionis run in the final stage to confirm the binary is present and PATH resolution picks ours.Why the latest-stable tag at build time and not a pinned version: Valve's SteamOS
xorg-xwayland-24.1.9-1.1is a stock upstream rebuild with zero Valve patches, so "match Valve" collapses to "match upstream stable". Pinning adds a maintenance burden (manual bumps when CVEs ship) without a corresponding benefit. Pulling at build time means each gow image rebuild picks up current Xwayland.Why sed on a sentinel symbol, not a line-numbered diff: line numbers in
xwayland-output.cshift when upstream adds or moves code. A symbol-based transformation survives refactors as long as the array keeps its name.xwl_output_fake_modeshas existed under that name since the feature landed in 2019.2. Pin gamescope's internal resolution
apps/steam/build/scripts/startup.shandimages/base-app/build/scripts/launch-comp.shnow pass-w "${GAMESCOPE_WIDTH}" -h "${GAMESCOPE_HEIGHT}"alongside the existing-W/-H. Orthogonal to the Xwayland patch: pins gamescope's nested Wayland output size so there's no room for a downstream component to round to a "standard" size. Matters for the future split-screen work where gamescope instances run at quarter-size (1128x752, etc.).What this unblocks
Short term: users with 3:2 laptops, ultrawide monitors, or any non-16:9 native resolution get true full-screen rendering at their panel's actual size instead of a letterboxed approximation.
Medium term: prerequisite for party-mode / split-screen streaming. In that architecture each player gets a per-tile gamescope instance at an arbitrary resolution (e.g. 2x2 of half-by-half dimensions). Without the Xwayland fix, every tile would round to the nearest standard mode and be letterboxed — making split-screen visually broken.
Risks / caveats
XRRSetScreenConfig()to mode-switch now have only one mode available and will no-op or error. In practice: gamescope handles this by rendering the app into its own window and scaling, which is the same outcome as before. No real regression.git ls-remoteto freedesktop.org. If that site is unreachable at build time, CI fails. Acceptable failure mode; mirror can be added later if it becomes a problem.xwl_output_fake_modes(e.g. because they finally made the feature configurable), our sed finds nothing and the build fails with a clear message to refresh. This is the correct failure mode — we'd want to know and choose a new approach rather than silently building an unpatched binary.Testing
Not locally buildable in this environment (Proxmox LXC-docker shim doesn't support
docker build). CI is the first real build — if meson fails or the sentinel assertions trip, it'll be visible in the workflow log.Once merged and an image is published, verification:
Xwayland -versioninside any base-app-derived container runs and reports a versionRUN_GAMESCOPE=trueandGAMESCOPE_MODE="-b -w $W -h $H"— game's video settings should list only the native resolution, no standard-mode fallbacks🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.