diff --git a/macos/Sources/Ghostty/Ghostty.App.swift b/macos/Sources/Ghostty/Ghostty.App.swift index bf06e3ef7..5e7674c79 100644 --- a/macos/Sources/Ghostty/Ghostty.App.swift +++ b/macos/Sources/Ghostty/Ghostty.App.swift @@ -621,6 +621,9 @@ extension Ghostty { case GHOSTTY_ACTION_MOVE_TAB: return moveTab(app, target: target, move: action.action.move_tab) + case GHOSTTY_ACTION_MOVE_TAB_TO_NEW_WINDOW: + return moveTabToNewWindow(app, target: target) + case GHOSTTY_ACTION_GOTO_TAB: return gotoTab(app, target: target, tab: action.action.goto_tab) @@ -1278,6 +1281,31 @@ extension Ghostty { return true } + private static func moveTabToNewWindow( + _ app: ghostty_app_t, + target: ghostty_target_s) -> Bool { + switch target.tag { + case GHOSTTY_TARGET_APP: + Ghostty.logger.warning("move tab to new window does nothing with an app target") + return false + + case GHOSTTY_TARGET_SURFACE: + guard let surface = target.target.surface else { return false } + guard let surfaceView = self.surfaceView(from: surface) else { return false } + + // See gotoTab for notes on this check. A lone tab is already + // a window of its own, so there is nothing to move. + guard (surfaceView.window?.tabGroup?.windows.count ?? 0) > 1 else { return false } + + surfaceView.window?.moveTabToNewWindow(nil) + + default: + assertionFailure() + } + + return true + } + private static func gotoTab( _ app: ghostty_app_t, target: ghostty_target_s, diff --git a/src/input/Binding.zig b/src/input/Binding.zig index 82b4bc8b8..6f2cc3136 100644 --- a/src/input/Binding.zig +++ b/src/input/Binding.zig @@ -588,9 +588,6 @@ pub const Action = union(enum) { move_tab: isize, /// Move a tab to a new window. - /// - /// Only implemented on Linux, but there's a native tab menu provided by - /// macOS. move_tab_to_new_window, /// Toggle the tab overview.