diff --git a/bin/omarchy-restart-shell b/bin/omarchy-restart-shell index 8537cca7..ef9bbed9 100755 --- a/bin/omarchy-restart-shell +++ b/bin/omarchy-restart-shell @@ -18,15 +18,10 @@ if [[ $(hyprctl -j monitors 2>/dev/null) == *'"LOCK"'* ]]; then exit 1 fi -for (( attempt = 0; attempt < 50; attempt++ )); do - quickshell kill -p "$CONFIG_DIR" --any-display >/dev/null 2>&1 || break - sleep 0.1 -done - -if (( attempt == 50 )); then - echo "Could not stop all Omarchy shell instances." >&2 - exit 1 -fi +# Each kill stops the oldest matching instance and only returns once it has +# fully exited, so the no-duplicate launch below can't race a dying shell. +# Requires our quickshell-git build; 0.3.0's kill returns immediately. +while timeout 5 quickshell kill -p "$CONFIG_DIR" --any-display >/dev/null 2>&1; do :; done setsid quickshell -n -p "$CONFIG_DIR" >/dev/null 2>&1 & diff --git a/test/shell.d/restart-shell-test.sh b/test/shell.d/restart-shell-test.sh index bd834fb2..b7cfba77 100755 --- a/test/shell.d/restart-shell-test.sh +++ b/test/shell.d/restart-shell-test.sh @@ -5,7 +5,15 @@ set -euo pipefail source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" test_tmp=$(mktemp -d) -trap 'rm -rf "$test_tmp"' EXIT +restart_pid_one="" +restart_pid_two="" + +cleanup() { + [[ -n $restart_pid_one ]] && kill "$restart_pid_one" 2>/dev/null || true + [[ -n $restart_pid_two ]] && kill "$restart_pid_two" 2>/dev/null || true + rm -rf "$test_tmp" +} +trap cleanup EXIT wrapper_root="$test_tmp/wrapper-root" wrapper_bin="$test_tmp/wrapper-bin" @@ -74,7 +82,8 @@ case " $* " in *' kill -p '*) pid=$(head -n 1 "$OMARCHY_TEST_QS_STATE") [[ $pid =~ ^[0-9]+$ ]] || exit 1 - printf 'stopped:%s\n' "$pid" >>"$OMARCHY_TEST_QS_LOG" + kill "$pid" 2>/dev/null + while kill -0 "$pid" 2>/dev/null; do sleep 0.01; done awk 'NR > 1' "$OMARCHY_TEST_QS_STATE" >"$OMARCHY_TEST_QS_STATE.next" mv "$OMARCHY_TEST_QS_STATE.next" "$OMARCHY_TEST_QS_STATE" ;; @@ -98,7 +107,11 @@ SH chmod +x "$restart_bin/qs" "$restart_bin/quickshell" "$restart_bin/hyprctl" -printf '101\n202\n' >"$restart_state" +sleep 30 & +restart_pid_one=$! +sleep 30 & +restart_pid_two=$! +printf '%s\n%s\n' "$restart_pid_one" "$restart_pid_two" >"$restart_state" PATH="$restart_bin:$PATH" \ OMARCHY_PATH="$restart_root" \ @@ -108,8 +121,16 @@ OMARCHY_TEST_QS_LOG="$restart_log" \ OMARCHY_TEST_IPC_LOG="$ipc_log" \ timeout 5 "$ROOT/bin/omarchy-restart-shell" -grep -F 'stopped:101' "$restart_log" >/dev/null || fail "restart stops the first matching shell instance" -grep -F 'stopped:202' "$restart_log" >/dev/null || fail "restart stops duplicate matching shell instances" +if kill -0 "$restart_pid_one" 2>/dev/null; then + fail "restart stops the first matching shell instance" +fi +if kill -0 "$restart_pid_two" 2>/dev/null; then + fail "restart stops duplicate matching shell instances" +fi +wait "$restart_pid_one" 2>/dev/null || true +wait "$restart_pid_two" 2>/dev/null || true +restart_pid_one="" +restart_pid_two="" [[ $(<"$restart_state") == 303 ]] || fail "restart leaves exactly one fresh shell instance" [[ $(grep -c '^-n -p ' "$restart_log") == 1 ]] || fail "restart launches one fresh shell process" grep -F 'shell ping' "$ipc_log" >/dev/null || fail "restart waits for fresh shell IPC readiness"