From 4a02da20d58d912a74748845bc55b5ec73acd65f Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Wed, 22 Jul 2026 12:44:09 -0700 Subject: [PATCH] Relaunch the shell through Hyprland so restarts match boot conditions Spawning quickshell directly from omarchy-restart-shell leaked transient environment variables from the calling terminal, SSH connection, or development tool into the fresh shell. Dispatch the launch through Hyprland instead so it inherits the canonical session environment, same as autostart. Co-Authored-By: Claude Fable 5 --- bin/omarchy-restart-shell | 4 +++- test/shell.d/restart-shell-test.sh | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/bin/omarchy-restart-shell b/bin/omarchy-restart-shell index ef9bbed9..ee07d931 100755 --- a/bin/omarchy-restart-shell +++ b/bin/omarchy-restart-shell @@ -23,7 +23,9 @@ fi # 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 & +# Spawn from Hyprland so the shell inherits the canonical session environment, +# not transient variables from a terminal, SSH connection, or development tool. +hyprctl dispatch 'hl.dsp.exec_cmd("quickshell -n -p $OMARCHY_PATH/shell")' >/dev/null for (( attempt = 0; attempt < 20; attempt++ )); do OMARCHY_SHELL_IPC_TIMEOUT=0.5s omarchy-shell shell ping >/dev/null 2>&1 && exit 0 diff --git a/test/shell.d/restart-shell-test.sh b/test/shell.d/restart-shell-test.sh index b7cfba77..727e95ed 100755 --- a/test/shell.d/restart-shell-test.sh +++ b/test/shell.d/restart-shell-test.sh @@ -54,6 +54,8 @@ restart_root="$test_tmp/restart-root" restart_bin="$restart_root/bin" restart_state="$test_tmp/restart-pids" restart_log="$test_tmp/restart.log" +restart_env_log="$test_tmp/restart-env.log" +dispatch_log="$test_tmp/dispatch.log" ipc_log="$test_tmp/ipc.log" runtime_dir="$test_tmp/runtime" mkdir -p "$restart_root/shell" "$restart_bin" "$runtime_dir" @@ -88,6 +90,7 @@ case " $* " in mv "$OMARCHY_TEST_QS_STATE.next" "$OMARCHY_TEST_QS_STATE" ;; *' -n -p '*) + printf '%s\n' "${OMARCHY_TEST_TRANSIENT_ENV-unset}" >"$OMARCHY_TEST_QS_ENV_LOG" printf '303\n' >"$OMARCHY_TEST_QS_STATE" ;; esac @@ -102,6 +105,12 @@ if [[ ${1:-} == "-j" && ${2:-} == "monitors" ]]; then else printf '[]\n' fi +elif [[ ${1:-} == "dispatch" && ${2:-} == hl.dsp.exec_cmd* ]]; then + printf '%s\n' "${2:-}" >>"$OMARCHY_TEST_DISPATCH_LOG" + env -u OMARCHY_TEST_TRANSIENT_ENV quickshell -n -p "$OMARCHY_PATH/shell" + printf 'ok\n' +elif [[ ${1:-} == "dispatch" ]]; then + exit 1 fi SH @@ -118,7 +127,10 @@ OMARCHY_PATH="$restart_root" \ XDG_RUNTIME_DIR="$runtime_dir" \ OMARCHY_TEST_QS_STATE="$restart_state" \ OMARCHY_TEST_QS_LOG="$restart_log" \ +OMARCHY_TEST_QS_ENV_LOG="$restart_env_log" \ +OMARCHY_TEST_DISPATCH_LOG="$dispatch_log" \ OMARCHY_TEST_IPC_LOG="$ipc_log" \ +OMARCHY_TEST_TRANSIENT_ENV=leaked \ timeout 5 "$ROOT/bin/omarchy-restart-shell" if kill -0 "$restart_pid_one" 2>/dev/null; then @@ -133,6 +145,8 @@ 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" +[[ $(<"$restart_env_log") == "unset" ]] || fail "restart uses the Hyprland session environment for the fresh shell" +grep -F 'hl.dsp.exec_cmd("quickshell -n -p $OMARCHY_PATH/shell")' "$dispatch_log" >/dev/null || fail "restart launches the fresh shell through Hyprland" grep -F 'shell ping' "$ipc_log" >/dev/null || fail "restart waits for fresh shell IPC readiness" pass "restart replaces duplicate shell instances" @@ -145,6 +159,7 @@ locked_error=$(PATH="$restart_bin:$PATH" \ OMARCHY_TEST_SESSION_LOCKED=1 \ OMARCHY_TEST_QS_STATE="$restart_state" \ OMARCHY_TEST_QS_LOG="$restart_log" \ + OMARCHY_TEST_DISPATCH_LOG="$dispatch_log" \ OMARCHY_TEST_IPC_LOG="$ipc_log" \ "$ROOT/bin/omarchy-restart-shell" 2>&1) && fail "restart refuses while the shell lock is active"