diff --git a/AGENTS.md b/AGENTS.md index b1a3afb..3380030 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -32,6 +32,12 @@ gamescope and the Plasma desktop. Primary target: the Valve Steam Machine the singletons `Theme` (colours, fonts), `Texts` (item texts) and `Input` (controller/keyboard/remote and its button names), listed in `qmldir`. Screens get the `AppState` as `app` and only show it or call its functions. +- **Paths.** Everything in the home folder lives under `steamify`: + `$STATE_DIR` (`~/.local/state/steamify`), `$STEAMIFY_DATA`/`$STEAMIFY_BIN` + (`~/.local/share/steamify/{app,bin}`), `lib/state.sh`. Never add files + under the old name `cachyos-gamescope-boot`; `migrate_layout` moves those + of older versions (symlinks keep older releases working). Keep the + `.bak-gamescope-wizard` backup suffix: existing backups are found by it. - `lib/*.sh` - one file per responsibility, each defining functions only (no top-level side effects besides constants). See the table in `TECHNICAL.md`. diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e51766..5c60a79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,8 @@ one per merged pull request. ## 2.5.0 - 2026-09-27 -- **fix: fill takes values literally; the notifier path is quoted in its unit** +- **feat: Everything in the home folder under steamify (state, scripts, icon), moved once from the old name** +- `2e0881b` **fix: fill takes values literally; the notifier path is quoted in its unit** - `cce31e1` **refactor: DKMS confs in patches/; an existing leds-valve DKMS override is kept and restored** - `bd4fa3a` **refactor: The session sync and kernel headers scripts in patches/** - `8ffa0f2` **refactor: systemd units in services/, read with service_file like patches/** diff --git a/TECHNICAL.md b/TECHNICAL.md index f9114c1..4e2e963 100644 --- a/TECHNICAL.md +++ b/TECHNICAL.md @@ -14,7 +14,7 @@ and turns on what you ticked. To be able to undo: off. - **KDE settings** in your home directory are recorded with their previous value the first time the wizard changes them, in an undo journal under - `~/.local/state/cachyos-gamescope-boot/`. Turning the component off writes + `~/.local/state/steamify/`. Turning the component off writes the old values back (or removes keys that didn't exist before). Setups made by older versions of the script, without a journal, fall back to KDE's defaults. @@ -240,7 +240,7 @@ normal run adds it. The **Update notifications** option (new in 2.5.0, ticked by default) installs `patches/steamify-notifier.py` as -`~/.local/share/cachyos-gamescope-boot/steamify-notifier` with two user +`~/.local/share/steamify/bin/steamify-notifier` with two user units in `~/.config/systemd/user`: `steamify-update-check.timer` (daily, `Persistent=`) and `steamify-update-check.service` (also wanted by `plasma-workspace.target`, so it checks a minute after each desktop login). @@ -290,7 +290,7 @@ worth it if the booster itself turns out to cause stutter. Each component has a feature version (`FEATURE_VERSION` in `lib/menu.sh`): the Steamify version in which what it sets up last changed (2.1.0 for everything that hasn't changed since). After a component is turned on -successfully, that version is recorded in `~/.local/state/cachyos-gamescope-boot/features.state` +successfully, that version is recorded in `~/.local/state/steamify/features.state` (turning it off records `off`). Whether a component is on is always checked on the system itself; the version only decides about updates: @@ -344,6 +344,31 @@ To walk through it without flashing anything, run the wizard with `WIZARD_BIOS_DRY_RUN=1`: it downloads and checks the package and shows both warnings, skips fwupd's device check, and only prints the install command. +## Where Steamify keeps its files + +In the home folder, everything is under `steamify`: + +| Where | What | +|---|---| +| `~/.local/state/steamify/` | State (`*.state`), undo journals (`*.journal`), the saved panel layout (`theme-layout/`) | +| `~/.local/share/steamify/app/` | The app (`steamify-app.sh` downloads it here) | +| `~/.local/share/steamify/bin/` | The shortcut's start scripts (`run-app`, `run-wizard`) and `steamify-notifier` | +| `~/.local/share/icons/hicolor/scalable/apps/steamify.svg` | The shortcut's icon | +| `~/.local/share/applications/steamify-*.desktop` | The launcher entries | +| `~/.config/systemd/user/` | `steamify-update-check.*`, `steam-desktop-autostart.service` | + +System-wide: `/usr/local/lib/steamify/` (kernel headers script), +`/usr/src/steamify-*` (DKMS modules), `/var/cache/steamify/kernel` (the old +kernel pin's packages), and `*.bak-gamescope-wizard` backups next to the +system files that were edited (that name stays: it's how they're found again). + +Before 2.5.0 the home folder paths used the project's old name +(`cachyos-gamescope-boot`). `migrate_layout` (`lib/state.sh`) moves them at +every start of a newer version, once, and leaves symlinks under the old names +so an older release still finds the same state; it fixes the paths in the +launcher entries and the update check's unit, and merges when both exist. +The headers script moves when Steam Machine support is set up again. + ## Manual session control ```bash diff --git a/lib/state.sh b/lib/state.sh index 1e87097..8bef63c 100644 --- a/lib/state.sh +++ b/lib/state.sh @@ -5,7 +5,11 @@ # deletes the key if it didn't exist before). # Sourced by steamify.sh; not meant to be run on its own. -STATE_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/cachyos-gamescope-boot" +STATE_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/steamify" +# Steamify's own files in the home folder: the app (app/, from +# steamify-app.sh) and the shortcut's and notifier's scripts (bin/). +STEAMIFY_DATA="${XDG_DATA_HOME:-$HOME/.local/share}/steamify" +STEAMIFY_BIN="$STEAMIFY_DATA/bin" UNSET=$'\x01' kset() { @@ -77,3 +81,57 @@ state_clear() { current_display_manager() { systemctl show -p Id --value display-manager 2>/dev/null | sed 's/\.service$//' } + +migrate_dir() { + # migrate_dir : moves to and leaves a symlink. + # When both exist (an older release ran after a newer one), what + # lacks is moved over; a file in both keeps 's copy and stays + # as it is. Returns 0 when something moved. + local old="$1" new="$2" f moved=1 + [[ -d "$old" && ! -L "$old" ]] || return 1 + if [[ ! -e "$new" ]]; then + mkdir -p "$(dirname "$new")" + mv "$old" "$new" && ln -s "$new" "$old" + return 0 + fi + for f in "$old"/* "$old"/.[!.]*; do + [[ -e "$f" || -L "$f" ]] || continue + [[ -e "$new/${f##*/}" ]] && continue + mv "$f" "$new/" && moved=0 + done + rmdir "$old" 2>/dev/null && ln -s "$new" "$old" + return "$moved" +} + +migrate_layout() { + # Before 2.5.0 the state and scripts were under the project's old name + # (cachyos-gamescope-boot). Moved once; the old names stay as symlinks, + # so an older release that still runs finds the same state. + local old_state="${XDG_STATE_HOME:-$HOME/.local/state}/cachyos-gamescope-boot" + local old_bin="${XDG_DATA_HOME:-$HOME/.local/share}/cachyos-gamescope-boot" + local old_icon="${XDG_DATA_HOME:-$HOME/.local/share}/icons/hicolor/scalable/apps/cachyos-gamescope-boot-wizard.svg" + local f + # Links left pointing at nothing once their component was turned off. + for f in "$old_state" "$old_bin"; do [[ -L "$f" && ! -e "$f" ]] && rm -f "$f"; done + migrate_dir "$old_state" "$STATE_DIR" + if migrate_dir "$old_bin" "$STEAMIFY_BIN"; then + # The notifier had the old paths built in; its unit and the + # shortcut's entries point at the scripts. + [[ -f "$STEAMIFY_BIN/steamify-notifier" ]] && + patch_file steamify-notifier.py | install_executable "$STEAMIFY_BIN/steamify-notifier" 755 + for f in "$NOTIFY_UNITS/$NOTIFY_NAME.service" "$WIZARD_APP_ENTRY" "$WIZARD_TERMINAL_ENTRY" \ + "$(wizard_desktop_dir)/$WIZARD_DESKTOP_NAME"; do + [[ -f "$f" ]] && sed -i "s|$old_bin/|$STEAMIFY_BIN/|g" "$f" + done + systemctl --user daemon-reload 2>/dev/null + fi + if [[ -f "$old_icon" ]]; then + if [[ -e "$WIZARD_ICON" ]]; then rm -f "$old_icon"; else mv "$old_icon" "$WIZARD_ICON"; fi + gtk-update-icon-cache -q -f -t "$(dirname "$(dirname "$(dirname "$WIZARD_ICON")")")" 2>/dev/null || true + fi + for f in "$WIZARD_APP_ENTRY" "$WIZARD_TERMINAL_ENTRY" "$(wizard_desktop_dir)/$WIZARD_DESKTOP_NAME"; do + [[ -f "$f" ]] && grep -q '^Icon=cachyos-gamescope-boot-wizard$' "$f" && + sed -i 's|^Icon=cachyos-gamescope-boot-wizard$|Icon=steamify|' "$f" + done + return 0 +} diff --git a/lib/steam-machine.sh b/lib/steam-machine.sh index f5c174e..54634b5 100644 --- a/lib/steam-machine.sh +++ b/lib/steam-machine.sh @@ -311,7 +311,9 @@ led_dkms_override_remove() { sudo rm -f "$LED_DKMS_OVERRIDE" fi } -HEADERS_SCRIPT="/usr/local/lib/cachyos-gamescope-boot/ensure-kernel-headers" +HEADERS_SCRIPT="/usr/local/lib/steamify/ensure-kernel-headers" +# Before 2.5.0; removed when it's set up again or turned off. +HEADERS_SCRIPT_OLD="/usr/local/lib/cachyos-gamescope-boot/ensure-kernel-headers" HEADERS_UNIT="/etc/systemd/system/ensure-kernel-headers.service" install_headers_boot_check() { @@ -323,6 +325,7 @@ install_headers_boot_check() { sudo mkdir -p "$(dirname "$HEADERS_SCRIPT")" patch_file ensure-kernel-headers.sh | sudo tee "$HEADERS_SCRIPT" > /dev/null sudo chmod 755 "$HEADERS_SCRIPT" + sudo rm -rf "$(dirname "$HEADERS_SCRIPT_OLD")" service_file ensure-kernel-headers.service HEADERS_SCRIPT="$HEADERS_SCRIPT" | sudo tee "$HEADERS_UNIT" > /dev/null sudo systemctl daemon-reload sudo systemctl enable ensure-kernel-headers.service @@ -432,7 +435,7 @@ machine_disable() { sudo systemctl disable ensure-kernel-headers.service 2>/dev/null led_dkms_override_remove sudo rm -f "$HEADERS_UNIT" "$HEADERS_SCRIPT" - sudo rmdir "$(dirname "$HEADERS_SCRIPT")" 2>/dev/null + sudo rm -rf "$(dirname "$HEADERS_SCRIPT")" "$(dirname "$HEADERS_SCRIPT_OLD")" sudo systemctl daemon-reload ok "Steam Machine support removed (the AUR helper, if installed, is kept)." } diff --git a/lib/update-notifier.sh b/lib/update-notifier.sh index bf2a68d..7f96cea 100644 --- a/lib/update-notifier.sh +++ b/lib/update-notifier.sh @@ -6,8 +6,7 @@ # then; it never updates anything itself (patches/steamify-notifier.py). # Sourced by steamify.sh; not meant to be run on its own. -NOTIFY_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/cachyos-gamescope-boot" -NOTIFY_SCRIPT="$NOTIFY_DIR/steamify-notifier" +NOTIFY_SCRIPT="$STEAMIFY_BIN/steamify-notifier" NOTIFY_UNITS="${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user" NOTIFY_NAME=steamify-update-check @@ -52,7 +51,7 @@ notify_enable() { notify_disable() { systemctl --user disable --now "$NOTIFY_NAME.timer" "$NOTIFY_NAME.service" >/dev/null 2>&1 rm -f "$NOTIFY_UNITS/$NOTIFY_NAME.service" "$NOTIFY_UNITS/$NOTIFY_NAME.timer" "$NOTIFY_SCRIPT" - rmdir "$NOTIFY_DIR" 2>/dev/null || true + rmdir "$STEAMIFY_BIN" 2>/dev/null || true systemctl --user daemon-reload state_clear notify ok "Update notifications off." diff --git a/lib/wizard-shortcut.sh b/lib/wizard-shortcut.sh index 63bd085..47db39e 100644 --- a/lib/wizard-shortcut.sh +++ b/lib/wizard-shortcut.sh @@ -10,9 +10,9 @@ WIZARD_RELEASE="https://github.com/theupriser/steamify-cachyos/releases/latest/d WIZARD_URL="$WIZARD_RELEASE/steamify.sh" WIZARD_APP_URL="$WIZARD_RELEASE/steamify-app.sh" # Steam logo with a gear (assets/ in the repo, published with every release). -WIZARD_ICON="${XDG_DATA_HOME:-$HOME/.local/share}/icons/hicolor/scalable/apps/cachyos-gamescope-boot-wizard.svg" -WIZARD_LAUNCHER="${XDG_DATA_HOME:-$HOME/.local/share}/cachyos-gamescope-boot/run-wizard" -WIZARD_APP_LAUNCHER="${XDG_DATA_HOME:-$HOME/.local/share}/cachyos-gamescope-boot/run-app" +WIZARD_ICON="${XDG_DATA_HOME:-$HOME/.local/share}/icons/hicolor/scalable/apps/steamify.svg" +WIZARD_LAUNCHER="$STEAMIFY_BIN/run-wizard" +WIZARD_APP_LAUNCHER="$STEAMIFY_BIN/run-app" WIZARD_APPS="${XDG_DATA_HOME:-$HOME/.local/share}/applications" # steamify-ui: the id the app gives itself, so its window belongs to this # entry. steamify-app.sh leaves an entry with X-Steamify-Shortcut alone. @@ -91,7 +91,7 @@ EOF tmp="$(mktemp)" if curl -fsSL --max-time 20 "$WIZARD_RELEASE/steam-gaming-settings.svg" -o "$tmp" && grep -q '/dev/null || true else warn "Couldn't download the shortcut's icon; using Steam's icon instead." diff --git a/patches/ensure-kernel-headers.sh b/patches/ensure-kernel-headers.sh index ca69b41..a3ac7be 100644 --- a/patches/ensure-kernel-headers.sh +++ b/patches/ensure-kernel-headers.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Installed by cachyos-gamescope-boot: install missing -headers for every +# Installed by Steamify: install missing -headers for every # installed kernel, so DKMS builds leds-valve for it. set -u missing=() diff --git a/patches/steamify-notifier.py b/patches/steamify-notifier.py index 457e9c1..bf198b9 100644 --- a/patches/steamify-notifier.py +++ b/patches/steamify-notifier.py @@ -16,11 +16,11 @@ import urllib.request REPO = "theupriser/steamify-cachyos" STATE_DIR = os.path.join(os.environ.get("XDG_STATE_HOME") or os.path.expanduser("~/.local/state"), - "cachyos-gamescope-boot") + "steamify") STATE = os.path.join(STATE_DIR, "notify.state") DATA = os.environ.get("XDG_DATA_HOME") or os.path.expanduser("~/.local/share") -RUN_APP = os.path.join(DATA, "cachyos-gamescope-boot", "run-app") -RUN_TERMINAL = os.path.join(DATA, "cachyos-gamescope-boot", "run-wizard") +RUN_APP = os.path.join(DATA, "steamify", "bin", "run-app") +RUN_TERMINAL = os.path.join(DATA, "steamify", "bin", "run-wizard") RELEASE = f"https://github.com/{REPO}/releases/latest/download" @@ -83,7 +83,7 @@ def main(): app.setApplicationName("Steamify") app.setDesktopFileName("steamify-ui") app.setQuitOnLastWindowClosed(False) - icon = QIcon.fromTheme("cachyos-gamescope-boot-wizard", QIcon.fromTheme("steam")) + icon = QIcon.fromTheme("steamify", QIcon.fromTheme("steam")) def open_app(): # The way Steamify was last used (the app or the terminal menu), the @@ -126,7 +126,7 @@ def main(): relay.picked.connect(lambda a: open_app() if a == "open" else skip() if a == "skip" else None) def notify(): - r = subprocess.run(["notify-send", "--app-name=Steamify", "--icon=cachyos-gamescope-boot-wizard", + r = subprocess.run(["notify-send", "--app-name=Steamify", "--icon=steamify", "-A", "open=Open Steamify", "-A", "skip=Skip this version", f"Steamify {new} is available", "Open Steamify to see what's new and choose what to update."], diff --git a/steamify.sh b/steamify.sh index 89ea74b..995c023 100755 --- a/steamify.sh +++ b/steamify.sh @@ -43,6 +43,7 @@ fi # Everything per-user (autologin user, Steam, theme, shortcut) is for the # user running the script. TARGET_USER="$(id -un)" +migrate_layout notify_seen restart_needed() { [[ -n "${BIOS_NEEDS_RESTART:-}" || "$RESTART_FOR_LOGIN" == true ]]; }