From 8fa1ca3a4d6f3ec5368e6cd7ad6fd24f7d360d30 Mon Sep 17 00:00:00 2001 From: Austin Wang Date: Mon, 9 Mar 2026 17:24:58 -0700 Subject: [PATCH] Hide browser portal when terminal tab is active (#1130) --- Sources/Panels/BrowserPanel.swift | 6 ++++-- Sources/Panels/BrowserPanelView.swift | 19 ++++++++++++++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/Sources/Panels/BrowserPanel.swift b/Sources/Panels/BrowserPanel.swift index 31961ce2..aaad9f23 100644 --- a/Sources/Panels/BrowserPanel.swift +++ b/Sources/Panels/BrowserPanel.swift @@ -1838,8 +1838,9 @@ final class BrowserPanel: Panel, ObservableObject { return true } - func releasePortalHostIfOwned(hostId: ObjectIdentifier, reason: String) { - guard let current = activePortalHostLease, current.hostId == hostId else { return } + @discardableResult + func releasePortalHostIfOwned(hostId: ObjectIdentifier, reason: String) -> Bool { + guard let current = activePortalHostLease, current.hostId == hostId else { return false } activePortalHostLease = nil #if DEBUG dlog( @@ -1848,6 +1849,7 @@ final class BrowserPanel: Panel, ObservableObject { "inWin=\(current.inWindow ? 1 : 0) area=\(String(format: "%.1f", current.area))" ) #endif + return true } var displayIcon: String? { diff --git a/Sources/Panels/BrowserPanelView.swift b/Sources/Panels/BrowserPanelView.swift index 4f8ff9f5..98ae7485 100644 --- a/Sources/Panels/BrowserPanelView.swift +++ b/Sources/Panels/BrowserPanelView.swift @@ -4323,11 +4323,23 @@ struct WebViewRepresentable: NSViewRepresentable { let activePaneDropContext = coordinator.desiredPortalVisibleInUI ? paneDropContext : nil let activeSearchOverlay = coordinator.desiredPortalVisibleInUI ? searchOverlay : nil let portalAnchorView = panel.portalAnchorView + let portalHideReason = !isCurrentPaneOwner ? "lostPaneOwnership" : "hidden" + let didReleasePortalHost: Bool if !shouldAttachWebView || !isCurrentPaneOwner { - panel.releasePortalHostIfOwned( + didReleasePortalHost = panel.releasePortalHostIfOwned( hostId: hostId, - reason: !isCurrentPaneOwner ? "lostPaneOwnership" : "hidden" + reason: portalHideReason ) + // Only the host that currently owns the portal is allowed to hide it. + // Older keep-alive hosts can still receive updates after a new owner binds. + if didReleasePortalHost { + BrowserWindowPortalRegistry.hide( + webView: webView, + source: "viewStateChanged.\(portalHideReason)" + ) + } + } else { + didReleasePortalHost = false } let portalHostAccepted = shouldAttachWebView && @@ -4345,7 +4357,8 @@ struct WebViewRepresentable: NSViewRepresentable { "browser.portal.owner.skip panel=\(panel.id.uuidString.prefix(5)) " + "viewPane=\(paneId.id.uuidString.prefix(5)) " + "currentPane=\(paneDropContext?.paneId.id.uuidString.prefix(5) ?? "nil") " + - "host=\(Self.objectID(host)) hostInWin=\(host.window != nil ? 1 : 0)" + "host=\(Self.objectID(host)) hostInWin=\(host.window != nil ? 1 : 0) " + + "released=\(didReleasePortalHost ? 1 : 0)" ) } #endif