diff --git a/README.md b/README.md index 8b6df65..9df5133 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,8 @@ It runs these steps, in this order, and every one of them is idempotent: | 7. systemd drop-ins | writes the shutdown timeouts, oomd thresholds, plocate prune paths, and sleep hooks under `/etc` | | 8. System services | enables NetworkManager, resolved, bluetooth, cups, avahi, docker, power-profiles-daemon, and oomd, and masks `NetworkManager-wait-online` | | 9. Login screen | installs the session entry and the SDDM config, enables `sddm.service`, and sets the default target to `graphical.target` | -| 10. Launch | starts the login screen, so the desktop comes up without a reboot | +| 10. Reload | reloads systemd, restarts the running user services, and in a running session re-renders the theme, reloads Hyprland, and restarts the Blob shell | +| 11. Launch | starts the login screen, so the desktop comes up without a reboot | Step 9 is the one a plain Arch install cannot do without: SDDM's stock Wayland greeter runs on `weston`, which Blob does not install, so the greeter is pointed diff --git a/docs/install.md b/docs/install.md index d8c49e6..d530ca3 100644 --- a/docs/install.md +++ b/docs/install.md @@ -17,6 +17,7 @@ with `--check`. | `install/steps/services.sh` | system services, systemd drop-ins, user units | | `install/steps/theme.sh` | the wallpaper link, the first theme, the first background | | `install/steps/login.sh` | SDDM, the session entry, and the first launch | +| `install/steps/reload.sh` | reloading systemd, the user services, and a running session | ## Steps @@ -128,7 +129,15 @@ with `--check`. `--autologin` writes `zzz-blob-autologin.conf`, the only file that sorts after `zz-blob.conf`. -10. **Launch.** `sddm`, `hyprland`, `quickshell` and `uwsm` are checked one last +10. **Reload.** systemd re-reads its units and `systemd-oomd` is restarted so + the new drop-ins apply. The user manager is reloaded and every Blob user + service that is running is restarted. When a Hyprland session is running + for this user, the current theme is rendered again with + `blob-theme-refresh`, Hyprland reloads its config, and the Blob shell + restarts, so an install over a live desktop takes effect without logging + out. The shell restart is refused while the screen is locked. Nothing that + was stopped is started, and `--check` only reports what would reload. +11. **Launch.** `sddm`, `hyprland`, `quickshell` and `uwsm` are checked one last time and any that are missing are named, because that is the whole difference between a desktop and a console. Then, when the installer was run from a console and nothing graphical is running, it starts `sddm.service` so the diff --git a/install.sh b/install.sh index becbabf..59a9555 100755 --- a/install.sh +++ b/install.sh @@ -19,7 +19,8 @@ usage() { Usage: ./install.sh [OPTIONS] Creates every directory Blob needs, installs the packages that are missing, -writes the config, enables the services, and opens the login screen. +writes the config, enables the services, reloads a running session so every +change takes effect, and opens the login screen. --check Report what would change, write nothing --force Overwrite files that have local changes @@ -50,6 +51,7 @@ source "$repo_dir/install/steps/config.sh" source "$repo_dir/install/steps/services.sh" source "$repo_dir/install/steps/theme.sh" source "$repo_dir/install/steps/login.sh" +source "$repo_dir/install/steps/reload.sh" say "Blob installer" say "repo: $repo_dir" @@ -88,6 +90,10 @@ report_greeter_compositor report_login_conflicts report_desktop_essentials +reload_system_services +reload_user_services +reload_session + say "" if [[ $check == true ]]; then say "$changes item(s) would change." diff --git a/install/steps/reload.sh b/install/steps/reload.sh new file mode 100644 index 0000000..abcd4f7 --- /dev/null +++ b/install/steps/reload.sh @@ -0,0 +1,79 @@ +reloaded_system_services=( + systemd-oomd.service +) + +session_running() { + pgrep -u "$UID" -x Hyprland &>/dev/null +} + +reload_system_services() { + if [[ $check == true ]]; then + say "would reload systemd and restart ${reloaded_system_services[*]}" + return 0 + fi + + if ! as_root systemctl daemon-reload; then + say "WARN could not reload systemd" + return 0 + fi + + local unit + for unit in "${reloaded_system_services[@]}"; do + system_unit_exists "$unit" || continue + as_root systemctl try-restart "$unit" || say "WARN could not restart $unit" + done + + say "ok system services reloaded" +} + +reload_user_services() { + if ! user_manager_available; then + say "SKIP user services reload (no user systemd manager)" + return 0 + fi + + if [[ $check == true ]]; then + say "would restart the running user services" + return 0 + fi + + systemctl --user daemon-reload + + local unit failed=() + for unit in "${user_services[@]}"; do + systemctl --user try-restart "$unit" &>/dev/null || failed+=("$unit") + done + + if (( ${#failed[@]} > 0 )); then + say "WARN could not restart: ${failed[*]}" + else + say "ok user services reloaded" + fi +} + +run_session_reload() { + local label="$1" + shift + + if BLOB_PATH="$blob_path" PATH="$blob_path/bin:$PATH" "$@" &>/dev/null; then + say "ok $label reloaded" + else + say "WARN could not reload $label" + fi +} + +reload_session() { + if ! session_running; then + say "SKIP session reload (Blob is not running)" + return 0 + fi + + if [[ $check == true ]]; then + say "would reload the theme, Hyprland, and the Blob shell" + return 0 + fi + + run_session_reload "theme" blob-theme-refresh + run_session_reload "Hyprland" blob-hypr-restart + run_session_reload "Blob shell" blob-shell-restart +}