From 16a7739a503598cabfcba2349f22fd37475240b1 Mon Sep 17 00:00:00 2001 From: TheUpriser Date: Sun, 6 Sep 2026 20:17:46 +0200 Subject: [PATCH] commit the script --- README.md | 150 ++++++++++++++++++++++ setup-gamescope-boot.sh | 266 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 416 insertions(+) create mode 100644 README.md create mode 100755 setup-gamescope-boot.sh diff --git a/README.md b/README.md new file mode 100644 index 0000000..387029c --- /dev/null +++ b/README.md @@ -0,0 +1,150 @@ +# CachyOS Gamescope Boot Wizard + +A setup script that makes a CachyOS desktop install (running KDE Plasma + +`plasma-login-manager`) always boot into a **Steam Deck-style gamescope +session** — the same "always boots into Big Picture, switch to desktop and +back on demand" experience SteamOS gives you on a real Deck or the Valve +Steam Machine. + +It exists because, as of the CachyOS March 2026 release (which switched the +default login manager from SDDM to `plasma-login-manager`), the stock +`gamescope-session-cachyos` tooling has a few gaps that stop this from +working out of the box. This script patches around them. + +## What's actually broken (and what this fixes) + +CachyOS's `gamescope-session-cachyos` package ships `steamos-session-select`, +which is meant to work exactly like it does on real SteamOS. On a +`plasma-login-manager` system, three things get in the way: + +1. **No `User=` written to the autologin config.** + `steam-set-session` (the script `steamos-session-select` calls under the + hood) only ever writes a `Session=` key to the autologin config file. On + SDDM this is fine, because SDDM's `User=` is set once by the installer and + never touched again. `plasma-login-manager` needs *both* `Session=` and + `User=` present to autologin at all — without `User=`, it just falls back + to showing the greeter every boot. + +2. **Missing `/etc/plasmalogin.conf.d` directory.** + If that directory doesn't exist, `steam-set-session` fails outright when + it tries to write to it. In practice this shows up as Steam's **"Switch to + Desktop"** hanging forever on a "Switching to Desktop" message with no way + back except a hard reset. + +3. **The base `/etc/plasmalogin.conf` wins over conf.d, and CachyOS ships it + hardcoded to `Session=plasma`.** + Every CachyOS tool that changes sessions (`steamos-session-select`, Steam's + power menu, and the `cachyos-gamescope-autologin.service` that's supposed + to reset you back to gamescope after a desktop session) only ever writes + to `/etc/plasmalogin.conf.d/zz-steamos-autologin.conf`. But the *base* + `/etc/plasmalogin.conf` file takes priority over that fragment, and it + ships with `Session=plasma` baked in — so none of those session switches + ever actually stick, no matter what the fragment says. + +This script fixes all three: it ensures the conf.d directory exists, sets the +base config's `Session=`, `User=`, and `Relogin=true` correctly, and installs +a small `systemd` path-watcher that keeps the base config in sync with +whatever CachyOS's own tools write to the conf.d fragment — so switching +sessions from inside Steam or the desktop actually works, in both +directions, and resets to gamescope on the next boot by default (matching +real Deck/SteamOS behavior). + +## Requirements + +- CachyOS (or an Arch-based system) with `pacman` +- KDE Plasma installed +- `plasma-login-manager` as the active display manager + *(the script will warn and ask for confirmation if it detects SDDM or + something else instead — most of these workarounds are specific to + `plasma-login-manager`)* +- A regular user account with `sudo` access + +## Usage + +```bash +git clone +cd +chmod +x setup-gamescope-boot.sh +./setup-gamescope-boot.sh +``` + +Run it as your normal user, **not** as root — it calls `sudo` internally for +the specific commands that need it. + +The script will: + +1. Ask which user account should autologin into gamescope (defaults to + whoever's running the script). +2. Check for and offer to install `gamescope-session-cachyos`, `steam`, and + `mangohud` if any are missing. +3. Create `/etc/plasmalogin.conf.d` if it doesn't exist. +4. Back up and rewrite `/etc/plasmalogin.conf`'s `[Autologin]` section. +5. Remove any stray manual override files from earlier troubleshooting + attempts (only files matching `zzz-steamos-autologin*.conf` — it never + touches `zz-steamos-autologin.conf`, which CachyOS's own tools own). +6. Install a sync script (`/usr/local/bin/sync-steamos-session.sh`) and a + `systemd` path unit that keeps the base config aligned with session + switches made through Steam or `steamos-session-select`. +7. Ask whether to reboot immediately to test it. + +It's **safe to re-run** — every step checks current state first, and any +file it modifies gets backed up once with a `.bak-gamescope-wizard` suffix +before the first change. + +## After running it + +Boot straight into gamescope: it should happen automatically. From inside +gamescope, Steam's **Power → Switch to Desktop** should now work. From the +desktop, logging out should drop you back into gamescope automatically +(thanks to CachyOS's own `cachyos-gamescope-autologin.service`, which this +script doesn't replace — it just makes sure the setting it writes actually +takes effect). + +You can also switch sessions manually at any time: + +```bash +steamos-session-select gamescope # switch to gamescope right now +steamos-session-select plasma # switch to desktop right now +steamos-session-select persistent # remember whichever session you used last, across reboots +steamos-session-select oneshot # always start in gamescope regardless of what you used last (the default Deck-like behavior) +``` + +## Restoring the originals + +Every file the script modifies is backed up next to itself: + +```bash +sudo cp /etc/plasmalogin.conf.bak-gamescope-wizard /etc/plasmalogin.conf +``` + +To fully remove the sync watcher this script adds: + +```bash +sudo systemctl disable --now sync-steamos-session.path +sudo rm /etc/systemd/system/sync-steamos-session.path +sudo rm /etc/systemd/system/sync-steamos-session.service +sudo rm /usr/local/bin/sync-steamos-session.sh +sudo systemctl daemon-reload +``` + +## Caveats + +- This works around current CachyOS/`plasma-login-manager` behavior as of + September 2026. If CachyOS fixes `steam-set-session` upstream to write + `User=` and to target whichever base config the login manager actually + reads, this script becomes unnecessary — check for updates before running + it on a freshly reinstalled system. +- Tested on a Valve Steam Machine (desktop AMD APU + discrete GPU) running + CachyOS Desktop edition. Should apply to any CachyOS desktop install using + `plasma-login-manager`, but hasn't been tested on Steam Deck/Legion Go + hardware, which typically ship with SDDM instead. +- If you find CachyOS has patched the underlying issue, please open an issue + or PR here so the script can detect that and skip the workaround. + +## Related upstream reports + +- [CachyOS/gamescope-session#9](https://github.com/CachyOS/gamescope-session/issues/9) — "Switch to Desktop" hang due to missing `/etc/plasmalogin.conf.d` + +## License + +MIT — do whatever you want with it. diff --git a/setup-gamescope-boot.sh b/setup-gamescope-boot.sh new file mode 100755 index 0000000..58fb1de --- /dev/null +++ b/setup-gamescope-boot.sh @@ -0,0 +1,266 @@ +#!/bin/bash +# +# setup-gamescope-boot.sh +# +# Wizard to configure a CachyOS (KDE Plasma + plasma-login-manager) install +# to always boot into a Steam Deck-style gamescope session, with the +# ability to switch to Plasma desktop and back, Deck-style, and have it +# reset to gamescope on the next boot/logout. +# +# Covers three real bugs found on CachyOS as of Sep 2026: +# 1. steam-set-session never writes User= to plasmalogin's autologin +# config, so plasma-login-manager never actually autologs in. +# 2. steam-set-session fails outright if /etc/plasmalogin.conf.d is +# missing, breaking "Switch to Desktop" from inside gamescope. +# 3. /etc/plasmalogin.conf (the base config) hardcodes Session=plasma +# and takes priority over anything written to +# /etc/plasmalogin.conf.d/*.conf, so session switches never stick +# without a bridge that copies the conf.d value back into the base +# file, plus Relogin=true so ending a session re-triggers autologin +# instead of dropping to the greeter. +# +# Safe to re-run: it is idempotent and backs up files before editing. + +set -uo pipefail + +# ---------- helpers ---------- + +c_reset="\033[0m"; c_bold="\033[1m"; c_green="\033[32m"; c_yellow="\033[33m"; c_red="\033[31m"; c_cyan="\033[36m" + +info() { echo -e "${c_cyan}==>${c_reset} $*"; } +ok() { echo -e "${c_green}✔${c_reset} $*"; } +warn() { echo -e "${c_yellow}!${c_reset} $*"; } +err() { echo -e "${c_red}✘ $*${c_reset}" >&2; } +ask_yn() { + local prompt="$1" default="${2:-y}" reply + local hint="[Y/n]"; [[ "$default" == "n" ]] && hint="[y/N]" + read -rp "$(echo -e "${c_bold}${prompt}${c_reset} ${hint} ")" reply + reply="${reply:-$default}" + [[ "$reply" =~ ^[Yy]$ ]] +} + +require_root_helper() { + # Re-exec any privileged step through sudo rather than requiring the + # whole script to run as root, so $HOME/whoami stay correct for the + # target user detection below. + if [[ $EUID -eq 0 && -z "${SUDO_USER:-}" ]]; then + err "Please run this script as your normal user (it will call sudo itself), not directly as root." + exit 1 + fi +} + +backup_file() { + local f="$1" + if [[ -f "$f" && ! -f "${f}.bak-gamescope-wizard" ]]; then + sudo cp -a "$f" "${f}.bak-gamescope-wizard" + info "Backed up $f -> ${f}.bak-gamescope-wizard" + fi +} + +# ---------- start ---------- + +require_root_helper + +echo -e "${c_bold}CachyOS Steam Deck-style Gamescope Boot Wizard${c_reset}" +echo "This sets your machine up to always boot into gamescope (like SteamOS)," +echo "with working Switch-to-Desktop and switch-back, surviving reboots." +echo + +if ! command -v pacman >/dev/null 2>&1; then + err "This doesn't look like an Arch/CachyOS system (no pacman found). Aborting." + exit 1 +fi + +TARGET_USER="${SUDO_USER:-$USER}" +read -rp "$(echo -e "${c_bold}Which user should autologin into gamescope?${c_reset} [${TARGET_USER}] ")" input_user +TARGET_USER="${input_user:-$TARGET_USER}" + +if ! id "$TARGET_USER" >/dev/null 2>&1; then + err "User '$TARGET_USER' does not exist on this system." + exit 1 +fi +ok "Using user: $TARGET_USER" +echo + +# ---------- 1. Login manager check ---------- + +DM="$(systemctl show -p Id --value display-manager 2>/dev/null | sed 's/\.service$//')" +info "Detected display manager: ${DM:-none}" + +if [[ "$DM" != "plasmalogin" ]]; then + warn "This wizard was built and tested against plasma-login-manager (plasmalogin)." + warn "Detected display manager is '${DM:-unknown}'. SDDM setups don't need" + warn "most of these workarounds (SDDM's own Autologin works out of the box);" + warn "this script will still try, but review the output carefully." + ask_yn "Continue anyway?" n || exit 0 +fi +echo + +# ---------- 2. Install packages ---------- + +info "Checking required packages: gamescope-session-cachyos, steam, mangohud" +MISSING=() +for pkg in gamescope-session-cachyos steam mangohud; do + pacman -Qi "$pkg" >/dev/null 2>&1 || MISSING+=("$pkg") +done + +if [[ ${#MISSING[@]} -gt 0 ]]; then + info "Missing packages: ${MISSING[*]}" + if ask_yn "Install them now?"; then + sudo pacman -S --needed "${MISSING[@]}" + else + err "Cannot continue without these packages." + exit 1 + fi +else + ok "All required packages already installed." +fi +echo + +# ---------- 3. Ensure plasmalogin.conf.d exists (fixes Switch-to-Desktop crash) ---------- + +info "Ensuring /etc/plasmalogin.conf.d exists (fixes the 'Switching to Desktop' hang bug)" +sudo mkdir -p /etc/plasmalogin.conf.d +ok "Directory present." +echo + +# ---------- 4. Fix the base /etc/plasmalogin.conf ---------- +# +# steam-set-session only ever writes to /etc/plasmalogin.conf.d/*.conf, +# but the base /etc/plasmalogin.conf takes priority and, as shipped by +# CachyOS, hardcodes Session=plasma with no User= and no Relogin=. We +# rewrite the [Autologin] block cleanly here. + +BASE_CONF="/etc/plasmalogin.conf" +info "Configuring $BASE_CONF (Session=gamescope-session.desktop, User=$TARGET_USER, Relogin=true)" +backup_file "$BASE_CONF" + +sudo touch "$BASE_CONF" + +# Strip any existing [Autologin] section (from the first [Autologin] line +# to the next section header or EOF), then append a clean one. This is +# safer than a series of seds for an unknown starting state. +sudo awk ' + BEGIN { in_autologin=0 } + /^\[Autologin\]/ { in_autologin=1; next } + /^\[/ { in_autologin=0 } + !in_autologin { print } +' "$BASE_CONF" | sudo tee "${BASE_CONF}.tmp" > /dev/null + +sudo mv "${BASE_CONF}.tmp" "$BASE_CONF" + +sudo tee -a "$BASE_CONF" > /dev/null << EOF +[Autologin] +Session=gamescope-session.desktop +User=$TARGET_USER +Relogin=true +EOF + +ok "Base autologin config written:" +sudo sed -n '/\[Autologin\]/,/^\[/p' "$BASE_CONF" | head -n -1 2>/dev/null || sudo cat "$BASE_CONF" +echo + +# ---------- 5. Clean up any stray conf.d autologin fragments from manual attempts ---------- + +info "Removing any leftover manual conf.d autologin overrides (base config now handles it)" +sudo rm -f /etc/plasmalogin.conf.d/zzz-steamos-autologin*.conf +ok "Cleaned." +echo + +# ---------- 6. Install the sync bridge: conf.d -> base config ---------- +# +# CachyOS's own tools (steamos-session-select, Steam's "Switch to +# Desktop", and cachyos-gamescope-autologin.service) only ever write the +# session choice to /etc/plasmalogin.conf.d/zz-steamos-autologin.conf. +# Since the base config wins, we need a watcher that copies that value +# into the base file whenever it changes. + +SYNC_SCRIPT="/usr/local/bin/sync-steamos-session.sh" +info "Installing session sync bridge at $SYNC_SCRIPT" + +sudo tee "$SYNC_SCRIPT" > /dev/null << 'EOF' +#!/bin/bash +# Copies the Session= value CachyOS's steamos tools write into +# /etc/plasmalogin.conf.d/zz-steamos-autologin.conf back into the base +# /etc/plasmalogin.conf, which plasma-login-manager actually obeys. +SRC="/etc/plasmalogin.conf.d/zz-steamos-autologin.conf" +DEST="/etc/plasmalogin.conf" + +[[ -f "$SRC" ]] || exit 0 +SESSION=$(grep -oP '^Session=\K.*' "$SRC") +[[ -z "$SESSION" ]] && exit 0 + +if grep -q '^Session=' "$DEST"; then + sed -i "s|^Session=.*|Session=$SESSION|" "$DEST" +else + echo "Session=$SESSION" >> "$DEST" +fi +EOF + +sudo chmod +x "$SYNC_SCRIPT" +ok "Sync script installed." +echo + +# ---------- 7. systemd path watcher + service ---------- + +info "Installing systemd path watcher so session switches take effect immediately" + +sudo tee /etc/systemd/system/sync-steamos-session.path > /dev/null << 'EOF' +[Unit] +Description=Watch for steamos session changes + +[Path] +PathModified=/etc/plasmalogin.conf.d/zz-steamos-autologin.conf + +[Install] +WantedBy=multi-user.target +EOF + +sudo tee /etc/systemd/system/sync-steamos-session.service > /dev/null << 'EOF' +[Unit] +Description=Sync steamos session selection into plasmalogin.conf + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/sync-steamos-session.sh +EOF + +sudo systemctl daemon-reload +sudo systemctl enable --now sync-steamos-session.path +ok "Path watcher enabled." +echo + +# ---------- 8. Run it once now so current state is in sync ---------- + +info "Running the sync once now to align current state" +sudo systemctl start sync-steamos-session.service +ok "Done. Current base config:" +sudo cat "$BASE_CONF" +echo + +# ---------- 9. Summary + reboot ---------- + +echo -e "${c_bold}Setup complete.${c_reset}" +echo "What this did:" +echo " - Installed gamescope-session-cachyos, steam, mangohud (if missing)" +echo " - Created /etc/plasmalogin.conf.d (fixes Switch-to-Desktop crash)" +echo " - Set $BASE_CONF to autologin '$TARGET_USER' into gamescope, with Relogin=true" +echo " - Installed a sync bridge + systemd watcher so Steam's Switch-to-Desktop" +echo " (and cachyos-gamescope-autologin.service resetting back to gamescope" +echo " on logout) both actually take effect" +echo +echo "Backups of any files this script modified were saved with a" +echo ".bak-gamescope-wizard suffix next to the original." +echo +echo "To manually flip sessions any time:" +echo " steamos-session-select gamescope # boot straight into gamescope now" +echo " steamos-session-select plasma # boot straight into desktop now" +echo " steamos-session-select persistent # remember last-used session across reboots" +echo " steamos-session-select oneshot # always start in gamescope regardless (default Deck behavior)" +echo + +if ask_yn "Reboot now to test it?" n; then + sudo reboot +else + info "Skipping reboot. Run 'sudo reboot' whenever you're ready to test." +fi