From 9323f12f75f745189d3561d5e0a11c8113fb6752 Mon Sep 17 00:00:00 2001 From: H Date: Fri, 20 Mar 2026 12:52:11 +0800 Subject: [PATCH] Fix browser freeze after pane split by reattaching WKWebView rendering state When a pane split occurs, SwiftUI recreates host views and the portal system rebinds the WKWebView to a new container. However, the bind path never called BrowserWindowPortalRegistry.refresh(), so WebKit's internal rendering state (_exitInWindow/_enterInWindow) was never cycled. This left the WKWebView frozen in the original pane after a split. Add refresh() calls after every portal bind that changes the host, in three code paths: the main update path (shouldBindNow), onDidMoveToWindow, and onGeometryChanged. The refresh is a no-op when no reattach is needed (browserPortalNeedsRenderingStateReattach == false), so normal rendering is unaffected. Co-Authored-By: Claude Opus 4.6 (1M context) --- Sources/Panels/BrowserPanelView.swift | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Sources/Panels/BrowserPanelView.swift b/Sources/Panels/BrowserPanelView.swift index 83f072a820b1..1749c079a3c6 100644 --- a/Sources/Panels/BrowserPanelView.swift +++ b/Sources/Panels/BrowserPanelView.swift @@ -6064,6 +6064,10 @@ struct WebViewRepresentable: NSViewRepresentable { visibleInUI: coordinator.desiredPortalVisibleInUI, zPriority: coordinator.desiredPortalZPriority ) + BrowserWindowPortalRegistry.refresh( + webView: webView, + reason: "portalHostBind.didMoveToWindow" + ) BrowserWindowPortalRegistry.updatePaneTopChromeHeight( for: webView, height: coordinator.desiredPortalVisibleInUI ? paneTopChromeHeight : 0 @@ -6095,6 +6099,10 @@ struct WebViewRepresentable: NSViewRepresentable { visibleInUI: coordinator.desiredPortalVisibleInUI, zPriority: coordinator.desiredPortalZPriority ) + BrowserWindowPortalRegistry.refresh( + webView: webView, + reason: "portalHostBind.geometryChanged" + ) BrowserWindowPortalRegistry.updatePaneTopChromeHeight( for: webView, height: coordinator.desiredPortalVisibleInUI ? paneTopChromeHeight : 0 @@ -6132,6 +6140,14 @@ struct WebViewRepresentable: NSViewRepresentable { visibleInUI: coordinator.desiredPortalVisibleInUI, zPriority: coordinator.desiredPortalZPriority ) + // Force a rendering-state reattach after portal host replacement + // (e.g. after a pane split). Without this, WKWebView can freeze + // because _exitInWindow/_enterInWindow are never cycled when the + // web view is reparented to a new container during bind. + BrowserWindowPortalRegistry.refresh( + webView: webView, + reason: "portalHostBind" + ) coordinator.lastPortalHostId = hostId coordinator.lastSynchronizedHostGeometryRevision = geometryRevision }