From ac0e5e28b3398f4e86ff283d1333c2933a86f744 Mon Sep 17 00:00:00 2001 From: Rick Peters Date: Sat, 3 Oct 2026 13:19:24 +0200 Subject: [PATCH] refactor: theme_enable and create_desktop_shortcut in steps; make test skips the hardware test --- CHANGELOG.md | 1 + Makefile | 3 ++- lib/desktop-shortcut.sh | 59 +++++++++++++++++++++-------------------- lib/vapor-theme.sh | 42 +++++++++++++++++++---------- 4 files changed, 61 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3aace20..8fadae6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ one per merged pull request. - **refactor: the retired kernel pin moved out of `lib/steam-machine.sh` into `lib/kernel-pin.sh`** - **refactor: the shortcut's two start scripts are files in `patches/` (`steamify-start.sh`, `steamify-app-start.sh`) instead of heredocs in `launcher_enable`, and the 83-line LED driver install is split into steps (`led_write_dkms_override`, `led_install_package`, `led_build_all_kernels`, `led_load_module`); what gets installed is byte-identical** - **fix: the daily update check no longer crashes on a release tag that isn't a plain version number (`TypeError` comparing it, found by the new unit tests); it is simply never offered** +- **refactor: `theme_enable` and `create_desktop_shortcut` split into steps; the Return to Gaming Mode shortcut is written with its mode already set (`install_executable`), like the other shortcuts, instead of chmod afterwards** - **test: the menu rules, the plan and the app's and installer's JSON are checked against a golden file (`tests/menu-test.sh` in steamify-cachyos-dev); `make check`, `.editorconfig`, `.shellcheckrc`** - **docs: README lists the sources and projects Steamify builds on, with licences and thanks** diff --git a/Makefile b/Makefile index 0294d90..6219afd 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,8 @@ SH := steamify.sh $(wildcard lib/*.sh) ui/steamify-app.sh .github/tools/bundle.sh # The unit tests live in ../steamify-cachyos-dev/tests (REPO points at this checkout). DEV ?= ../steamify-cachyos-dev -TESTS := $(wildcard $(DEV)/tests/*-test.sh) +# Not the hardware test: it is for a real NVIDIA PC and writes a report in $$HOME. +TESTS := $(filter-out %-hardware-test.sh,$(wildcard $(DEV)/tests/*-test.sh)) .PHONY: check syntax lint lint-sh lint-py lint-qml test bundle fmt-check check: syntax lint test bundle diff --git a/lib/desktop-shortcut.sh b/lib/desktop-shortcut.sh index 1779418..eb74a1e 100644 --- a/lib/desktop-shortcut.sh +++ b/lib/desktop-shortcut.sh @@ -2,41 +2,46 @@ # "Return to Gaming Mode" desktop shortcut and the sudoers rule it needs. # Sourced by steamify.sh; not meant to be run on its own. -create_desktop_shortcut() { - # Determine the home directory of the target user - local user_home +shortcut_desktop_dir() { + # The target user's Desktop folder, from their user-dirs.dirs. + local user_home desktop_dir user_home="$(getent passwd "$TARGET_USER" | cut -d: -f6)" - - # Locate the correct Desktop directory - local desktop_dir if [[ -f "$user_home/.config/user-dirs.dirs" ]]; then desktop_dir=$(grep '^XDG_DESKTOP_DIR=' "$user_home/.config/user-dirs.dirs" | cut -d '"' -f 2) desktop_dir="${desktop_dir/\$HOME/$user_home}" fi - desktop_dir="${desktop_dir:-$user_home/Desktop}" + echo "${desktop_dir:-$user_home/Desktop}" +} +shortcut_install_sudoers() { + # plasma-login-manager needs the sync bridge run and a restart, which the + # shortcut can't sudo for interactively (Terminal=false), so it gets a + # password-less rule scoped to exactly those two commands. + local sudoers_tmp + sudoers_tmp="$(mktemp)" + cat > "$sudoers_tmp" << EOF +$TARGET_USER ALL=(root) NOPASSWD: /usr/bin/systemctl start sync-steamos-session.service, /usr/bin/systemctl restart plasmalogin +EOF + if sudo visudo -cf "$sudoers_tmp" >/dev/null; then + sudo install -m 0440 -o root -g root "$sudoers_tmp" /etc/sudoers.d/gamescope-session-switch + ok "Installed /etc/sudoers.d/gamescope-session-switch for the shortcut." + else + warn "Generated sudoers rule failed validation; the shortcut will not be able to restart plasmalogin." + fi + rm -f "$sudoers_tmp" +} + +create_desktop_shortcut() { + local desktop_dir + desktop_dir="$(shortcut_desktop_dir)" mkdir -p "$desktop_dir" # On SDDM, steamos-session-select logging out is enough: Relogin=true # logs straight back in to the newly selected session, like SteamOS. - # plasma-login-manager needs the sync bridge run and a restart, which - # the shortcut can't sudo for interactively (Terminal=false), so it gets - # a password-less rule scoped to exactly those two commands. local exec_line="steamos-session-select gamescope" if [[ "$LOGIN_MANAGER" == "plasmalogin" ]]; then exec_line="sh -c 'steamos-session-select gamescope && sudo -n /usr/bin/systemctl start sync-steamos-session.service && sudo -n /usr/bin/systemctl restart plasmalogin'" - local sudoers_tmp - sudoers_tmp="$(mktemp)" - cat > "$sudoers_tmp" << EOF -$TARGET_USER ALL=(root) NOPASSWD: /usr/bin/systemctl start sync-steamos-session.service, /usr/bin/systemctl restart plasmalogin -EOF - if sudo visudo -cf "$sudoers_tmp" >/dev/null; then - sudo install -m 0440 -o root -g root "$sudoers_tmp" /etc/sudoers.d/gamescope-session-switch - ok "Installed /etc/sudoers.d/gamescope-session-switch for the shortcut." - else - warn "Generated sudoers rule failed validation; the shortcut will not be able to restart plasmalogin." - fi - rm -f "$sudoers_tmp" + shortcut_install_sudoers else sudo rm -f /etc/sudoers.d/gamescope-session-switch fi @@ -49,11 +54,11 @@ EOF [[ -f /usr/local/share/icons/hicolor/scalable/actions/gaming-return.svg ]] && shortcut_icon="gaming-return" - # 2. Generate the .desktop shortcut with instant session switcher strings local shortcut_path="$desktop_dir/Return to Gaming Mode.desktop" info "Creating 'Return to Gaming Mode' desktop shortcut at: $shortcut_path" - - cat << EOF > "$shortcut_path" + # Written with its mode already set: Plasma opens a desktop icon it first + # saw non-executable in an editor. + install_executable "$shortcut_path" 755 << EOF [Desktop Entry] Name=Return to Gaming Mode Comment=Switch session back to Gamescope @@ -63,10 +68,6 @@ Terminal=false Type=Application Categories=System; EOF - - # Fix permissions for the target user and KDE Plasma desktop ecosystem - chmod +x "$shortcut_path" - ok "Desktop shortcut created successfully." } diff --git a/lib/vapor-theme.sh b/lib/vapor-theme.sh index d9b688a..ac025fa 100644 --- a/lib/vapor-theme.sh +++ b/lib/vapor-theme.sh @@ -47,26 +47,27 @@ theme_status() { [[ "$(kreadconfig6 --file kdeglobals --group KDE --key LookAndFeelPackage)" == "$VAPOR_LOOKANDFEEL" ]] } -theme_enable() { - if ! pacman -Q cachyos-vapor >/dev/null 2>&1; then - info "Installing cachyos-vapor..." - sudo pacman -S --needed --noconfirm cachyos-vapor || { err "Installing cachyos-vapor failed."; return 1; } - # Only remove it again on disable if we were the ones installing it. - state_set theme installed_pkg 1 - fi +theme_install_package() { + pacman -Q cachyos-vapor >/dev/null 2>&1 && return 0 + info "Installing cachyos-vapor..." + sudo pacman -S --needed --noconfirm cachyos-vapor || { err "Installing cachyos-vapor failed."; return 1; } + # Only remove it again on disable if we were the ones installing it. + state_set theme installed_pkg 1 +} + +theme_check_offline() { # Without a session (the ISO's installer), for a user who has never # logged in: the layout still CachyOS's default from /etc/skel is # removed (after the backup below), and Plasma builds its first layout # from the look-and-feel package, as --resetLayout does below. - local offline=false layout=~/.config/plasma-org.kde.plasma.desktop-appletsrc - if [[ -z "${WAYLAND_DISPLAY:-}${DISPLAY:-}" ]]; then - if [[ -e "$layout" ]] && ! cmp -s "$layout" "/etc/skel/.config/${layout##*/}"; then - err "Run this from the Plasma desktop: applying the Vapor layout needs a running Plasma session." - return 1 - fi - offline=true + local layout=~/.config/plasma-org.kde.plasma.desktop-appletsrc + if [[ -e "$layout" ]] && ! cmp -s "$layout" "/etc/skel/.config/${layout##*/}"; then + err "Run this from the Plasma desktop: applying the Vapor layout needs a running Plasma session." + return 1 fi +} +theme_backup_originals() { # Only the first time, so a re-apply doesn't overwrite the originals. local backup="$STATE_DIR/theme-layout" f if [[ ! -d "$backup" ]]; then @@ -84,7 +85,9 @@ theme_enable() { [[ -f "$f" ]] && kset theme "$f" Settings gtk-cursor-theme-name \ "$(kreadconfig6 --file "$f" --group Settings --key gtk-cursor-theme-name)" done +} +theme_set_look() { kset theme kdeglobals KDE LookAndFeelPackage "$VAPOR_LOOKANDFEEL" # Vapor is a dark theme: register it as the dark one, or Plasma's Dark # Mode toggle shows "off" and offers to switch to Breeze Dark. @@ -94,6 +97,17 @@ theme_enable() { # scheme that is already named in the config, without writing its colors. kset theme kdeglobals General ColorScheme --delete plasma-apply-colorscheme Vapor >/dev/null 2>&1 || true +} + +theme_enable() { + theme_install_package || return 1 + local offline=false + if [[ -z "${WAYLAND_DISPLAY:-}${DISPLAY:-}" ]]; then + theme_check_offline || return 1 + offline=true + fi + theme_backup_originals + theme_set_look if [[ "$offline" == true ]]; then rm -f ~/.config/plasma-org.kde.plasma.desktop-appletsrc ~/.config/plasmashellrc