diff --git a/bin/omarchy-system-reboot b/bin/omarchy-system-reboot index 661971bd..e3e23c36 100755 --- a/bin/omarchy-system-reboot +++ b/bin/omarchy-system-reboot @@ -4,10 +4,11 @@ # omarchy:examples=omarchy reboot | omarchy system reboot # omarchy:aliases=omarchy reboot -omarchy-state clear re*-required +# Schedule the reboot in the user manager so closing the terminal's systemd +# scope cannot terminate it before it runs. +systemd-run --user --collect --quiet --on-active="2s" systemctl reboot --no-wall || exit 1 -# Schedule the reboot to happen after closing windows (detached from terminal) -nohup bash -c "sleep 2 && systemctl reboot --no-wall" >/dev/null 2>&1 & +omarchy-state clear re*-required # Now close all windows omarchy-hyprland-window-close-all diff --git a/bin/omarchy-system-shutdown b/bin/omarchy-system-shutdown index 50e489ff..e13e6658 100755 --- a/bin/omarchy-system-shutdown +++ b/bin/omarchy-system-shutdown @@ -4,10 +4,11 @@ # omarchy:examples=omarchy shutdown | omarchy system shutdown # omarchy:aliases=omarchy shutdown -omarchy-state clear re*-required +# Schedule the shutdown in the user manager so closing the terminal's systemd +# scope cannot terminate it before it runs. +systemd-run --user --collect --quiet --on-active="2s" systemctl poweroff --no-wall || exit 1 -# Schedule the shutdown to happen after closing windows (detached from terminal) -nohup bash -c "sleep 2 && systemctl poweroff --no-wall" >/dev/null 2>&1 & +omarchy-state clear re*-required # Now close all windows omarchy-hyprland-window-close-all diff --git a/test/shell.d/system-power-test.sh b/test/shell.d/system-power-test.sh new file mode 100755 index 00000000..cc90ee9b --- /dev/null +++ b/test/shell.d/system-power-test.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +source "$(dirname "$0")/base-test.sh" + +test_tmp=$(mktemp -d) +trap 'rm -rf "$test_tmp"' EXIT + +mock_bin="$test_tmp/bin" +call_log="$test_tmp/calls.log" +mkdir -p "$mock_bin" + +cat >"$mock_bin/systemd-run" <<'SH' +#!/bin/bash + +printf 'systemd-run %s\n' "$*" >>"$CALL_LOG" +[[ ${FAIL_SYSTEMD_RUN:-false} == "true" ]] && exit 1 +exit 0 +SH + +for command in omarchy-state omarchy-hyprland-window-close-all sleep; do + cat >"$mock_bin/$command" <<'SH' +#!/bin/bash + +printf '%s %s\n' "$(basename "$0")" "$*" >>"$CALL_LOG" +SH +done +chmod +x "$mock_bin"/* + +run_power_command() { + local action="$1" + + : >"$call_log" + PATH="$mock_bin:$PATH" CALL_LOG="$call_log" "$ROOT/bin/omarchy-system-$action" +} + +assert_power_calls() { + local action="$1" + local systemctl_action="$2" + local expected_log="$test_tmp/$action-expected.log" + + cat >"$expected_log" <"$call_log" + if PATH="$mock_bin:$PATH" CALL_LOG="$call_log" FAIL_SYSTEMD_RUN=true "$ROOT/bin/omarchy-system-$action"; then + fail "$action aborts when scheduling fails" + fi + + if (( $(wc -l <"$call_log") != 1 )); then + fail "$action leaves state and windows alone when scheduling fails" + fi + pass "$action leaves state and windows alone when scheduling fails" +done