From 7c98f991dbb33c58be1fd44845cc190f2671539a Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 4 Aug 2023 17:45:57 -0700 Subject: [PATCH] macos: new tab menu/shortcut works even if no windows are present --- macos/Sources/AppDelegate.swift | 8 ++++-- .../Primary Window/PrimaryWindowManager.swift | 27 ++++++++++--------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/macos/Sources/AppDelegate.swift b/macos/Sources/AppDelegate.swift index a986eb423..836ac7467 100644 --- a/macos/Sources/AppDelegate.swift +++ b/macos/Sources/AppDelegate.swift @@ -76,9 +76,13 @@ class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject { } @IBAction func newTab(_ sender: Any?) { - windowManager.addNewTab() + if let existingWindow = windowManager.mainWindow { + windowManager.addNewTab(to: existingWindow) + } else { + windowManager.addNewWindow() + } } - + @IBAction func closeWindow(_ sender: Any) { guard let currentWindow = NSApp.keyWindow else { return } currentWindow.close() diff --git a/macos/Sources/Features/Primary Window/PrimaryWindowManager.swift b/macos/Sources/Features/Primary Window/PrimaryWindowManager.swift index c4e6c93e6..16b241070 100644 --- a/macos/Sources/Features/Primary Window/PrimaryWindowManager.swift +++ b/macos/Sources/Features/Primary Window/PrimaryWindowManager.swift @@ -22,6 +22,21 @@ class PrimaryWindowManager { // windows "cascade" over each other and don't just launch directly on top // of each other. static var lastCascadePoint = NSPoint(x: 0, y: 0) + + /// Returns the main window of the managed window stack. + /// Falls back the first element if no window is main. Note that this would + /// likely be an internal inconsistency we gracefully handle here. + var mainWindow: NSWindow? { + let mainManagedWindow = managedWindows + .first { $0.window.isMainWindow } + + // In case we run into the inconsistency, let it crash in debug mode so we + // can fix our window management setup to prevent this from happening. + assert(mainManagedWindow != nil || managedWindows.isEmpty) + + return (mainManagedWindow ?? managedWindows.first) + .map { $0.window } + } private var ghostty: Ghostty.AppState private var managedWindows: [ManagedWindow] = [] @@ -46,24 +61,12 @@ class PrimaryWindowManager { newWindow.makeKeyAndOrderFront(nil) } - func addNewTab() { - guard let existingWindow = mainWindow() else { return } - addNewTab(to: existingWindow) - } - func addNewTab(to window: NSWindow) { guard let controller = createWindowController() else { return } guard let newWindow = addManagedWindow(windowController: controller)?.window else { return } window.addTabbedWindow(newWindow, ordered: .above) newWindow.makeKeyAndOrderFront(nil) } - - /// Returns the main window of the managed window stack. - /// Falls back the first element if no window is main. - private func mainWindow() -> NSWindow? { - let mainManagedWindow = managedWindows.first { $0.window.isMainWindow } - return (mainManagedWindow ?? managedWindows.first).map { $0.window } - } private func createWindowController() -> PrimaryWindowController? { guard let appDelegate = NSApplication.shared.delegate as? AppDelegate else { return nil }