diff --git a/macos/Sources/GhosttyApp.swift b/macos/Sources/GhosttyApp.swift index 9226a722f..a68978c2b 100644 --- a/macos/Sources/GhosttyApp.swift +++ b/macos/Sources/GhosttyApp.swift @@ -23,6 +23,20 @@ struct GhosttyApp: App { TerminalView(app: ghostty.app!) .modifier(WindowObservationModifier()) } + }.commands { + CommandGroup(after: .newItem) { + Button("New Tab", action: newTab).keyboardShortcut("t", modifiers: [.command]) + } + } + } + + // Create a new tab in the currently active window + func newTab() { + guard let currentWindow = NSApp.keyWindow else { return } + guard let windowController = currentWindow.windowController else { return } + windowController.newWindowForTab(nil) + if let newWindow = NSApp.keyWindow, currentWindow != newWindow { + currentWindow.addTabbedWindow(newWindow, ordered: .above) } } } diff --git a/macos/Sources/TerminalView.swift b/macos/Sources/TerminalView.swift index 9ff166241..123388802 100644 --- a/macos/Sources/TerminalView.swift +++ b/macos/Sources/TerminalView.swift @@ -5,6 +5,7 @@ struct TerminalView: View { let app: ghostty_app_t @FocusState private var surfaceFocus: Bool @Environment(\.isKeyWindow) private var isKeyWindow: Bool + @Environment(\.openWindow) private var openWindow @State private var title: String = "Ghostty" // This is true if the terminal is considered "focused". The terminal is focused if diff --git a/src/App.zig b/src/App.zig index 948e409c1..a29f87330 100644 --- a/src/App.zig +++ b/src/App.zig @@ -219,6 +219,8 @@ fn newTab(self: *App, msg: Message.NewWindow) !void { return; } + // In embedded mode, it is up to the embedder to implement tabbing + // on their own. if (comptime build_config.artifact != .exe) { log.warn("tabbing is not supported in embedded mode", .{}); return;