From 7f36e7c3f2946902cd11b28203cccda81892f241 Mon Sep 17 00:00:00 2001 From: Bryan Lee <38807139+liby@users.noreply.github.com> Date: Wed, 5 Feb 2025 13:30:35 +0800 Subject: [PATCH] Improve split and tab navigation behavior --- macos/Sources/Ghostty/Ghostty.App.swift | 18 +++++++++++++++--- macos/Sources/Ghostty/Ghostty.SplitNode.swift | 9 +++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/macos/Sources/Ghostty/Ghostty.App.swift b/macos/Sources/Ghostty/Ghostty.App.swift index 43c0f245a..bcaa6c63f 100644 --- a/macos/Sources/Ghostty/Ghostty.App.swift +++ b/macos/Sources/Ghostty/Ghostty.App.swift @@ -107,7 +107,7 @@ extension Ghostty { deinit { // This will force the didSet callbacks to run which free. self.app = nil - + #if os(macOS) NotificationCenter.default.removeObserver(self) #endif @@ -773,8 +773,20 @@ extension Ghostty { return case GHOSTTY_TARGET_SURFACE: - guard let surface = target.target.surface else { return } - guard let surfaceView = self.surfaceView(from: surface) else { return } + guard let surface = target.target.surface, + let surfaceView = self.surfaceView(from: surface), + let window = surfaceView.window, + let controller = window.windowController as? TerminalController, + let surfaceTree = controller.surfaceTree else { return } + + if !surfaceTree.isViewInSplit(surfaceView) && + (direction == GHOSTTY_GOTO_SPLIT_NEXT || direction == GHOSTTY_GOTO_SPLIT_PREVIOUS) { + let tabDirection: ghostty_action_goto_tab_e = direction == GHOSTTY_GOTO_SPLIT_NEXT ? + GHOSTTY_GOTO_TAB_NEXT : GHOSTTY_GOTO_TAB_PREVIOUS + gotoTab(app, target: target, tab: tabDirection) + return + } + NotificationCenter.default.post( name: Notification.ghosttyFocusSplit, object: surfaceView, diff --git a/macos/Sources/Ghostty/Ghostty.SplitNode.swift b/macos/Sources/Ghostty/Ghostty.SplitNode.swift index 899825d37..4188849b4 100644 --- a/macos/Sources/Ghostty/Ghostty.SplitNode.swift +++ b/macos/Sources/Ghostty/Ghostty.SplitNode.swift @@ -130,6 +130,15 @@ extension Ghostty { } } + /// Returns true if the view is in a split (not a single leaf) + func isViewInSplit(_ view: SurfaceView) -> Bool { + if case .split = self { + return contains(view: view) + } + return false + } + + /// Find a surface view by UUID. func findUUID(uuid: UUID) -> SurfaceView? { switch (self) {