From 28cc41abddd8dcfb42b5f0f1f333d6476428396e Mon Sep 17 00:00:00 2001 From: Bernardo Magri Date: Thu, 30 Apr 2026 20:09:15 +0100 Subject: [PATCH] fix(restart-app): wait for SIGTERM to take effect before respawning Previous behavior: `pkill -x $1` (no wait) followed by an immediate background `setsid uwsm-app`. The new instance attached its wayland surface while the old one's surface was still mapped. Layer-shell apps got the same visible ghosting that waybar showed on theme switch before the SIGUSR2 fix (386da51), and non-layer apps got brief double instances. Fix: - Quote $1 (was unquoted, breaks if app name has whitespace - rare but cost-free to fix while we're here). - After SIGTERM, poll pgrep for up to ~1.5s in 100ms ticks. - If anything is still alive after the poll window, SIGKILL it - prevents a misbehaving process from holding the surface forever. - Only spawn the new instance after the old one is confirmed gone. Affects every caller that hits the non-systemd-managed restart path (menu's update-process actions, voxtype install/remove, font-change follow-ups, etc.). Co-Authored-By: Claude Opus 4.7 --- features/scripts/utils/nomarchy-restart-app | 26 +++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/features/scripts/utils/nomarchy-restart-app b/features/scripts/utils/nomarchy-restart-app index 53ba2d1..953845a 100755 --- a/features/scripts/utils/nomarchy-restart-app +++ b/features/scripts/utils/nomarchy-restart-app @@ -2,6 +2,28 @@ # Restart an application by killing it and relaunching via uwsm. # Usage: nomarchy-restart-app [application-args...] +# +# We wait for the old process to actually exit before launching the +# new one. Without the wait, the new instance starts while the old +# one's wayland surface is still mapped — visible as ghosting on +# layer-shell apps and double-instance briefly for everything else. +# Same race that produced the waybar theme-switch artifacts before +# 386da51 moved waybar to a SIGUSR2-reload path. -pkill -x $1 -setsid uwsm-app -- "$@" >/dev/null 2>&1 & +app="$1" +shift || true + +if pgrep -x "$app" >/dev/null 2>&1; then + pkill -x "$app" 2>/dev/null || true + # Poll for graceful exit, up to ~1.5s. + for _ in $(seq 1 15); do + pgrep -x "$app" >/dev/null 2>&1 || break + sleep 0.1 + done + # Anything still running: SIGKILL it. Without this, a misbehaving + # process can hold the surface indefinitely and the new instance + # races on top. + pkill -KILL -x "$app" 2>/dev/null || true +fi + +setsid uwsm-app -- "$app" "$@" >/dev/null 2>&1 &