diff --git a/README.md b/README.md index 5d5d024..31747d9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # DeckShift -**Version 0.1.6** — Steam Deck-style gaming mode for [Omarchy](https://omarchy.com). Press `Super+Shift+S` to enter Gaming Mode (Steam Big Picture in Gamescope), `Super+Shift+R` to return to your desktop. +**Version 0.1.8** — Steam Deck-style gaming mode for [Omarchy](https://omarchy.com). Press `Super+Shift+S` to enter Gaming Mode (Steam Big Picture in Gamescope), `Super+Shift+R` to return to your desktop. Lineage: forked from [Super-Shift-S-Omarchy-Deck-Mode](https://git.no-signal.uk/nosignal/Super-Shift-S-Omarchy-Deck-Mode), briefly renamed Omarchy Deck, then renamed DeckShift. @@ -10,6 +10,16 @@ Lineage: forked from [Super-Shift-S-Omarchy-Deck-Mode](https://git.no-signal.uk/ ## What's New +### v0.1.8 — Settings TUI now reaches gamescope without re-login + +- The Settings TUI used to write `~/.config/environment.d/gamescope-session-plus.conf` and rely on the user logging out before the change reached `gamescope-session-plus@.service`. Saving the TUI now calls `systemctl --user import-environment` for the keys it just wrote, so the next Gaming Mode launch picks up the new values immediately. +- Refresh-rate writes are now a comma list with `60` as the floor (e.g. `60,165`) rather than a single value. Gamescope's `--custom-refresh-rates` is a list of switchable rates, not a launch-rate selector — keeping `60` in the list guarantees a safe fallback if the high-rate mode isn't enumerated on first launch. +- Fixes a reported regression where Gaming Mode always launched at 60 Hz on NVIDIA + HDMI even though the TUI showed the user's chosen rate. + +### v0.1.7 — Foot terminal compatibility + +- Internal: confirmed DeckShift Settings TUI works unchanged with Omarchy's new `foot` terminal (in addition to kitty / ghostty / alacritty). No code changes required — Omarchy's stock floating-window rule already lists foot's native class. + ### v0.1.6 — Omarchy-only, simpler portal recovery - Dropped the non-Omarchy fallback in `deckshift-portal-recovery` — DeckShift targets Omarchy only, so the helper now just calls `omarchy-restart-walker` directly. @@ -477,6 +487,18 @@ If you're on AC and using Omarchy, this is expected — see the *Performance Mod - Older Gen8/9 Intel iGPUs (Skylake, Kaby Lake) struggle with Vulkan workloads. Lower the launch resolution via the Settings TUI (`deckshift-settings`) — 720p / 1080p makes a big difference. - If you have a discrete GPU that should take over, check its driver is loaded: `lspci -k | grep -A2 VGA` +**Gaming Mode launches at 60 Hz even though I picked a higher rate in the TUI** + +`--custom-refresh-rates` is gamescope's list of *switchable* rates, not a launch-rate selector. On embedded/DRM output (especially NVIDIA + HDMI) gamescope picks the connector's EDID-preferred mode at first launch, which is usually 60 Hz even when higher modes are enumerated. Two-step fix: + +1. Confirm the env var actually reached the session: + ```bash + systemctl --user show-environment | grep REFRESH + journalctl --user -u "gamescope-session-plus@*" -b --no-pager | grep -m1 -- '--custom-refresh-rates' + ``` + In v0.1.8+ this should work without re-login — the Settings TUI now calls `systemctl --user import-environment` on save. If you're on an older release, log out and back in once after saving in the TUI. +2. Once Steam Big Picture is up, set the rate explicitly: Settings → Display → Refresh Rate → your rate. Steam persists this client-side, so every subsequent Gaming Mode launch will go straight to that rate. + ### Log Locations | Component | Command | diff --git a/bin/deckshift-settings b/bin/deckshift-settings index 8a105de..5631d37 100755 --- a/bin/deckshift-settings +++ b/bin/deckshift-settings @@ -109,6 +109,19 @@ flush_pending() { echo "${key}=${value}" >> "$CONF" fi done + + # environment.d/*.conf is parsed by `systemd --user` at user-manager startup, + # so edits made here don't reach gamescope-session-plus@.service until the + # next login unless we nudge systemd. import-environment pulls the keys we + # just wrote into the running user manager scope so the next Gaming Mode + # launch sees them without a re-login. + if [[ ${#PENDING_SET[@]} -gt 0 ]]; then + # shellcheck disable=SC2046 + systemctl --user import-environment $(printf '%s ' "${!PENDING_SET[@]}") 2>/dev/null || true + fi + if [[ ${#PENDING_UNSET[@]} -gt 0 ]]; then + systemctl --user unset-environment "${!PENDING_UNSET[@]}" 2>/dev/null || true + fi } # ------------------------------------------------------------------------------ @@ -225,6 +238,12 @@ show_state() { width=$(effective SCREEN_WIDTH) height=$(effective SCREEN_HEIGHT) refresh=$(effective CUSTOM_REFRESH_RATES) + # Stored as a comma list (e.g. "60,165") so gamescope has a safe 60 Hz + # fallback. The user only cares about the rate they picked — the highest + # member of the list. + if [[ "$refresh" == *,* ]]; then + refresh=$(tr ',' '\n' <<<"$refresh" | sort -nr | head -1) + fi vk_adapter=$(effective VULKAN_ADAPTER) dri_prime=$(effective DRI_PRIME) prime_offload=$(effective __NV_PRIME_RENDER_OFFLOAD) @@ -385,7 +404,17 @@ choose_refresh_rate() { rate=${choice%% *} fi [[ -z "$rate" ]] && return 0 - pending_set CUSTOM_REFRESH_RATES "$rate" + + # gamescope-session-plus passes this env value to gamescope as + # --custom-refresh-rates, which is a list of *switchable* rates the user can + # cycle between in Steam Big Picture. Writing a single value (e.g. "165") can + # leave gamescope without a safe 60 Hz fallback if the monitor's EDID + # preferred mode is 60 Hz and the high-rate mode isn't enumerated on first + # launch — most visibly on NVIDIA HDMI outputs. Always include 60 as the + # floor so Steam can fall back and the user can switch up to their pick. + local rate_list="$rate" + [[ "$rate" != "60" ]] && rate_list="60,${rate}" + pending_set CUSTOM_REFRESH_RATES "$rate_list" } # Keys this menu owns. Cleared at the start of every selection so switching @@ -526,6 +555,11 @@ confirm_risky_save() { w=$(effective SCREEN_WIDTH) h=$(effective SCREEN_HEIGHT) rate=$(effective CUSTOM_REFRESH_RATES) + # Check the user's actual pick (highest of the comma list) against monitor + # support — not the bare list, which won't match a single mode line. + if [[ "$rate" == *,* ]]; then + rate=$(tr ',' '\n' <<<"$rate" | sort -nr | head -1) + fi local -a warnings=() if [[ -n "$w" && -n "$h" ]] && ! resolution_supported "$w" "$h"; then diff --git a/deckshift.sh b/deckshift.sh index 0f56252..e479956 100755 --- a/deckshift.sh +++ b/deckshift.sh @@ -34,7 +34,7 @@ set -Euo pipefail # -u: Treat unset variables as errors (catches typos in variable names) # -o pipefail: A pipeline fails if ANY command in it fails, not just the last one -DECKSHIFT_VERSION="0.1.7" +DECKSHIFT_VERSION="0.1.8" # Resolve the directory this script lives in so we can find sibling files like # bin/deckshift-settings and applications/deckshift-settings.desktop when