mirror of
https://github.com/theupriser/steamify-cachyos.git
synced 2026-10-13 20:35:40 +02:00
feat: the gaming session on NVIDIA runs on the display's own mode, Steam's UI at its size; pin 3.16.31-2
Sync git.upriser.nl mirror / sync (push) Skipped
Sync git.upriser.nl mirror / sync (push) Skipped
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KkpbsMw4rQyBsxDG6ebHK2
This commit is contained in:
1 parent
d4bb4c4d92
commit
59e941e8e4
8 files changed
+155
-13
No files matched your search
@@ -48,11 +48,15 @@ gamescope and the Plasma desktop. Primary target: the Valve Steam Machine
|
||||
`<id>_available` is checked via `component_available` (e.g. `machine`
|
||||
only on Fremont). Turn-on order is `COMPONENTS` order, turn-off reverse;
|
||||
`gaming` must stay first. Dependencies live in `toggle_component`.
|
||||
- **NVIDIA** (`lib/nvidia.sh`): gamescope's session is broken on NVIDIA, so the SteamOS conversion (`gaming`, `boot`, `single`,
|
||||
`glyphs`) is hidden there (unless already on) and `nvidia` + its sub-option `bigpicture` ("Gaming on NVIDIA") replace it:
|
||||
Steam on the Plasma desktop, started at login. Never reintroduce a gamescope session for NVIDIA without re-testing on the
|
||||
hardware (notes: steamify-cachyos-dev, `nvidia/`). It can't be tested without the hardware: keep the branch behind
|
||||
`.no-release-yet` until it was.
|
||||
- **NVIDIA** (`lib/gamescope-nvidia.sh`, `lib/nvidia.sh`): since 2.11.2 the SteamOS conversion (`gaming` and its options) runs on
|
||||
NVIDIA PCs with a patched gamescope (GBM scan-out: gamescope#2309; Steam's UI kept at the display's size), downloaded as the
|
||||
newest release of theupriser/steamify-gamescope-nvidia, with the pinned package (`GSN_VERSION`, `GSN_SHA256`), the copy the ISO
|
||||
leaves, and a build here (`patches/gamescope-nvidia.PKGBUILD` + the two patches) as the fallback. "Gaming on NVIDIA" (`nvidia`,
|
||||
`bigpicture`, `nvsilent`) isn't offered any more (`nvidia_available`); turning the conversion on turns it off (`nvidia_swap_out`).
|
||||
A new pin = the release's tag + its sha256 in `lib/gamescope-nvidia.sh` and the PKGBUILD's pkgver/pkgrel, copied from the
|
||||
repository (the patches in `patches/` must stay identical to that repository's). Steam must keep running with `-steamos3`
|
||||
(without it games don't launch in gaming mode and the settings pages go): never "fix" the UI size by dropping flags or by
|
||||
`XWAYLAND_COUNT`. Tested on an RTX 5080 only; keep the branch behind `.no-release-yet` until the whole flow ran on hardware.
|
||||
- **Feature versions.** Set `FEATURE_VERSION[<id>]` (`lib/menu.sh`) to the new
|
||||
`VERSION` whenever what `<id>_enable` sets up changes (a new component gets
|
||||
one too): installs recorded with an older version
|
||||
|
||||
@@ -7,6 +7,8 @@ one per merged pull request.
|
||||
|
||||
## 2.11.2 - 2026-10-13
|
||||
|
||||
- **feat: on NVIDIA the gaming session runs on the display's own mode and Steam's interface at its size: a second gamescope patch (`gamescope-ui-native.patch`, release `3.16.31-2` of steamify-gamescope-nvidia, now the pin) keeps Steam's UI X server at the output size when Steam (with `-steamos3`) asks for 1920x1080, and a wrapper (`gamescope-display-wrapper.sh`, set up by the conversion with a drop-in of `gamescope-session.service`) starts gamescope on the mode KDE has saved for the connected display, else the biggest mode at the highest refresh rate: before, gaming mode ran at the display's preferred mode (60 Hz on many monitors) with a 1080p Steam UI. Tested on an RTX 5080, 3440x1440@175: widescreen, sharp, a Proton game starts**
|
||||
|
||||
- **fix: on an NVIDIA PC that had single user mode on before the SteamOS conversion, "Return to Gaming Mode" and the boot choice work again: single user mode's desktop autologin (`zzz-steamify-autologin.conf`, read last) pinned the Plasma session; the conversion removes it, and turning the conversion off sets it up again**
|
||||
|
||||
- **fix: when an option fails, its sub-options are not applied any more (a failed conversion used to leave its "Boot into the desktop", silent start and icons on without it)**
|
||||
|
||||
+43
-3
@@ -20,8 +20,8 @@ GSN_PKG=steamify-gamescope-nvidia
|
||||
GSN_RELEASES="${GSN_RELEASES:-https://github.com/theupriser/steamify-gamescope-nvidia/releases}"
|
||||
# The package this Steamify release was tested with (patches/gamescope-nvidia.PKGBUILD names the same version): the
|
||||
# fallback. A new pin: the release's tag, the package's sha256, and the PKGBUILD's pkgver/pkgrel.
|
||||
GSN_VERSION=3.16.31-1
|
||||
GSN_SHA256=9f20e5243866d1ddeb9ba0c6828bc7be1945f623f9a5d8094391f0df043002e1
|
||||
GSN_VERSION=3.16.31-2
|
||||
GSN_SHA256=3b981bed4dfdac383d22b8c22feaef191c2f2863bccf5676d1ec959c2c5ee3a3
|
||||
# Where the ISO leaves a copy of the pinned package, for installs without GitHub.
|
||||
GSN_BACKUP_DIR="${GSN_BACKUP_DIR:-/usr/local/share/steamify/gamescope}"
|
||||
# How long a look at GitHub for a newer release counts (seconds), so opening the menu doesn't ask every time.
|
||||
@@ -123,7 +123,8 @@ gsn_build_package() {
|
||||
# On disk, not /tmp: the installer's chroot has a tmpfs there (RAM), and the build is 1-2 GB.
|
||||
mkdir -p "$cache" && dir="$(mktemp -d -p "$cache" gamescope-build.XXXXXX)" || return 1
|
||||
patch_file gamescope-nvidia.PKGBUILD > "$dir/PKGBUILD" &&
|
||||
patch_file gamescope-gbm-scanout.patch > "$dir/gamescope-gbm-scanout.patch" || {
|
||||
patch_file gamescope-gbm-scanout.patch > "$dir/gamescope-gbm-scanout.patch" &&
|
||||
patch_file gamescope-ui-native.patch > "$dir/gamescope-ui-native.patch" || {
|
||||
err "Couldn't write the build files." >&2
|
||||
rm -rf "$dir"; return 1
|
||||
}
|
||||
@@ -179,6 +180,43 @@ gsn_env_disable() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# --- The session starts gamescope on the display's own mode
|
||||
#
|
||||
# gamescope-session starts gamescope without a size or a refresh rate, so it takes the display's *preferred* mode, which
|
||||
# many monitors declare as 60 Hz while the desktop runs them at their highest. patches/gamescope-display-wrapper.sh (put
|
||||
# first in the gaming session's PATH by a drop-in of gamescope-session.service) starts it on the mode KDE has saved for
|
||||
# the connected display, else the biggest mode at the highest refresh rate, read at every session start.
|
||||
GSN_DISPLAY_WRAPPER="${GSN_DISPLAY_WRAPPER:-$STEAMIFY_BIN/gamescope}"
|
||||
GSN_DISPLAY_DROPIN="${GSN_DISPLAY_DROPIN:-$HOME/.config/systemd/user/gamescope-session.service.d/steamify-display.conf}"
|
||||
|
||||
gsn_display_status() { [[ -x "$GSN_DISPLAY_WRAPPER" && -f "$GSN_DISPLAY_DROPIN" ]]; }
|
||||
|
||||
gsn_display_pending() {
|
||||
# The patched gamescope is in use but the session still starts it on the display's preferred mode: a normal run sets it up.
|
||||
gsn_package_installed && gsn_env_set && ! gsn_display_status
|
||||
}
|
||||
|
||||
gsn_display_enable() {
|
||||
patch_file gamescope-display-wrapper.sh | install_executable "$GSN_DISPLAY_WRAPPER" 755 || return 1
|
||||
mkdir -p "$(dirname "$GSN_DISPLAY_DROPIN")"
|
||||
cat > "$GSN_DISPLAY_DROPIN" << EOF
|
||||
# Steamify: the gaming session starts gamescope on the display's own mode (see lib/gamescope-nvidia.sh). Turning the
|
||||
# SteamOS conversion off removes this file.
|
||||
[Service]
|
||||
ExecStart=
|
||||
ExecStart=/usr/bin/bash -c 'PATH="$(dirname "$GSN_DISPLAY_WRAPPER"):\$PATH" exec /usr/lib/steamos/gamescope-session'
|
||||
EOF
|
||||
user_systemctl daemon-reload
|
||||
}
|
||||
|
||||
gsn_display_disable() {
|
||||
# Only our own files: the wrapper is recognised by its first comment line.
|
||||
grep -qs "^# Steamify: gamescope-session starts gamescope" "$GSN_DISPLAY_WRAPPER" && rm -f "$GSN_DISPLAY_WRAPPER"
|
||||
[[ -f "$GSN_DISPLAY_DROPIN" ]] && rm -f "$GSN_DISPLAY_DROPIN" && rmdir "$(dirname "$GSN_DISPLAY_DROPIN")" 2>/dev/null
|
||||
user_systemctl daemon-reload
|
||||
return 0
|
||||
}
|
||||
|
||||
gsn_enable() {
|
||||
# Only on a supported NVIDIA card; elsewhere the stock gamescope is right.
|
||||
nvidia_present || return 0
|
||||
@@ -191,6 +229,7 @@ gsn_enable() {
|
||||
nvidia_extras_enable || return 1
|
||||
gsn_install_package || return 1
|
||||
gsn_env_enable
|
||||
gsn_display_enable || warn "Couldn't set up the display mode for gaming mode: gamescope takes the display's preferred mode."
|
||||
ok "gamescope draws NVIDIA's picture through GBM (gamescope_drm_gbm_scanout=1) from the next gaming mode start."
|
||||
}
|
||||
|
||||
@@ -198,6 +237,7 @@ gsn_disable() {
|
||||
# The setting goes, and what nvidia_*_enable added; the packages stay (patched gamescope, 32-bit libraries), like
|
||||
# the other packages of the conversion (steam, gamescope-session-cachyos).
|
||||
gsn_env_disable
|
||||
gsn_display_disable
|
||||
nvidia_present || return 0
|
||||
nvidia_extras_disable
|
||||
nvidia_kernel_disable
|
||||
|
||||
+1
-1
@@ -117,7 +117,7 @@ feature_outdated() {
|
||||
[[ "$1" == gaming ]] && nvidia_migration_pending && return 0
|
||||
[[ "${CURRENT[$1]:-0}" == 1 ]] || return 1
|
||||
# NVIDIA: a newer patched gamescope is out (lib/gamescope-nvidia.sh): a normal run installs it.
|
||||
[[ "$1" == gaming ]] && nvidia_present && gsn_update_pending && return 0
|
||||
[[ "$1" == gaming ]] && nvidia_present && { gsn_update_pending || gsn_display_pending; } && return 0
|
||||
have="$(state_get features "$1" "$FEATURE_BASELINE")"
|
||||
[[ "$have" == off ]] && have="$FEATURE_BASELINE"
|
||||
want="${FEATURE_VERSION[$1]:-$FEATURE_BASELINE}"
|
||||
|
||||
@@ -20,3 +20,5 @@ read and reviewed on their own. `lib/*.sh` reads them with `patch_file
|
||||
| `gamescope-nvidia.PKGBUILD` | `lib/gamescope-nvidia.sh` (gamescope on NVIDIA) | The recipe for the patched gamescope package (`steamify-gamescope-nvidia`, provides and conflicts with `gamescope`): Valve's gamescope at `pkgver` plus `gamescope-gbm-scanout.patch`; written with the patch to a temporary folder and built with `makepkg` |
|
||||
| `cros-ec-cec.c` | `lib/cec.sh` (HDMI-CEC) | Valve's Steam Machine CEC driver (GPL-2.0+, from evlaV/linux-integration at the pinned commit): the backup when downloading it from GitHub fails; used only if its sha256 equals `CEC_DRIVER_SHA256` (a new pin needs a new copy) |
|
||||
| `python-hid-shim.PKGBUILD` | `lib/packages.sh` (required packages) | An empty package that provides `python-hid`, for PCs that keep `python-hidapi` (they conflict; jupiter-hw-support, a dependency of gamescope-session-cachyos, wants python-hid, only the Steam Deck controller updater uses it): built with `makepkg` and installed before the conversion's packages |
|
||||
| `gamescope-ui-native.patch` | `lib/gamescope-nvidia.sh` (gamescope on NVIDIA) | Small patch after the GBM one: keeps Steam's UI X server at the display's size when Steam (with `-steamos3`) asks for 1920x1080; `gamescope_xwayland_ui_native=0` turns it off |
|
||||
| `gamescope-display-wrapper.sh` | `lib/gamescope-nvidia.sh` (gamescope on NVIDIA) | Installed as `gamescope` in Steamify's bin folder and put first in the gaming session's PATH: starts gamescope on the mode KDE has saved for the connected display, else the biggest mode at the highest refresh rate (modetest + `kwinoutputconfig.json`) |
|
||||
@@ -0,0 +1,51 @@
|
||||
#!/bin/bash
|
||||
# Steamify: gamescope-session starts gamescope without a size or a refresh rate, so it takes the display's *preferred* mode,
|
||||
# which many monitors declare as 60 Hz (the faster modes sit in an extension block of the EDID). This starts it the way the
|
||||
# desktop runs that display: the mode KDE has saved for the connected display (System Settings > Display), when the display
|
||||
# still has it, else its biggest mode at the highest refresh rate.
|
||||
# Read at every session start (modetest, part of libdrm which gamescope needs, and KDE's ~/.config/kwinoutputconfig.json), so
|
||||
# changing the resolution in KDE, another monitor or a TV just works. Anything unclear (no modetest output, no modes, more than
|
||||
# one display connected: gamescope chooses which one it uses) leaves gamescope's own choice alone.
|
||||
real=/usr/bin/gamescope
|
||||
|
||||
modes() {
|
||||
# One line per mode of every connected connector: "<connector> <width> <height> <refresh>"
|
||||
local m
|
||||
for m in nvidia-drm amdgpu i915 xe nouveau radeon; do
|
||||
timeout 10 modetest -M "$m" -c 2>/dev/null | awk '
|
||||
/^[0-9]+[ \t]+[0-9]+[ \t]+(connected|disconnected|unknown)/ { conn = ($3 == "connected") ? $4 : ""; next }
|
||||
conn != "" && /^[ \t]+#[0-9]+ [0-9]+x[0-9]+ [0-9.]+ / && !/interlace/ {
|
||||
split($2, wh, "x"); printf "%s %d %d %.0f\n", conn, wh[1], wh[2], $3
|
||||
}'
|
||||
done
|
||||
}
|
||||
|
||||
kde_mode() {
|
||||
# kde_mode <connector>: "<width> <height> <refresh>" as KDE has it saved for that connector, or nothing.
|
||||
python3 -I - "$1" "${XDG_CONFIG_HOME:-$HOME/.config}/kwinoutputconfig.json" 2>/dev/null << 'EOF'
|
||||
import json, sys
|
||||
try:
|
||||
for block in json.load(open(sys.argv[2])):
|
||||
if block.get("name") == "outputs":
|
||||
for o in block.get("data", []):
|
||||
m = o.get("mode")
|
||||
if o.get("connectorName") == sys.argv[1] and m:
|
||||
print(m["width"], m["height"], round(m["refreshRate"] / 1000))
|
||||
except Exception:
|
||||
pass
|
||||
EOF
|
||||
}
|
||||
|
||||
args=()
|
||||
all="$(modes)"
|
||||
conn="$(awk '{print $1}' <<< "$all" | sort -u)"
|
||||
if [[ -n "$conn" && "$(wc -l <<< "$conn")" == 1 ]]; then
|
||||
read -r w h r <<< "$(kde_mode "$conn")"
|
||||
# KDE's mode only counts when the display really has it (a refresh rate within 1 Hz).
|
||||
if [[ -z "${w:-}" ]] || ! awk -v w="$w" -v h="${h:-0}" -v r="${r:-0}" '$2 == w && $3 == h && ($4 - r < 2 && r - $4 < 2) {f = 1} END {exit !f}' <<< "$all"; then
|
||||
read -r _ w h r < <(awk '{print $2 * $3, $2, $3, $4}' <<< "$all" | sort -k1,1nr -k4,4nr | head -1 | awk '{print "x", $2, $3, $4}')
|
||||
fi
|
||||
[[ "${w:-0}" -gt 0 && "${h:-0}" -gt 0 && "${r:-0}" -gt 0 ]] && args=(-W "$w" -H "$h" -r "$r")
|
||||
fi
|
||||
if [[ "${1:-}" == --print-args ]]; then echo "${args[*]}"; exit 0; fi
|
||||
exec "$real" "${args[@]}" "$@"
|
||||
@@ -2,14 +2,14 @@
|
||||
# Based on Arch Linux's gamescope PKGBUILD (Maxime Gauduin, Giancarlo Razzolini, Sven-Hendrik Haase and contributors).
|
||||
#
|
||||
# gamescope with GBM-allocated scan-out buffers for NVIDIA (opt-in: gamescope_drm_gbm_scanout=1).
|
||||
# The patch is gamescope-gbm-scanout.patch (next to this file; see its header for where it comes from). pkgver is the gamescope
|
||||
# release the patch was made for and tested with. Kept in sync with https://github.com/theupriser/steamify-gamescope-nvidia;
|
||||
# Steamify (lib/gamescope-nvidia.sh) writes both files into a temporary folder and runs makepkg there.
|
||||
# The patches are gamescope-gbm-scanout.patch and gamescope-ui-native.patch (next to this file, applied in this order); see the
|
||||
# README for where they come from.
|
||||
# UPSTREAM_VERSION (next to this file) names the gamescope tag the patch is made for.
|
||||
|
||||
pkgname=steamify-gamescope-nvidia
|
||||
_srcname=gamescope
|
||||
pkgver=3.16.31
|
||||
pkgrel=1
|
||||
pkgrel=2
|
||||
pkgdesc='SteamOS session compositing window manager, with GBM scan-out for NVIDIA (opt-in: gamescope_drm_gbm_scanout=1)'
|
||||
arch=(x86_64)
|
||||
url=https://github.com/theupriser/steamify-gamescope-nvidia
|
||||
@@ -73,6 +73,7 @@ makedepends=(
|
||||
source=(
|
||||
gamescope::git+https://github.com/ValveSoftware/gamescope.git#commit=${pkgver}
|
||||
gamescope-gbm-scanout.patch
|
||||
gamescope-ui-native.patch
|
||||
git+https://gitlab.freedesktop.org/emersion/libdisplay-info.git
|
||||
git+https://gitlab.freedesktop.org/emersion/libliftoff.git
|
||||
git+https://github.com/ValveSoftware/openvr.git
|
||||
@@ -89,6 +90,7 @@ b2sums=('SKIP'
|
||||
'SKIP'
|
||||
'SKIP'
|
||||
'SKIP'
|
||||
'SKIP'
|
||||
'SKIP')
|
||||
|
||||
prepare() {
|
||||
@@ -98,6 +100,8 @@ prepare() {
|
||||
# silently produce an unpatched gamescope under this package's name.
|
||||
git apply --check ../gamescope-gbm-scanout.patch || { echo "gbm patch does not apply to gamescope ${pkgver}" >&2; return 1; }
|
||||
git apply ../gamescope-gbm-scanout.patch
|
||||
git apply --check ../gamescope-ui-native.patch || { echo "ui-native patch does not apply to gamescope ${pkgver}" >&2; return 1; }
|
||||
git apply ../gamescope-ui-native.patch
|
||||
|
||||
meson subprojects download
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
Keeps Steam's UI X server (server 0) at the output size when Steam asks for a smaller one.
|
||||
|
||||
With -steamos3 (what gamescope-session-cachyos passes) Steam sets its UI to 1920x1080 right after it starts
|
||||
(GAMESCOPE_XWAYLAND_MODE_CONTROL), so on a bigger display, and on one that isn't 16:9, the whole interface is a scaled-up
|
||||
1080p picture. Games already run at the display's size. With this the server stays at the output size and Steam draws its
|
||||
window to match; Steam's SteamOS features (settings pages, game launching) keep working. Written for Steamify on an NVIDIA
|
||||
PC (RTX 5080, 3440x1440@175, tested with Steam's UI and a Proton game); not part of the farnoy patch. On by default; the
|
||||
setting gamescope_xwayland_ui_native=0 (in gamescope's environment) turns it off.
|
||||
Applies with `git apply` after gamescope-gbm-scanout.patch (it ignores these lines).
|
||||
|
||||
diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
|
||||
index 2cb5eb5..ce14c8d 100644
|
||||
--- a/src/steamcompmgr.cpp
|
||||
+++ b/src/steamcompmgr.cpp
|
||||
@@ -129,6 +129,8 @@ LogScope g_WaitableLog("waitable");
|
||||
|
||||
gamescope::ConVar<bool> cv_overlay_unmultiplied_alpha{ "overlay_unmultiplied_alpha", false };
|
||||
|
||||
+gamescope::ConVar<bool> cv_xwayland_ui_native( "xwayland_ui_native", true, "Keep the Steam UI X server (server 0) at the output size when Steam asks for a smaller one." );
|
||||
+
|
||||
gamescope::ConVar<bool> cv_vr_show_forwarded_overlays{ "vr_show_forwarded_overlays", false };
|
||||
|
||||
std::string *g_pVROverlayKey = nullptr;
|
||||
@@ -7240,6 +7242,15 @@ handle_property_notify(xwayland_ctx_t *ctx, XPropertyEvent *ev)
|
||||
height = std::min<int>(height, currentOutputHeight);
|
||||
}
|
||||
|
||||
+ // Steam asks for a smaller size for its own UI (server 0, 1920x1080 with -steamos3), which makes the whole
|
||||
+ // interface a scaled-up picture on a bigger display, and on one that isn't 16:9 as well. The UI server
|
||||
+ // stays at the output size: Steam sizes its window to the server.
|
||||
+ if ( server_idx == 0 && cv_xwayland_ui_native )
|
||||
+ {
|
||||
+ width = currentOutputWidth;
|
||||
+ height = currentOutputHeight;
|
||||
+ }
|
||||
+
|
||||
gamescope_xwayland_server_t *server = wlserver_get_xwayland_server( server_idx );
|
||||
if ( server )
|
||||
{
|
||||
Reference in new issue
Block a user