mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
new_tab action
This commit is contained in:
55
src/App.zig
55
src/App.zig
@ -95,7 +95,7 @@ pub fn create(alloc: Allocator, config: *const Config) !*App {
|
||||
errdefer if (comptime builtin.target.isDarwin()) app.darwin.deinit();
|
||||
|
||||
// Create the first window
|
||||
try app.newWindow(.{});
|
||||
_ = try app.newWindow(.{});
|
||||
|
||||
return app;
|
||||
}
|
||||
@ -148,7 +148,8 @@ fn drainMailbox(self: *App) !void {
|
||||
while (drain.next()) |message| {
|
||||
log.debug("mailbox message={s}", .{@tagName(message)});
|
||||
switch (message) {
|
||||
.new_window => |msg| try self.newWindow(msg),
|
||||
.new_window => |msg| _ = try self.newWindow(msg),
|
||||
.new_tab => |msg| try self.newTab(msg),
|
||||
.quit => try self.setQuit(),
|
||||
.window_message => |msg| try self.windowMessage(msg.window, msg.message),
|
||||
}
|
||||
@ -156,7 +157,7 @@ fn drainMailbox(self: *App) !void {
|
||||
}
|
||||
|
||||
/// Create a new window
|
||||
fn newWindow(self: *App, msg: Message.NewWindow) !void {
|
||||
fn newWindow(self: *App, msg: Message.NewWindow) !*Window {
|
||||
var window = try Window.create(self.alloc, self, self.config);
|
||||
errdefer window.destroy();
|
||||
try self.windows.append(self.alloc, window);
|
||||
@ -164,6 +165,33 @@ fn newWindow(self: *App, msg: Message.NewWindow) !void {
|
||||
|
||||
// Set initial font size if given
|
||||
if (msg.font_size) |size| window.setFontSize(size);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
/// Create a new tab in the parent window
|
||||
fn newTab(self: *App, msg: Message.NewWindow) !void {
|
||||
if (comptime !builtin.target.isDarwin()) {
|
||||
log.warn("tabbing is not supported on this platform", .{});
|
||||
return;
|
||||
}
|
||||
|
||||
const parent = msg.parent orelse {
|
||||
log.warn("parent must be set in new_tab message", .{});
|
||||
return;
|
||||
};
|
||||
|
||||
// If the parent was closed prior to us handling the message, we do nothing.
|
||||
if (!self.hasWindow(parent)) {
|
||||
log.warn("new_tab parent is gone, not launching a new tab", .{});
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the new window
|
||||
const window = try self.newWindow(msg);
|
||||
|
||||
// Add the window to our parent tab group
|
||||
parent.addWindow(window);
|
||||
}
|
||||
|
||||
/// Start quitting
|
||||
@ -182,22 +210,32 @@ fn windowMessage(self: *App, win: *Window, msg: Window.Message) !void {
|
||||
// We want to ensure our window is still active. Window messages
|
||||
// are quite rare and we normally don't have many windows so we do
|
||||
// a simple linear search here.
|
||||
for (self.windows.items) |window| {
|
||||
if (window == win) {
|
||||
if (self.hasWindow(win)) {
|
||||
try win.handleMessage(msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Window was not found, it probably quit before we handled the message.
|
||||
// Not a problem.
|
||||
}
|
||||
|
||||
fn hasWindow(self: *App, win: *Window) bool {
|
||||
for (self.windows.items) |window| {
|
||||
if (window == win) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// The message types that can be sent to the app thread.
|
||||
pub const Message = union(enum) {
|
||||
/// Create a new terminal window.
|
||||
new_window: NewWindow,
|
||||
|
||||
/// Create a new tab within the tab group of the focused window.
|
||||
/// This does nothing if we're on a platform or using a window
|
||||
/// environment that doesn't support tabs.
|
||||
new_tab: NewWindow,
|
||||
|
||||
/// Quit
|
||||
quit: void,
|
||||
|
||||
@ -208,6 +246,9 @@ pub const Message = union(enum) {
|
||||
},
|
||||
|
||||
const NewWindow = struct {
|
||||
/// The parent window, only used for new tabs.
|
||||
parent: ?*Window = null,
|
||||
|
||||
/// The font size to create the window with or null to default to
|
||||
/// the configuration amount.
|
||||
font_size: ?font.face.DesiredSize = null,
|
||||
|
@ -542,6 +542,18 @@ pub fn shouldClose(self: Window) bool {
|
||||
return self.window.shouldClose();
|
||||
}
|
||||
|
||||
/// Add a window to the tab group of this window.
|
||||
pub fn addWindow(self: Window, other: *Window) void {
|
||||
assert(builtin.target.isDarwin());
|
||||
|
||||
const NSWindowOrderingMode = enum(isize) { below = -1, out = 0, above = 1 };
|
||||
const nswindow = objc.Object.fromId(glfwNative.getCocoaWindow(self.window).?);
|
||||
nswindow.msgSend(void, objc.sel("addTabbedWindow:ordered:"), .{
|
||||
objc.Object.fromId(glfwNative.getCocoaWindow(other.window).?),
|
||||
NSWindowOrderingMode.above,
|
||||
});
|
||||
}
|
||||
|
||||
/// Called from the app thread to handle mailbox messages to our specific
|
||||
/// window.
|
||||
pub fn handleMessage(self: *Window, msg: Message) !void {
|
||||
@ -953,6 +965,20 @@ fn keyCallback(
|
||||
win.app.wakeup();
|
||||
},
|
||||
|
||||
.new_tab => {
|
||||
_ = win.app.mailbox.push(.{
|
||||
.new_tab = .{
|
||||
.parent = win,
|
||||
|
||||
.font_size = if (win.config.@"window-inherit-font-size")
|
||||
win.font_size
|
||||
else
|
||||
null,
|
||||
},
|
||||
}, .{ .instant = {} });
|
||||
win.app.wakeup();
|
||||
},
|
||||
|
||||
.close_window => win.window.setShouldClose(true),
|
||||
|
||||
.quit => {
|
||||
|
@ -217,7 +217,12 @@ pub const Config = struct {
|
||||
.{ .key = .w, .mods = .{ .super = true } },
|
||||
.{ .close_window = {} },
|
||||
);
|
||||
if (builtin.os.tag == .macos) {
|
||||
if (comptime builtin.target.isDarwin()) {
|
||||
try result.keybind.set.put(
|
||||
alloc,
|
||||
.{ .key = .t, .mods = .{ .super = true } },
|
||||
.{ .new_tab = {} },
|
||||
);
|
||||
try result.keybind.set.put(
|
||||
alloc,
|
||||
.{ .key = .q, .mods = .{ .super = true } },
|
||||
|
@ -144,7 +144,10 @@ pub const Action = union(enum) {
|
||||
/// Open a new window
|
||||
new_window: void,
|
||||
|
||||
/// Close the current window
|
||||
/// Open a new tab
|
||||
new_tab: void,
|
||||
|
||||
/// Close the current window or tab
|
||||
close_window: void,
|
||||
|
||||
/// Quit ghostty
|
||||
|
Reference in New Issue
Block a user