Fix RDP session drop/flicker: stop re-parenting Guacamole display (#45)
Symptom: desktop flickers in for a moment then goes blank while the tab still says "connected"; guacd logs "User is not responding" and the client reconnects in a loop. Root cause: the multi-session view moved each session's display element between DOM nodes on tab switch (host.innerHTML='' + appendChild). Detaching a guacamole-common-js display from the DOM stalls its sync loop, so the client stops echoing guacd's sync instructions and guacd drops it as unresponsive. Proven out-of-band: a raw guacd client that echoes sync held a connection for 30s/116 syncs with no drop, while the browser dropped within seconds. Fix: mount each session's container into the display host ONCE and never move it; toggle visibility (display:none) to switch tabs so every session's display stays in the DOM and its sync loop keeps running. Containers are absolutely positioned in a relative host; close still removes the container. Co-authored-by: Samuel James <ssamjame@amazon.com> Co-authored-by: Kiro <noreply@kiro.dev>
This commit is contained in:
parent
a7fbbabeb2
commit
58a46553d9
1 changed files with 17 additions and 15 deletions
|
|
@ -64,7 +64,13 @@ export default function RemoteDesktop() {
|
||||||
setActiveSessionId(sessionId)
|
setActiveSessionId(sessionId)
|
||||||
|
|
||||||
const container = document.createElement('div')
|
const container = document.createElement('div')
|
||||||
container.className = 'h-full w-full overflow-auto'
|
container.className = 'absolute inset-0 overflow-auto'
|
||||||
|
container.style.display = 'none'
|
||||||
|
// Mount the container into the display host ONCE and never move it again —
|
||||||
|
// re-parenting the Guacamole display between DOM nodes breaks its sync loop,
|
||||||
|
// which makes guacd drop the user as "not responding". We toggle visibility
|
||||||
|
// instead (see the activation effect below).
|
||||||
|
displayHostRef.current?.appendChild(container)
|
||||||
|
|
||||||
const token = getToken()
|
const token = getToken()
|
||||||
const proto = window.location.protocol === 'https:' ? 'wss' : 'ws'
|
const proto = window.location.protocol === 'https:' ? 'wss' : 'ws'
|
||||||
|
|
@ -105,20 +111,16 @@ export default function RemoteDesktop() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show only the active session's display element; keep the rest mounted off-DOM so
|
// Show only the active session's display; keep all others mounted but hidden so
|
||||||
// background sessions stay connected while their tab isn't focused.
|
// their sessions stay connected AND their sync loop keeps running (do NOT move
|
||||||
|
// them out of the DOM — that breaks Guacamole's sync and guacd drops them).
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const host = displayHostRef.current
|
handlesRef.current.forEach((handle, id) => {
|
||||||
if (!host) return
|
const visible = id === activeSessionId
|
||||||
host.innerHTML = ''
|
handle.container.style.display = visible ? 'block' : 'none'
|
||||||
const active = activeSessionId ? handlesRef.current.get(activeSessionId) : null
|
if (visible) fitDisplay(handle, displayHostRef.current)
|
||||||
if (active) {
|
})
|
||||||
host.appendChild(active.container)
|
}, [activeSessionId, sessions])
|
||||||
// The display may have received its size while off-DOM (zero-sized), which
|
|
||||||
// leaves the canvas unscaled / invisible — re-fit now that it's visible.
|
|
||||||
fitDisplay(active, host)
|
|
||||||
}
|
|
||||||
}, [activeSessionId])
|
|
||||||
|
|
||||||
// Keep the active session scaled to the panel as the window/panel resizes.
|
// Keep the active session scaled to the panel as the window/panel resizes.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -216,7 +218,7 @@ export default function RemoteDesktop() {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div ref={displayHostRef} className="flex-1 overflow-auto" />
|
<div ref={displayHostRef} className="relative flex-1 overflow-hidden" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue