diff --git a/macos/Sources/ContentView.swift b/macos/Sources/ContentView.swift index eb938cc2e..d53951d47 100644 --- a/macos/Sources/ContentView.swift +++ b/macos/Sources/ContentView.swift @@ -26,6 +26,9 @@ struct ContentView: View { NSApplication.shared.reply(toApplicationShouldTerminate: true) } case .ready: + let center = NotificationCenter.default + let gotoTab = center.publisher(for: Ghostty.Notification.ghosttyGotoTab) + let confirmQuitting = Binding(get: { self.appDelegate.confirmQuit && (self.window?.isKeyWindow ?? false) }, set: { @@ -35,6 +38,7 @@ struct ContentView: View { Ghostty.TerminalSplit(onClose: Self.closeWindow) .ghosttyApp(ghostty.app!) .background(WindowAccessor(window: $window)) + .onReceive(gotoTab) { onGotoTab(notification: $0) } .confirmationDialog( "Quit Ghostty?", isPresented: confirmQuitting) { @@ -57,4 +61,27 @@ struct ContentView: View { guard let currentWindow = NSApp.keyWindow else { return } currentWindow.close() } + + private func onGotoTab(notification: SwiftUI.Notification) { + // Notification center indiscriminately sends to every subscriber (makes sense) + // but we only want to process this once. In order to process it once lets only + // handle it if we're the focused window. + guard let window = self.window else { return } + guard window.isKeyWindow else { return } + + // Get the tab index from the notification + guard let tabIndexAny = notification.userInfo?[Ghostty.Notification.GotoTabKey] else { return } + guard let tabIndex = tabIndexAny as? Int32 else { return } + + guard let windowController = window.windowController else { return } + guard let tabGroup = windowController.window?.tabGroup else { return } + let tabbedWindows = tabGroup.windows + + // Tabs are 0-indexed here, so we subtract one from the key the user hit. + let adjustedIndex = Int(tabIndex - 1); + guard adjustedIndex >= 0 && adjustedIndex < tabbedWindows.count else { return } + + let targetWindow = tabbedWindows[adjustedIndex] + targetWindow.makeKeyAndOrderFront(nil) + } } diff --git a/macos/Sources/GhosttyApp.swift b/macos/Sources/GhosttyApp.swift index b9b948f86..85845dd02 100644 --- a/macos/Sources/GhosttyApp.swift +++ b/macos/Sources/GhosttyApp.swift @@ -17,13 +17,8 @@ struct GhosttyApp: App { @FocusedValue(\.ghosttySurfaceView) private var focusedSurface var body: some Scene { - let center = NotificationCenter.default - let gotoTab = center.publisher(for: Ghostty.Notification.ghosttyGotoTab) - WindowGroup { ContentView(ghostty: ghostty) - // TODO: This is wrong. This fires for every open tab. - .onReceive(gotoTab) { onGotoTab(notification: $0) } } .backport.defaultSize(width: 800, height: 600) @@ -107,26 +102,6 @@ struct GhosttyApp: App { guard let surface = surfaceView.surface else { return } ghostty.splitMoveFocus(surface: surface, direction: direction) } - - private func onGotoTab(notification: SwiftUI.Notification) { - // Get the tab index from the notification - guard let tabIndexAny = notification.userInfo?[Ghostty.Notification.GotoTabKey] else { return } - guard let tabIndex = tabIndexAny as? Int32 else { return } - - guard let currentWindow = NSApp.keyWindow else { return } - guard let windowController = currentWindow.windowController else { return } - guard let tabGroup = windowController.window?.tabGroup else { return } - - let tabbedWindows = tabGroup.windows - - // Tabs are 0-indexed here, so we subtract one from the key the user hit. - let adjustedIndex = Int(tabIndex - 1); - guard adjustedIndex >= 0 && adjustedIndex < tabbedWindows.count else { return } - - let targetWindow = tabbedWindows[adjustedIndex] - targetWindow.makeKeyAndOrderFront(nil) - } - } class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {