diff --git a/macos/Sources/Features/Primary Window/PrimaryWindow.swift b/macos/Sources/Features/Primary Window/PrimaryWindow.swift index 7b2e7c08e..85ca49601 100644 --- a/macos/Sources/Features/Primary Window/PrimaryWindow.swift +++ b/macos/Sources/Features/Primary Window/PrimaryWindow.swift @@ -23,12 +23,18 @@ class PrimaryWindow: NSWindow { backing: .buffered, defer: false) window.center() + window.contentView = NSHostingView(rootView: PrimaryView( ghostty: ghostty, appDelegate: appDelegate, focusedSurfaceWrapper: window.focusedSurfaceWrapper)) + + // We do want to cascade when new windows are created window.windowController?.shouldCascadeWindows = true + + // A default title. This should be overwritten quickly by the Ghostty core. window.title = "Ghostty 👻" + return window } diff --git a/macos/Sources/Features/Primary Window/PrimaryWindowController.swift b/macos/Sources/Features/Primary Window/PrimaryWindowController.swift index c0e1961c2..751bff7a8 100644 --- a/macos/Sources/Features/Primary Window/PrimaryWindowController.swift +++ b/macos/Sources/Features/Primary Window/PrimaryWindowController.swift @@ -6,9 +6,16 @@ class PrimaryWindowController: NSWindowController { // of each other. static var lastCascadePoint = NSPoint(x: 0, y: 0) - static func create(ghosttyApp: Ghostty.AppState, appDelegate: AppDelegate) -> PrimaryWindowController { - let window = PrimaryWindow.create(ghostty: ghosttyApp, appDelegate: appDelegate) - lastCascadePoint = window.cascadeTopLeft(from: lastCascadePoint) - return PrimaryWindowController(window: window) + // This is used to programmatically control tabs. + weak var windowManager: PrimaryWindowManager? + + // This is required for the "+" button to show up in the tab bar to add a + // new tab. + override func newWindowForTab(_ sender: Any?) { + // TODO: specify our window so the tab is created in the proper window + // guard let window = self.window else { preconditionFailure("Expected window to be loaded") } + + guard let manager = self.windowManager else { return } + manager.addNewTab() } } diff --git a/macos/Sources/Features/Primary Window/PrimaryWindowManager.swift b/macos/Sources/Features/Primary Window/PrimaryWindowManager.swift index 67f32e82f..81b4f1b92 100644 --- a/macos/Sources/Features/Primary Window/PrimaryWindowManager.swift +++ b/macos/Sources/Features/Primary Window/PrimaryWindowManager.swift @@ -17,6 +17,11 @@ class PrimaryWindowManager { let window: NSWindow let closePublisher: AnyCancellable } + + // Keep track of the last point that our window was launched at so that new + // windows "cascade" over each other and don't just launch directly on top + // of each other. + static var lastCascadePoint = NSPoint(x: 0, y: 0) private var ghostty: Ghostty.AppState private var managedWindows: [ManagedWindow] = [] @@ -58,7 +63,11 @@ class PrimaryWindowManager { private func createWindowController() -> PrimaryWindowController? { guard let appDelegate = NSApplication.shared.delegate as? AppDelegate else { return nil } - return PrimaryWindowController.create(ghosttyApp: self.ghostty, appDelegate: appDelegate) + let window = PrimaryWindow.create(ghostty: ghostty, appDelegate: appDelegate) + Self.lastCascadePoint = window.cascadeTopLeft(from: Self.lastCascadePoint) + let controller = PrimaryWindowController(window: window) + controller.windowManager = self + return controller } private func addManagedWindow(windowController: PrimaryWindowController) -> ManagedWindow? {