Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Sources/Panels/BrowserPanelView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6064,6 +6064,10 @@ struct WebViewRepresentable: NSViewRepresentable {
visibleInUI: coordinator.desiredPortalVisibleInUI,
zPriority: coordinator.desiredPortalZPriority
)
BrowserWindowPortalRegistry.refresh(
webView: webView,
reason: "portalHostBind.didMoveToWindow"
)
Comment on lines +6067 to +6070

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 onDidMoveToWindow refresh fires unconditionally on every window-entry event

Unlike the onGeometryChanged handler (which guards with coordinator.lastPortalHostId != hostId || !isWebView(boundTo:) before calling bind + refresh), this path calls bind() + refresh() on every invocation that passes the generation/ownership/window guards — even when the host hasn't changed.

refreshHostedWebViewPresentation schedules three layout + browserPortalReattachRenderingState passes (immediate, async, and asyncAfter +30 ms), guarded only by containerView.isHidden. If the container is visible at the moment onDidMoveToWindow fires (e.g., after SwiftUI recreates the host view during a workspace transition while the pane is in view), all three passes run unnecessarily.

Consider adding an early-exit guard consistent with onGeometryChanged:

Suggested change
BrowserWindowPortalRegistry.refresh(
webView: webView,
reason: "portalHostBind.didMoveToWindow"
)
Self.installPortalAnchorView(portalAnchorView, in: host)
let hostId = ObjectIdentifier(host)
let needsRebind = coordinator.lastPortalHostId != hostId ||
!BrowserWindowPortalRegistry.isWebView(webView, boundTo: portalAnchorView)
BrowserWindowPortalRegistry.bind(
webView: webView,
to: portalAnchorView,
visibleInUI: coordinator.desiredPortalVisibleInUI,
zPriority: coordinator.desiredPortalZPriority
)
if needsRebind {
BrowserWindowPortalRegistry.refresh(
webView: webView,
reason: "portalHostBind.didMoveToWindow"
)
}

This mirrors the guard already present in onGeometryChanged and avoids the three-pass refresh cycle on ordinary re-presentations where the host–anchor binding is already correct.

BrowserWindowPortalRegistry.updatePaneTopChromeHeight(
for: webView,
height: coordinator.desiredPortalVisibleInUI ? paneTopChromeHeight : 0
Expand Down Expand Up @@ -6095,6 +6099,10 @@ struct WebViewRepresentable: NSViewRepresentable {
visibleInUI: coordinator.desiredPortalVisibleInUI,
zPriority: coordinator.desiredPortalZPriority
)
BrowserWindowPortalRegistry.refresh(
webView: webView,
reason: "portalHostBind.geometryChanged"
)
Comment on lines +6102 to +6105

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Missing explanatory comment in onGeometryChanged refresh path

The shouldBindNow path has a detailed comment explaining why refresh() is required (cycling _exitInWindow/_enterInWindow after a pane split reparents the WKWebView). The same rationale applies here — a new hostId means the web view was reparented — but there's no comment, which can make this call look like unnecessary churn to a future reader.

Suggested change
BrowserWindowPortalRegistry.refresh(
webView: webView,
reason: "portalHostBind.geometryChanged"
)
BrowserWindowPortalRegistry.refresh(
webView: webView,
reason: "portalHostBind.geometryChanged"
)
// 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.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

BrowserWindowPortalRegistry.updatePaneTopChromeHeight(
for: webView,
height: coordinator.desiredPortalVisibleInUI ? paneTopChromeHeight : 0
Expand Down Expand Up @@ -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
}
Expand Down