diff --git a/macos/Sources/Features/Terminal/TerminalController.swift b/macos/Sources/Features/Terminal/TerminalController.swift index dac57a69e..e744e7c38 100644 --- a/macos/Sources/Features/Terminal/TerminalController.swift +++ b/macos/Sources/Features/Terminal/TerminalController.swift @@ -57,9 +57,6 @@ class TerminalController: BaseTerminalController, TabGroupCloseCoordinator.Contr /// The notification cancellable for focused surface property changes. private var surfaceAppearanceCancellables: Set = [] - /// The KVO cancellable for `window.contentView.intrinsicContentSize` changes. - private var contentIntrinsicContentSizeCancellable: AnyCancellable? - /// This will be set to the initial frame of the window from the xib on load. private var initialFrame: NSRect? @@ -1041,10 +1038,9 @@ class TerminalController: BaseTerminalController, TabGroupCloseCoordinator.Contr } // Initialize our content view to the SwiftUI root - let contentView = TerminalViewContainer { + window.contentView = TerminalViewContainer { TerminalView(ghostty: ghostty, viewModel: self, delegate: self) } - window.contentView = contentView // If we have a default size, we want to apply it. if let defaultSize { @@ -1053,21 +1049,17 @@ class TerminalController: BaseTerminalController, TabGroupCloseCoordinator.Contr // Frames can be applied immediately defaultSize.apply(to: window) - case let .contentIntrinsicSize(minSize): - // We wait for the first proper content intrinsic size, - // after AppKit laid out our SwiftUI views. - contentIntrinsicContentSizeCancellable = contentView.publisher(for: \.intrinsicContentSize) - .filter { $0.width >= minSize.width && $0.height >= minSize.height } - .first() - .sink { [weak self, weak window] _ in - guard let self, let window else { return } - defaultSize.apply(to: window) - if let screen = window.screen ?? NSScreen.main { - let frame = self.adjustForWindowPosition(frame: window.frame, on: screen) - window.setFrameOrigin(frame.origin) - } - contentIntrinsicContentSizeCancellable = nil + case .contentIntrinsicSize: + // Content intrinsic size requires a short delay so that AppKit + // can layout our SwiftUI views. + DispatchQueue.main.asyncAfter(deadline: .now() + .microseconds(10_000)) { [weak self, weak window] in + guard let self, let window else { return } + defaultSize.apply(to: window) + if let screen = window.screen ?? NSScreen.main { + let frame = self.adjustForWindowPosition(frame: window.frame, on: screen) + window.setFrameOrigin(frame.origin) } + } } } @@ -1568,21 +1560,6 @@ class TerminalController: BaseTerminalController, TabGroupCloseCoordinator.Contr self.windowPositionX = config.windowPositionX self.windowPositionY = config.windowPositionY } - - /// The minimum size a window can be resized to as of macOS 26.3, it should cover most cases. - /// - /// We use this to filter incorrect intrinsicContentSize values when positioning a new window. - fileprivate var minimumWindowSize: CGSize { - switch macosTitlebarStyle { - case "native", "transparent": - CGSize(width: 105 + 1, height: 33 + 1) - case "tabs": - CGSize(width: 90 + 1, height: 48 + 1) - // hidden or others - default: - CGSize(width: 27 + 1, height: 40 + 1) - } - } } } @@ -1630,7 +1607,7 @@ extension TerminalController { case frame(NSRect) /// A content size, set with `window.setContentSize` - case contentIntrinsicSize(_ minimum: CGSize) + case contentIntrinsicSize func isChanged(for window: NSWindow) -> Bool { switch self { @@ -1667,7 +1644,7 @@ extension TerminalController { } else if focusedSurface?.initialSize != nil { // Initial size as requested by the configuration (e.g. `window-width`) // takes next priority. - return .contentIntrinsicSize(derivedConfig.minimumWindowSize) + return .contentIntrinsicSize } else if let initialFrame { // The initial frame we had when we started otherwise. return .frame(initialFrame)