Resync terminal portals after sidebar changes (#1253)

* Add regression test for portal ancestor shifts

* Resync terminal portals after sidebar changes

* Restore safeHelp view helper

* Fix portal geometry regression test harness
This commit is contained in:
Lawrence Chen 2026-03-12 02:46:30 -07:00 committed by GitHub
parent 292359f600
commit 8d5a1f611d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 100 additions and 1 deletions

View file

@ -7,6 +7,15 @@ struct Backport<Content> {
extension View {
var backport: Backport<Self> { Backport(content: self) }
@ViewBuilder
func safeHelp(_ text: String) -> some View {
if text.isEmpty {
self
} else {
self.help(text)
}
}
}
extension Scene {

View file

@ -2591,10 +2591,14 @@ struct ContentView: View {
if abs(sidebarState.persistedWidth - sanitized) > 0.5 {
sidebarState.persistedWidth = sanitized
}
// Sidebar width changes are pure SwiftUI layout updates, so portal-hosted
// terminals need an explicit post-layout geometry resync.
TerminalWindowPortalRegistry.scheduleExternalGeometrySynchronizeForAllWindows()
updateSidebarResizerBandState()
})
view = AnyView(view.onChange(of: sidebarState.isVisible) { _ in
TerminalWindowPortalRegistry.scheduleExternalGeometrySynchronizeForAllWindows()
updateSidebarResizerBandState()
})

View file

@ -724,7 +724,7 @@ final class WindowTerminalPortal: NSObject {
return frameInContainer.width > 1 && frameInContainer.height > 1
}
private func synchronizeAllEntriesFromExternalGeometryChange() {
fileprivate func synchronizeAllEntriesFromExternalGeometryChange() {
guard ensureInstalled() else { return }
synchronizeLayoutHierarchy()
synchronizeAllHostedViews(excluding: nil)
@ -1635,6 +1635,7 @@ final class WindowTerminalPortal: NSObject {
enum TerminalWindowPortalRegistry {
private static var portalsByWindowId: [ObjectIdentifier: WindowTerminalPortal] = [:]
private static var hostedToWindowId: [ObjectIdentifier: ObjectIdentifier] = [:]
private static var hasPendingExternalGeometrySyncForAllWindows = false
#if DEBUG
private static var blockedBindCount: Int = 0
private static var blockedBindReasons: [String: Int] = [:]
@ -1780,6 +1781,17 @@ enum TerminalWindowPortalRegistry {
portal.synchronizeHostedViewForAnchor(anchorView)
}
static func scheduleExternalGeometrySynchronizeForAllWindows() {
guard !Self.hasPendingExternalGeometrySyncForAllWindows else { return }
Self.hasPendingExternalGeometrySyncForAllWindows = true
DispatchQueue.main.async {
Self.hasPendingExternalGeometrySyncForAllWindows = false
for portal in Self.portalsByWindowId.values {
portal.synchronizeAllEntriesFromExternalGeometryChange()
}
}
}
static func hideHostedView(_ hostedView: GhosttySurfaceScrollView) {
let hostedId = ObjectIdentifier(hostedView)
guard let windowId = hostedToWindowId[hostedId],