From ace3dcb03dfb727a1e48a5393cf03f7ec846c2f5 Mon Sep 17 00:00:00 2001 From: Kyzcreig <9063726+Kyzcreig@users.noreply.github.com> Date: Fri, 10 Jul 2026 17:44:46 -0700 Subject: [PATCH] =?UTF-8?q?fix(desktop):=20cross-machine=20session-list=20?= =?UTF-8?q?sync=20=E2=80=94=20refresh=20sidebar=20on=20focus=20+=2030s=20f?= =?UTF-8?q?ocused=20poll?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BroadcastChannel only reaches windows on the SAME machine, and gateway session.info events route to the owning transport only, so a pin/unpin/ title/create on one desktop never propagated live to another (visible only after app restart — reported by Ace pinning on Studio and MBP). Mirrors the poll-based livesync pattern: refresh on window focus + a 30s interval while focused. No new RPCs; reuses refreshSessions(). --- apps/desktop/src/app/desktop-controller.tsx | 27 +++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/apps/desktop/src/app/desktop-controller.tsx b/apps/desktop/src/app/desktop-controller.tsx index fd689ef6dd3d..5bff50623cc7 100644 --- a/apps/desktop/src/app/desktop-controller.tsx +++ b/apps/desktop/src/app/desktop-controller.tsx @@ -415,6 +415,33 @@ export function DesktopController() { return onSessionsChanged(() => void refreshSessions().catch(() => undefined)) }, [refreshSessions]) + // Cross-MACHINE session-list sync: BroadcastChannel only reaches windows on + // this machine, and the gateway routes session.info events to the session's + // owning transport only — so a pin/title/create on another desktop never + // reaches this one live (it only showed up after an app restart). Re-pull the + // list on window focus and on a slow poll while focused, mirroring the + // poll-based livesync pattern. + useEffect(() => { + if (isSecondaryWindow()) { + return + } + + const refresh = () => void refreshSessions().catch(() => undefined) + + window.addEventListener('focus', refresh) + + const timer = window.setInterval(() => { + if (typeof document.hasFocus !== 'function' || document.hasFocus()) { + refresh() + } + }, 30_000) + + return () => { + window.removeEventListener('focus', refresh) + window.clearInterval(timer) + } + }, [refreshSessions]) + const toggleSelectedPin = useCallback(() => { const sessionId = $selectedStoredSessionId.get()