mirror of
https://github.com/theupriser/steamify-cachyos.git
synced 2026-10-03 17:41:58 +02:00
commit the script
This commit is contained in:
commit
16a7739a50
2 files changed
+416
No files matched your search
@@ -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 <this-repo-url>
|
||||||
|
cd <this-repo>
|
||||||
|
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.
|
||||||
Executable
+266
@@ -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
|
||||||
Reference in new issue
Block a user