Fix browser freeze after pane split by reattaching WKWebView rendering state (#1852)

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) <noreply@anthropic.com>
This commit is contained in:
Apptah 2026-03-23 09:05:39 +08:00 committed by GitHub
parent 5be9edaf5e
commit 5ced3134d3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -6098,6 +6098,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
@ -6129,6 +6133,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
@ -6166,6 +6174,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
}