From 0f503dd112d7d51860f118179b579d5a9143fe6f Mon Sep 17 00:00:00 2001 From: Rick Peters Date: Thu, 24 Sep 2026 13:24:52 +0200 Subject: [PATCH] feat: Boot into gamescope or the desktop - Menu row "Boot into: [gamescope] / desktop" under the conversion; gamescope is the default. - Desktop: steamify-boot-desktop.service sets the autologin session to Plasma at every boot, before the login manager; switching back and forth keeps working. - VERSION 0.10.0. --- AGENTS.md | 8 ++++++ CHANGELOG.md | 16 ++++++++++-- README.md | 23 +++++++++++------ lib/boot-session.sh | 62 +++++++++++++++++++++++++++++++++++++++++++++ lib/menu.sh | 28 +++++++++++++++++--- steamify.sh | 6 ++--- 6 files changed, 126 insertions(+), 17 deletions(-) create mode 100644 lib/boot-session.sh diff --git a/AGENTS.md b/AGENTS.md index 16fa88a..2f41ba5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -132,6 +132,14 @@ gamescope and the Plasma desktop. Primary target: the Valve Steam Machine and `ensure-kernel-headers.service` installs missing ones at boot (a pacman hook can't run pacman), which triggers DKMS's install hook. The module creates `/sys/class/leds/valve-leds*`. +- `boot` ("Boot into: [gamescope] / desktop") is a choice row, not a + checkbox: on = desktop. It needs `gaming` (ticking it ticks gaming, + unticking gaming unticks it) and is never preselected (`NO_PRESELECT`), so + the conversion boots into gamescope by default. Desktop is + `steamify-boot-desktop.service`, ordered `Before=` the login managers: + `steam-set-session plasma.desktop` plus the plasmalogin sync bridge when it + exists, at every boot. CachyOS's `cachyos-gamescope-autologin` still sets + gamescope during each desktop session; the unit corrects it at boot. - `bios` is an *action* (`ACTIONS` in `lib/menu.sh`), not an on/off component: never preselected (not even on a first run), never re-applied by `a`, not listed in the state overview, and `bios_status` is always off. diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ca9f6d..d5c5652 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,14 +5,26 @@ All notable changes, per version and per commit. Versions follow `steamify.sh`. Versions before 0.7.0 were numbered afterwards, one per merged pull request. -## 0.9.1 - 2026-09-24 +## 0.10.0 - 2026-09-24 + +- **feat: Boot into gamescope or the desktop** + - New menu row under the conversion, "Boot into: [gamescope] / desktop"; + gamescope stays the default and is never changed on a first run. + - Desktop: `steamify-boot-desktop.service` sets the autologin session to + Plasma at every boot, before the login manager starts; Return to Gaming + Mode and Steam's Switch to Desktop keep working. Back to gamescope removes + it. Choosing desktop turns the conversion on; turning the conversion off + resets it to gamescope. + - The later menu items move down one (BIOS is now 8 on a Steam Machine). + +## 0.9.1 - 2026-09-24 (#10) - `2e107e5` **fix: LED driver for every kernel on a fresh install** - The DKMS override was written to `/etc/dkms` before `dkms` was installed, when that folder doesn't exist yet, so it silently failed and the build for other kernels (e.g. LTS) failed as in 0.6. The folder is created first now, and a failed write stops with an error. -- **feat: Restart question on quit is "Restart now? [Y/n]"** +- `5ab83d6` **feat: Restart question on quit is "Restart now? [Y/n]"** - When something needs a restart, `q` asks with yes as the default; `n` goes back to the menu and the next `q` asks again. Ctrl+C quits without restarting; scripted input that runs out never restarts. diff --git a/README.md b/README.md index 9498e31..abdac14 100644 --- a/README.md +++ b/README.md @@ -14,19 +14,22 @@ Everything you turn off is put back the way it was. Desktop** in Steam works and so does going back (the **Return to Gaming Mode** icon on the desktop), you're back in gaming mode after a restart, and Steam's on-screen keyboard (Steam + X) also works on the desktop. -2. **SteamOS theme** - the Vapor look for the desktop (CachyOS's +2. **Boot into: [gamescope] / desktop** - where the PC starts. Gamescope + (gaming mode) is the default; choose desktop to start in KDE Plasma + instead, with Return to Gaming Mode one double-click away. (Needs 1.) +3. **SteamOS theme** - the Vapor look for the desktop (CachyOS's `cachyos-vapor` package). -3. **Steam Deck/Machine icons** - Steam Deck button icons in gaming mode. -4. **Single user mode** - like SteamOS: never a login or lock screen, no +4. **Steam Deck/Machine icons** - Steam Deck button icons in gaming mode. +5. **Single user mode** - like SteamOS: never a login or lock screen, no user switching or logging out. Typing a password with a controller is no fun. (Needs 1.) -5. **Steamify shortcut** - a "Steamify CachyOS" icon on the desktop and in +6. **Steamify shortcut** - a "Steamify CachyOS" icon on the desktop and in the app launcher (the Steam logo with a gear) that opens the newest version of Steamify in Konsole, so you don't need the install command again. -6. **Steam Machine support** - only shown on a Valve Steam Machine: the +7. **Steam Machine support** - only shown on a Valve Steam Machine: the driver for the front LED bar, and the hardware settings in Steam (fan, TV control over HDMI-CEC). -7. **Update BIOS** - only on a Steam Machine, opt-in and at your own risk: +8. **Update BIOS** - only on a Steam Machine, opt-in and at your own risk: installs the newest Steam Machine BIOS from Valve (see [BIOS updates](#bios-updates-steam-machine)). @@ -97,9 +100,12 @@ files in `lib/` next to it. **Power > Switch to Desktop**. - **Back to gaming mode:** double-click **Return to Gaming Mode** on the desktop (or log out, if you're not using single user mode). -- After a restart you always start in gaming mode. +- After a restart you start in gaming mode, or on the desktop if you chose + **Boot into: desktop** in the menu. Switching back and forth works the same + either way. -Prefer to decide yourself where your PC starts? Run one of these in Konsole: +Prefer to start where you left off last time? Run one of these in Konsole +(with **Boot into: gamescope**): ```bash steamos-session-select persistent # start where you left off last time @@ -356,6 +362,7 @@ gamescope-session, ...) stay installed. | `lib/state.sh` | Undo journal for KDE settings (`kset`/`krevert`) | | `lib/common.sh` | Output helpers, prompts, backups, plasmashell handling | | `lib/packages.sh` | Required packages, AUR helper (yay/paru) | +| `lib/boot-session.sh` | Boot into gamescope or the desktop (`steamify-boot-desktop.service`) | | `lib/login-manager.sh` | SteamOS conversion: SDDM or plasmalogin autologin, sync bridge | | `lib/steam-desktop.sh` | Steam in the Plasma session; Steam Deck/Machine icons | | `lib/desktop-shortcut.sh` | Return to Gaming Mode shortcut and its sudoers rule | diff --git a/lib/boot-session.sh b/lib/boot-session.sh new file mode 100644 index 0000000..5e5d565 --- /dev/null +++ b/lib/boot-session.sh @@ -0,0 +1,62 @@ +#!/bin/bash +# "Boot into: gamescope / desktop" menu item, on top of the SteamOS +# conversion. Gamescope is the default (the conversion's autologin, and +# CachyOS's cachyos-gamescope-autologin resetting to it after a desktop +# session). Desktop: a unit that sets the autologin session to Plasma at +# every boot, before the login manager starts. Switching between the two in +# a running system (Return to Gaming Mode, Steam's Switch to Desktop) works +# the same either way. +# Sourced by steamify.sh; not meant to be run on its own. + +BOOT_UNIT_NAME="steamify-boot-desktop.service" +BOOT_UNIT="/etc/systemd/system/$BOOT_UNIT_NAME" +SESSION_SYNC="/usr/local/bin/sync-steamos-session.sh" + +boot_status() { + # On = boots into the desktop. + [[ -f "$BOOT_UNIT" ]] && systemctl is-enabled -q "$BOOT_UNIT_NAME" 2>/dev/null +} + +boot_enable() { + info "Setting the PC to boot into the desktop..." + # The sync bridge (plasma-login-manager only; not there with SDDM) copies + # the session into the base config; run it right away rather than rely + # on its path unit, which could still be pending when the login manager + # starts. + sudo tee "$BOOT_UNIT" > /dev/null << EOF +[Unit] +Description=Steamify CachyOS: boot into the desktop instead of gaming mode +Before=display-manager.service sddm.service plasmalogin.service + +[Service] +Type=oneshot +ExecStart=/usr/lib/steamos/steam-set-session plasma.desktop +ExecStart=/bin/sh -c '[ -x $SESSION_SYNC ] && exec $SESSION_SYNC || true' + +[Install] +WantedBy=graphical.target +EOF + sudo systemctl daemon-reload + sudo systemctl enable "$BOOT_UNIT_NAME" || { err "Enabling $BOOT_UNIT_NAME failed."; return 1; } + ok "Boots into the desktop from the next boot on (Return to Gaming Mode still works)." +} + +boot_disable() { + info "Setting the PC to boot into gaming mode again..." + sudo systemctl disable "$BOOT_UNIT_NAME" 2>/dev/null + sudo rm -f "$BOOT_UNIT" + sudo systemctl daemon-reload + # Next boot into gamescope, as the conversion sets it up. + sudo /usr/lib/steamos/steam-set-session gamescope-session.desktop + [[ -x "$SESSION_SYNC" ]] && sudo "$SESSION_SYNC" + ok "Boots into gaming mode from the next boot on." +} + +boot_choice() { + # The menu row: the chosen option in brackets. + if [[ "$1" == 1 ]]; then + echo "Boot into: gamescope [desktop]" + else + echo "Boot into: [gamescope] desktop" + fi +} diff --git a/lib/menu.sh b/lib/menu.sh index ab45c60..0e22a73 100644 --- a/lib/menu.sh +++ b/lib/menu.sh @@ -5,13 +5,17 @@ # Menu order. Components are turned on in this order and off in reverse; # gaming must come first (single user builds on it). -COMPONENTS=(gaming theme glyphs single launcher machine bios) +COMPONENTS=(gaming boot theme glyphs single launcher machine bios) # One-off actions rather than on/off components: never preselected, never # re-applied, not listed as on or off. ACTIONS=(bios) +# Never preselected on a first run: booting into the desktop is a choice, +# gamescope is the default. +NO_PRESELECT=(boot) declare -A LABEL=( [gaming]="SteamOS conversion: boot into gaming mode, Steam on the desktop" + [boot]="Boot into the desktop instead of gaming mode" [theme]="Install SteamOS theme: Vapor look (cachyos-vapor)" [glyphs]="Install Steam Deck/Machine icons: Deck button icons in gaming mode" [single]="Single user mode: no password, lock screen or log out (SDDM)" @@ -49,7 +53,8 @@ detect_components() { # First run: preselect the full SteamOS experience (never an action). if [[ "$any" == false ]]; then for c in "${COMPONENTS[@]}"; do - component_available "$c" && ! is_action "$c" && WANTED[$c]=1 + component_available "$c" && ! is_action "$c" && + [[ " ${NO_PRESELECT[*]} " != *" $c "* ]] && WANTED[$c]=1 done fi } @@ -60,7 +65,9 @@ toggle_component() { WANTED[$c]=$(( 1 - WANTED[$c] )) # Single user mode only makes sense on top of the SteamOS conversion. if [[ "$c" == single && "${WANTED[single]}" == 1 ]]; then WANTED[gaming]=1; fi - if [[ "$c" == gaming && "${WANTED[gaming]}" == 0 ]]; then WANTED[single]=0; fi + if [[ "$c" == gaming && "${WANTED[gaming]}" == 0 ]]; then WANTED[single]=0; WANTED[boot]=0; fi + # Where to boot to is part of the conversion, too. + if [[ "$c" == boot && "${WANTED[boot]}" == 1 ]]; then WANTED[gaming]=1; fi } show_menu() { @@ -77,7 +84,13 @@ show_menu() { now="$(printf '%-6s' "$now")" [[ "${CURRENT[$c]}" == 1 ]] && now="${now/on/${c_green}on${c_reset}}" want="[ ]"; [[ "${WANTED[$c]}" == 1 ]] && want="[x]" - if component_selectable "$c"; then + if [[ "$c" == boot ]]; then + # A choice rather than a checkbox: Now/Want show the mode. + now="gaming"; [[ "${CURRENT[boot]}" == 1 ]] && now="desk" + [[ "${CURRENT[gaming]}" == 1 ]] || now="-" + want="gaming"; [[ "${WANTED[boot]}" == 1 ]] && want="desk" + printf " %-3s %-6s %-6s %s\n" "$i" "$now" "$want" "$(boot_choice "${WANTED[boot]}")" + elif component_selectable "$c"; then printf " %-3s %b %-6s %s\n" "$i" "$now" "$want" "${LABEL[$c]}" else printf " %b%-3s %-6s %-6s %s (not available)%b\n" "$c_dim" "$i" "$now" "$want" "${LABEL[$c]}" "$c_reset" @@ -115,6 +128,13 @@ draw_menu_tui() { state=" (now: off)"; [[ "${CURRENT[$c]}" == 1 ]] && state=" (now: ${c_green}on${c_reset})" is_action "$c" && state=" (opt-in, runs once)" line="$box ${LABEL[$c]}" + if [[ "$c" == boot ]]; then + # A choice rather than a checkbox; Space switches it. + line="$(boot_choice "${WANTED[boot]}")" + line="${line/\[/[${c_green}}"; line="${line/\]/${c_reset}]}" + state=" (now: gamescope)"; [[ "${CURRENT[boot]}" == 1 ]] && state=" (now: desktop)" + [[ "${CURRENT[gaming]}" == 1 ]] || state=" (with the SteamOS conversion)" + fi if ! component_selectable "$c"; then # Greyed out: nothing to do (e.g. BIOS already up to date). local mark=" "; (( i == cursor )) && mark=" ${c_cyan}>${c_reset} " diff --git a/steamify.sh b/steamify.sh index f305511..3363ea0 100755 --- a/steamify.sh +++ b/steamify.sh @@ -15,11 +15,11 @@ set -uo pipefail # Release version, see CHANGELOG.md. -VERSION=0.9.1 +VERSION=0.10.0 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -for lib in common state packages login-manager single-user steam-desktop steam-machine vapor-theme steamos-extras bios desktop-shortcut wizard-shortcut menu; do +for lib in common state packages login-manager single-user steam-desktop steam-machine boot-session vapor-theme steamos-extras bios desktop-shortcut wizard-shortcut menu; do # shellcheck source=/dev/null source "$SCRIPT_DIR/lib/$lib.sh" done @@ -135,7 +135,7 @@ while true; do apply_changes # Login manager changes only take effect after a restart. - [[ " ${TO_DISABLE[*]} ${TO_ENABLE[*]} " == *" gaming "* || " ${TO_DISABLE[*]} ${TO_ENABLE[*]} " == *" single "* ]] && + [[ " ${TO_DISABLE[*]} ${TO_ENABLE[*]} " =~ \ (gaming|single|boot)\ ]] && RESTART_FOR_LOGIN=true echo