From d18846dcbc9cf178fa3c6e27cd4e2e788af68f09 Mon Sep 17 00:00:00 2001 From: lbgos <285507185+lbgos@users.noreply.github.com> Date: Tue, 13 Oct 2026 06:39:05 +0300 Subject: [PATCH] steamvr_drv: adopt a respawned compositor instead of restarting the session DisplayRecovery froze its compositor handle while the loss latch was set, so a compositor SteamVR had already respawned still looked dead and the guard SIGTERMed a self-healed session. Re-pin whenever the tracked generation exits and a unique replacement exists; keep the dead handle only while nothing replaced it. --- .../steamvr_drv/ovrd_roomsetup_guard.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/xrt/state_trackers/steamvr_drv/ovrd_roomsetup_guard.cpp b/src/xrt/state_trackers/steamvr_drv/ovrd_roomsetup_guard.cpp index 31262559b..27231b749 100644 --- a/src/xrt/state_trackers/steamvr_drv/ovrd_roomsetup_guard.cpp +++ b/src/xrt/state_trackers/steamvr_drv/ovrd_roomsetup_guard.cpp @@ -243,9 +243,16 @@ public: bool stable = display_health.update(connected && !exited(compositor), vsync_age, vsync, now); if (connected) { connected_once = true; - if (!lost && exited(compositor)) { - if (compositor >= 0) close(compositor); - compositor = unique_runtime_process(runtime / "vrcompositor"); + if (exited(compositor)) { + // Adopt a replacement compositor if SteamVR already respawned + // one: killing the session then would destroy a self-healed + // display. Keep the dead handle as evidence while no + // replacement exists so the trigger below still fires. + int replacement = unique_runtime_process(runtime / "vrcompositor"); + if (replacement >= 0) { + if (compositor >= 0) close(compositor); + compositor = replacement; + } } // A watchdog can exit well after USB returns. Disarm only after native // vsync advances continuously, never merely because the process lives.