From df779d32eaf3d5d3ac3bcd0b9edb0c88cafcea36 Mon Sep 17 00:00:00 2001 From: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com> Date: Mon, 23 Feb 2026 05:54:02 -0800 Subject: [PATCH] Portal: hide terminal view before hidden-frame updates --- Sources/TerminalWindowPortal.swift | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/Sources/TerminalWindowPortal.swift b/Sources/TerminalWindowPortal.swift index 07831c71..0fbde41d 100644 --- a/Sources/TerminalWindowPortal.swift +++ b/Sources/TerminalWindowPortal.swift @@ -870,6 +870,22 @@ final class WindowTerminalPortal: NSObject { ) } #endif + + // Hide before updating the frame when this entry should not be visible. + // This avoids a one-frame flash of unrendered terminal background when a portal + // briefly transitions through offscreen/tiny geometry during rapid split churn. + if shouldHide, !hostedView.isHidden { +#if DEBUG + dlog( + "portal.hidden hosted=\(portalDebugToken(hostedView)) value=1 " + + "visibleInUI=\(entry.visibleInUI ? 1 : 0) anchorHidden=\(anchorHidden ? 1 : 0) " + + "tiny=\(tinyFrame ? 1 : 0) finite=\(hasFiniteFrame ? 1 : 0) " + + "outside=\(outsideHostBounds ? 1 : 0) frame=\(portalDebugFrame(frameInHost))" + ) +#endif + hostedView.isHidden = true + } + if !Self.rectApproximatelyEqual(oldFrame, frameInHost) { CATransaction.begin() CATransaction.setDisableActions(true) @@ -877,21 +893,22 @@ final class WindowTerminalPortal: NSObject { CATransaction.commit() if abs(oldFrame.size.width - frameInHost.size.width) > 0.5 || - abs(oldFrame.size.height - frameInHost.size.height) > 0.5 { + abs(oldFrame.size.height - frameInHost.size.height) > 0.5, + !shouldHide { hostedView.reconcileGeometryNow() } } - if hostedView.isHidden != shouldHide { + if !shouldHide, hostedView.isHidden { #if DEBUG dlog( - "portal.hidden hosted=\(portalDebugToken(hostedView)) value=\(shouldHide ? 1 : 0) " + + "portal.hidden hosted=\(portalDebugToken(hostedView)) value=0 " + "visibleInUI=\(entry.visibleInUI ? 1 : 0) anchorHidden=\(anchorHidden ? 1 : 0) " + "tiny=\(tinyFrame ? 1 : 0) finite=\(hasFiniteFrame ? 1 : 0) " + "outside=\(outsideHostBounds ? 1 : 0) frame=\(portalDebugFrame(frameInHost))" ) #endif - hostedView.isHidden = shouldHide + hostedView.isHidden = false } ensureDividerOverlayOnTop()