macOS: implement move_tab_to_new_window

The action and its keybind exist, and GTK implements them, but macOS had no
handler so the binding did nothing there. AppKit already has the command for
window tabs, so this forwards to it.

A window that isn't in a tab group, or is alone in one, is already a window of
its own, so there is nothing to move and the action reports it did nothing.

Implements the remaining macOS half of #2630.
This commit is contained in:
Pedro Augusto
2026-09-08 19:43:35 +01:00
parent 44f2a44df7
commit 1a8f331f16
2 changed files with 28 additions and 3 deletions

View File

@@ -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,

View File

@@ -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.