From c4ec755a4ad8915cbbb767418165adfc942d5a8f Mon Sep 17 00:00:00 2001 From: Rick Peters Date: Mon, 28 Sep 2026 10:06:45 +0200 Subject: [PATCH] feat: --defaults --options (exactly these on) replaces --skip; steamify.sh --boot gamescope|desktop on its own switches where an installed conversion starts --- AGENTS.md | 10 ++++++--- CHANGELOG.md | 3 ++- README.md | 8 +++++++ TECHNICAL.md | 24 +++++++++++++++++++++ lib/menu.sh | 59 ++++++++++++++++++++++++++++++++++++++-------------- steamify.sh | 32 ++++++++++++++++++++++++++-- 6 files changed, 114 insertions(+), 22 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index bc33392..04a8845 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -279,9 +279,13 @@ gamescope and the Plasma desktop. Primary target: the Valve Steam Machine removes it so Plasma builds Vapor's layout at the first login. What needs that layout (single user's launcher) runs then, from a one-time autostart (`lib/first-login.sh`, `--first-login`) that also opens the app. - `--skip ,...` and `--boot gamescope|desktop` (2.7.0, `defaults_options` - in `lib/menu.sh`) change the preselection through `toggle_component`, so the - menu's dependencies hold; the ISO's installer pages pass them. + `--options ,...` (exactly these on, the rest off; an item on brings its + parent) and `--boot gamescope|desktop` (desktop only with `gaming`) (2.7.0, + `defaults_options` in `lib/menu.sh`); the ISO's installer page passes them. + Items this PC can't use are left off with a warning, not an error. + `steamify.sh --boot gamescope|desktop` on its own (2.7.0, for scripts) only + switches `boot` on an installed conversion: `WANTED` is `CURRENT` plus + that, so no updates or removals a normal run would pick. - `Relogin=true` means a gamescope that fails to start is relaunched in a tight loop; keep that in mind when changing session handling. diff --git a/CHANGELOG.md b/CHANGELOG.md index 74e7a7f..ab91c6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,8 @@ one per merged pull request. - `4f6e6fd` **feat: --defaults takes --skip and --boot gamescope|desktop, for the Steam Machine ISO's installer pages** - `5bf9da4` **fix: HDMI-CEC enables cec-audio-control.socket (the TV remote's volume keys); existing installs get it as an update** -- **fix: the app's progress screen says "Boot into desktop", not "Boot into Boot into"** +- `14aa7c0` **fix: the app's progress screen says "Boot into desktop", not "Boot into Boot into"** +- **feat: --defaults --options (exactly these on) replaces --skip; steamify.sh --boot gamescope|desktop on its own switches where an installed conversion starts** ## 2.6.0 - 2026-09-27 diff --git a/README.md b/README.md index 764a3dc..4b80d7e 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,14 @@ steamos-session-select persistent # start where you left off last time steamos-session-select oneshot # always start in gaming mode (default) ``` +Where the PC starts after a restart can also be set from a script, once the +SteamOS conversion is on (only that changes; `sudo` may ask for your password): + +```bash +steamify.sh --boot desktop # start in the desktop from the next boot on +steamify.sh --boot gamescope # start in gaming mode again (default) +``` + ## Something wrong? Stuck on a black screen in gaming mode: press **Ctrl+Alt+F3**, log in, and run diff --git a/TECHNICAL.md b/TECHNICAL.md index a14c6c1..4229f64 100644 --- a/TECHNICAL.md +++ b/TECHNICAL.md @@ -420,6 +420,30 @@ steamos-session-select persistent # remember the last-used session across reboo steamos-session-select oneshot # always start in gamescope (default, like a Deck) ``` +`steamify.sh --boot gamescope|desktop` sets where the PC starts after a +restart (the menu's Boot into row) from a script: it needs the SteamOS +conversion and changes nothing else, not even the updates a normal run would +apply. Exit code 1 without the conversion or with another value. + +## Install-time mode (`--defaults`) + +For an installer (the Steam Machine ISO), without a session or prompts +(passwordless sudo required): + +```bash +steamify.sh --defaults # what the menu would preselect +steamify.sh --defaults --options gaming,theme,cec,machine --boot desktop +``` + +`--options` turns on exactly the listed items (the menu's ids: `gaming`, +`theme`, `glyphs`, `single`, `launcher`, `notify`, `vram`, `cec`, `machine`, +`poweroff`), everything else off; an item that's on brings its parent +(single user the conversion, the power-off fix Steam Machine support). An +item this PC can't use (e.g. `vram` without a VRAM region) is left off with +a warning. `--boot desktop` needs `gaming`. Unknown options, ids, `boot` or +`bios` in the list: exit code 1 before anything changes. What needs a +Plasma session waits for the first login (`lib/first-login.sh`). + With `Relogin=true`, a gamescope session that fails to start is restarted immediately, which can turn into a loop - see [TROUBLESHOOTING.md](TROUBLESHOOTING.md) for the way out. diff --git a/lib/menu.sh b/lib/menu.sh index fac73ba..8372868 100644 --- a/lib/menu.sh +++ b/lib/menu.sh @@ -180,32 +180,59 @@ detect_components() { } defaults_options() { - # defaults_options [--skip [,...]] [--boot gamescope|desktop]: - # changes --defaults' preselection like unticking items in the menu - # (the Steam Machine ISO's installer pages pass them). Returns 1 on an - # unknown option or id. - local c ids + # defaults_options [--options [,...]] [--boot gamescope|desktop]: + # what --defaults sets up, from the Steam Machine ISO's installer page. + # --options: exactly these items on, every other off (without it, the + # menu's preselection). An item that's on brings its parent (single user + # the conversion, like ticking it in the menu); one this PC can't use is + # left off with a warning. --boot desktop needs the conversion. Returns 1 + # on an unknown option, item or value. + local c ids list=false boot="" while [[ $# -gt 0 ]]; do + # Both take a value: without one, shift 2 fails and never shifts, so + # the loop would spin forever. + [[ "$1" == --options || "$1" == --boot ]] && [[ $# -lt 2 ]] && { err "$1 needs a value"; return 1; } case "$1" in - --skip) - IFS=, read -ra ids <<< "${2:-}" - for c in "${ids[@]}"; do - [[ -n "${LABEL[$c]:-}" ]] || { err "Unknown item: $c"; return 1; } - # Unticking through the menu's rules: e.g. skipping the - # conversion also skips single user mode. - [[ "${WANTED[$c]:-0}" == 1 ]] && toggle_component "$c" - done + --options) + list=true + IFS=, read -ra ids <<< "$2" shift 2 ;; --boot) - case "${2:-}" in - gamescope) [[ "${WANTED[boot]:-0}" == 1 ]] && toggle_component boot ;; - desktop) [[ "${WANTED[boot]:-0}" == 0 && "${WANTED[gaming]:-0}" == 1 ]] && toggle_component boot ;; + case "$2" in + gamescope|desktop) boot="$2" ;; *) err "--boot takes gamescope or desktop"; return 1 ;; esac shift 2 ;; *) err "Unknown option: $1"; return 1 ;; esac done + if [[ "$list" == true ]]; then + for c in "${ids[@]}"; do + [[ -n "$c" ]] || continue + [[ -n "${LABEL[$c]:-}" ]] || { err "Unknown item: $c"; return 1; } + [[ "$c" == boot ]] && { err "Where to start is --boot, not an item."; return 1; } + is_action "$c" && { err "$c can't be part of the install."; return 1; } + done + for c in "${COMPONENTS[@]}"; do WANTED[$c]=0; done + for c in "${ids[@]}"; do + [[ -n "$c" ]] || continue + if component_available "$c" && component_selectable "$c"; then + WANTED[$c]=1 + else + warn "Leaving out ${LABEL[$c]%%:*}: not available on this PC." + fi + done + [[ "${WANTED[single]}" == 1 ]] && WANTED[gaming]=1 + for c in "${COMPONENTS[@]}"; do + [[ "${WANTED[$c]}" == 1 && -n "${PARENT[$c]:-}" ]] && WANTED[${PARENT[$c]}]=1 + done + fi + case "$boot" in + desktop) + [[ "${WANTED[gaming]}" == 1 ]] || { err "--boot desktop needs the SteamOS conversion (gaming)."; return 1; } + WANTED[boot]=1 ;; + gamescope) WANTED[boot]=0 ;; + esac return 0 } diff --git a/steamify.sh b/steamify.sh index 5a7828f..df5129f 100755 --- a/steamify.sh +++ b/steamify.sh @@ -28,11 +28,15 @@ require_root_helper BACKEND=false [[ "${1:-}" == --backend ]] && BACKEND=true -# --defaults [--skip ,...] [--boot gamescope|desktop]: apply what the -# menu would preselect (minus the skipped items), without the menu or any +# --defaults [--options ,...] [--boot gamescope|desktop]: apply what the +# menu would preselect (or exactly the listed items), without the menu or any # prompt (the Steam Machine ISO's first login runs this; sudo must not ask). DEFAULTS=false [[ "${1:-}" == --defaults ]] && DEFAULTS=true +# --boot gamescope|desktop: only change where an installed conversion +# starts, everything else stays as it is (for scripts; no menu). +BOOT_ONLY=false +[[ "${1:-}" == --boot ]] && BOOT_ONLY=true if [[ "$BACKEND" == false ]]; then echo -e "${c_bold}Steamify CachyOS${c_reset} v$VERSION" @@ -139,6 +143,30 @@ if [[ "$DEFAULTS" == true ]]; then exit 0 fi +if [[ "$BOOT_ONLY" == true ]]; then + RESTART_FOR_LOGIN=false + REAPPLY=false + case "${2:-}" in + gamescope|desktop) ;; + *) err "--boot takes gamescope or desktop"; exit 1 ;; + esac + detect_components + [[ "${CURRENT[gaming]}" == 1 ]] || { err "--boot needs the SteamOS conversion; turn it on first."; exit 1; } + # What is on stays on, and nothing else changes: not the updates or + # removals a normal run would pick. + for c in "${COMPONENTS[@]}"; do WANTED[$c]=${CURRENT[$c]:-0}; done + WANTED[boot]=0; [[ "$2" == desktop ]] && WANTED[boot]=1 + plan_changes + if [[ ${#TO_DISABLE[@]} -eq 0 && ${#TO_ENABLE[@]} -eq 0 ]]; then + ok "Already starting in $2." + exit 0 + fi + apply_changes + [[ ${#FAILED[@]} -eq 0 ]] || { warn "These had problems (see above): ${FAILED[*]}"; exit 1; } + ok "Starts in $2 from the next boot on." + exit 0 +fi + # Menu loop: after each run the menu comes back with the new state, until # the user quits; the restart question comes then, once, for everything. RESTART_FOR_LOGIN=false