From 04c140f608b254f0a11acd5d19ff50a23f92e865 Mon Sep 17 00:00:00 2001 From: Vantz Stockwell Date: Mon, 30 Mar 2026 12:58:57 -0400 Subject: [PATCH] fix: RDP canvas re-measures container on tab switch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When switching from SSH back to RDP, the canvas retained the resolution from when the copilot panel was open — even after closing the panel. The ResizeObserver doesn't fire while the tab is hidden (v-show/display), so the container size change goes unnoticed. Fix: On tab activation, double-rAF waits for layout, measures the container via getBoundingClientRect, compares with canvas.width/height, and sends rdp_resize if they differ. This ensures the RDP session always matches the current available space. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/components/rdp/RdpView.vue | 43 +++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/src/components/rdp/RdpView.vue b/src/components/rdp/RdpView.vue index f1cdea0..89b684d 100644 --- a/src/components/rdp/RdpView.vue +++ b/src/components/rdp/RdpView.vue @@ -204,17 +204,44 @@ onBeforeUnmount(() => { if (resizeTimeout) { clearTimeout(resizeTimeout); resizeTimeout = null; } }); -// Focus canvas and force full frame refresh when switching to this tab +// Focus canvas, re-check dimensions, and force full frame on tab switch watch( () => props.isActive, (active) => { - if (active && canvasRef.value) { - // Force full frame fetch to repaint the canvas immediately - invoke("rdp_force_refresh", { sessionId: props.sessionId }).catch(() => {}); - if (keyboardGrabbed.value) { - setTimeout(() => canvasRef.value?.focus(), 0); - } - } + if (!active || !canvasRef.value) return; + + // Wait for layout to settle after tab becomes visible + requestAnimationFrame(() => { + requestAnimationFrame(() => { + const wrapper = canvasWrapper.value; + const canvas = canvasRef.value; + if (!wrapper || !canvas) return; + + const { width: cw, height: ch } = wrapper.getBoundingClientRect(); + const newW = Math.round(cw) & ~1; + const newH = Math.round(ch); + + // If container size differs from canvas resolution, resize the RDP session + if (newW >= 200 && newH >= 200 && (newW !== canvas.width || newH !== canvas.height)) { + invoke("rdp_resize", { + sessionId: props.sessionId, + width: newW, + height: newH, + }).then(() => { + canvas.width = newW; + canvas.height = newH; + setTimeout(() => { + invoke("rdp_force_refresh", { sessionId: props.sessionId }).catch(() => {}); + }, 200); + }).catch(() => {}); + } else { + // Same size — just refresh the frame + invoke("rdp_force_refresh", { sessionId: props.sessionId }).catch(() => {}); + } + + if (keyboardGrabbed.value) canvas.focus(); + }); + }); }, );