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
@@ -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