mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-04-21 23:05:20 +00:00
parameterize close_tab
- Add mode (`this`/`other`) parameter to `close_tab` keybind/apprt action. - Keybinds will default to `this` if not specified, eliminating backward compatibility issues (`keybind=x=close_tab` === `keybind=x=close_tab:this`). - Remove `close_other_tabs` keybind and apprt action.
This commit is contained in:
@@ -83,12 +83,9 @@ pub const Action = union(Key) {
|
||||
/// the tab should be opened in a new window.
|
||||
new_tab,
|
||||
|
||||
/// Closes the tab belonging to the currently focused split.
|
||||
close_tab,
|
||||
|
||||
/// Closes all tabs in the current window other than the currently
|
||||
/// focused tab.
|
||||
close_other_tabs,
|
||||
/// Closes the tab belonging to the currently focused split, or all other
|
||||
/// tabs, depending on the mode.
|
||||
close_tab: CloseTabMode,
|
||||
|
||||
/// Create a new split. The value determines the location of the split
|
||||
/// relative to the target.
|
||||
@@ -304,7 +301,6 @@ pub const Action = union(Key) {
|
||||
new_window,
|
||||
new_tab,
|
||||
close_tab,
|
||||
close_other_tabs,
|
||||
new_split,
|
||||
close_all_windows,
|
||||
toggle_maximize,
|
||||
@@ -706,3 +702,11 @@ pub const OpenUrl = struct {
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/// sync with ghostty_action_close_tab_mode_e in ghostty.h
|
||||
pub const CloseTabMode = enum(c_int) {
|
||||
/// Close the current tab.
|
||||
this,
|
||||
/// Close all other tabs.
|
||||
other,
|
||||
};
|
||||
|
||||
@@ -542,7 +542,7 @@ pub const Application = extern struct {
|
||||
value: apprt.Action.Value(action),
|
||||
) !bool {
|
||||
switch (action) {
|
||||
.close_tab => return Action.closeTab(target),
|
||||
.close_tab => return Action.closeTab(target, value),
|
||||
.close_window => return Action.closeWindow(target),
|
||||
|
||||
.config_change => try Action.configChange(
|
||||
@@ -625,7 +625,6 @@ pub const Application = extern struct {
|
||||
// Unimplemented
|
||||
.secure_input,
|
||||
.close_all_windows,
|
||||
.close_other_tabs,
|
||||
.float_window,
|
||||
.toggle_visibility,
|
||||
.cell_size,
|
||||
@@ -873,7 +872,8 @@ pub const Application = extern struct {
|
||||
self.syncActionAccelerator("win.close", .{ .close_window = {} });
|
||||
self.syncActionAccelerator("win.new-window", .{ .new_window = {} });
|
||||
self.syncActionAccelerator("win.new-tab", .{ .new_tab = {} });
|
||||
self.syncActionAccelerator("win.close-tab", .{ .close_tab = {} });
|
||||
self.syncActionAccelerator("win.close-tab::this", .{ .close_tab = .this });
|
||||
self.syncActionAccelerator("tab.close::this", .{ .close_tab = .this });
|
||||
self.syncActionAccelerator("win.split-right", .{ .new_split = .right });
|
||||
self.syncActionAccelerator("win.split-down", .{ .new_split = .down });
|
||||
self.syncActionAccelerator("win.split-left", .{ .new_split = .left });
|
||||
@@ -1577,12 +1577,16 @@ pub const Application = extern struct {
|
||||
|
||||
/// All apprt action handlers
|
||||
const Action = struct {
|
||||
pub fn closeTab(target: apprt.Target) bool {
|
||||
pub fn closeTab(target: apprt.Target, value: apprt.Action.Value(.close_tab)) bool {
|
||||
switch (target) {
|
||||
.app => return false,
|
||||
.surface => |core| {
|
||||
const surface = core.rt_surface.surface;
|
||||
return surface.as(gtk.Widget).activateAction("tab.close", null) != 0;
|
||||
return surface.as(gtk.Widget).activateAction(
|
||||
"tab.close",
|
||||
glib.ext.VariantType.stringFor([:0]const u8),
|
||||
@as([*:0]const u8, @tagName(value)),
|
||||
) != 0;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,7 +156,6 @@ pub const CommandPalette = extern struct {
|
||||
// for GTK.
|
||||
switch (command.action) {
|
||||
.close_all_windows,
|
||||
.close_other_tabs,
|
||||
.toggle_secure_input,
|
||||
.check_for_updates,
|
||||
.redo,
|
||||
|
||||
@@ -199,8 +199,11 @@ pub const Tab = extern struct {
|
||||
}
|
||||
|
||||
fn initActionMap(self: *Self) void {
|
||||
const s_param_type = glib.ext.VariantType.newFor([:0]const u8);
|
||||
defer s_param_type.free();
|
||||
|
||||
const actions = [_]ext.actions.Action(Self){
|
||||
.init("close", actionClose, null),
|
||||
.init("close", actionClose, s_param_type),
|
||||
.init("ring-bell", actionRingBell, null),
|
||||
};
|
||||
|
||||
@@ -314,18 +317,48 @@ pub const Tab = extern struct {
|
||||
|
||||
fn actionClose(
|
||||
_: *gio.SimpleAction,
|
||||
_: ?*glib.Variant,
|
||||
param_: ?*glib.Variant,
|
||||
self: *Self,
|
||||
) callconv(.c) void {
|
||||
const param = param_ orelse {
|
||||
log.warn("tab.close-tab called without a parameter", .{});
|
||||
return;
|
||||
};
|
||||
|
||||
var str: ?[*:0]const u8 = null;
|
||||
param.get("&s", &str);
|
||||
|
||||
const tab_view = ext.getAncestor(
|
||||
adw.TabView,
|
||||
self.as(gtk.Widget),
|
||||
) orelse return;
|
||||
|
||||
const page = tab_view.getPage(self.as(gtk.Widget));
|
||||
|
||||
const mode = std.meta.stringToEnum(
|
||||
apprt.action.CloseTabMode,
|
||||
std.mem.span(
|
||||
str orelse {
|
||||
log.warn("invalid mode provided to tab.close-tab", .{});
|
||||
return;
|
||||
},
|
||||
),
|
||||
) orelse {
|
||||
// Need to be defensive here since actions can be triggered externally.
|
||||
log.warn("invalid mode provided to tab.close-tab: {s}", .{str.?});
|
||||
return;
|
||||
};
|
||||
|
||||
// Delegate to our parent to handle this, since this will emit
|
||||
// a close-page signal that the parent can intercept.
|
||||
tab_view.closePage(page);
|
||||
switch (mode) {
|
||||
.this => {
|
||||
tab_view.closePage(page);
|
||||
},
|
||||
.other => {
|
||||
log.warn("close-tab:other is not implemented", .{});
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn actionRingBell(
|
||||
|
||||
@@ -320,10 +320,13 @@ pub const Window = extern struct {
|
||||
|
||||
/// Setup our action map.
|
||||
fn initActionMap(self: *Self) void {
|
||||
const s_variant_type = glib.ext.VariantType.newFor([:0]const u8);
|
||||
defer s_variant_type.free();
|
||||
|
||||
const actions = [_]ext.actions.Action(Self){
|
||||
.init("about", actionAbout, null),
|
||||
.init("close", actionClose, null),
|
||||
.init("close-tab", actionCloseTab, null),
|
||||
.init("close-tab", actionCloseTab, s_variant_type),
|
||||
.init("new-tab", actionNewTab, null),
|
||||
.init("new-window", actionNewWindow, null),
|
||||
.init("ring-bell", actionRingBell, null),
|
||||
@@ -1679,10 +1682,31 @@ pub const Window = extern struct {
|
||||
|
||||
fn actionCloseTab(
|
||||
_: *gio.SimpleAction,
|
||||
_: ?*glib.Variant,
|
||||
param_: ?*glib.Variant,
|
||||
self: *Window,
|
||||
) callconv(.c) void {
|
||||
self.performBindingAction(.close_tab);
|
||||
const param = param_ orelse {
|
||||
log.warn("win.close-tab called without a parameter", .{});
|
||||
return;
|
||||
};
|
||||
|
||||
var str: ?[*:0]const u8 = null;
|
||||
param.get("&s", &str);
|
||||
|
||||
const mode = std.meta.stringToEnum(
|
||||
input.Binding.Action.CloseTabMode,
|
||||
std.mem.span(
|
||||
str orelse {
|
||||
log.warn("invalid mode provided to win.close-tab", .{});
|
||||
return;
|
||||
},
|
||||
),
|
||||
) orelse {
|
||||
log.warn("invalid mode provided to win.close-tab: {s}", .{str.?});
|
||||
return;
|
||||
};
|
||||
|
||||
self.performBindingAction(.{ .close_tab = mode });
|
||||
}
|
||||
|
||||
fn actionNewWindow(
|
||||
|
||||
@@ -228,7 +228,8 @@ menu context_menu_model {
|
||||
|
||||
item {
|
||||
label: _("Close Tab");
|
||||
action: "win.close-tab";
|
||||
action: "tab.close";
|
||||
target: "this";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -226,6 +226,7 @@ menu main_menu {
|
||||
item {
|
||||
label: _("Close Tab");
|
||||
action: "win.close-tab";
|
||||
target: "this";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -491,7 +491,7 @@ pub fn performAction(
|
||||
.toggle_maximize => self.toggleMaximize(target),
|
||||
.toggle_fullscreen => self.toggleFullscreen(target, value),
|
||||
.new_tab => try self.newTab(target),
|
||||
.close_tab => return try self.closeTab(target),
|
||||
.close_tab => return try self.closeTab(target, value),
|
||||
.goto_tab => return self.gotoTab(target, value),
|
||||
.move_tab => self.moveTab(target, value),
|
||||
.new_split => try self.newSplit(target, value),
|
||||
@@ -528,7 +528,6 @@ pub fn performAction(
|
||||
|
||||
// Unimplemented
|
||||
.close_all_windows,
|
||||
.close_other_tabs,
|
||||
.float_window,
|
||||
.toggle_visibility,
|
||||
.cell_size,
|
||||
@@ -586,7 +585,7 @@ fn newTab(_: *App, target: apprt.Target) !void {
|
||||
}
|
||||
}
|
||||
|
||||
fn closeTab(_: *App, target: apprt.Target) !bool {
|
||||
fn closeTab(_: *App, target: apprt.Target, value: apprt.Action.Value(.close_tab)) !bool {
|
||||
switch (target) {
|
||||
.app => return false,
|
||||
.surface => |v| {
|
||||
@@ -598,8 +597,16 @@ fn closeTab(_: *App, target: apprt.Target) !bool {
|
||||
return false;
|
||||
};
|
||||
|
||||
tab.closeWithConfirmation();
|
||||
return true;
|
||||
switch (value) {
|
||||
.this => {
|
||||
tab.closeWithConfirmation();
|
||||
return true;
|
||||
},
|
||||
.other => {
|
||||
log.warn("close-tab:other is not implemented", .{});
|
||||
return false;
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1146,7 +1153,7 @@ fn syncActionAccelerators(self: *App) !void {
|
||||
try self.syncActionAccelerator("win.close", .{ .close_window = {} });
|
||||
try self.syncActionAccelerator("win.new-window", .{ .new_window = {} });
|
||||
try self.syncActionAccelerator("win.new-tab", .{ .new_tab = {} });
|
||||
try self.syncActionAccelerator("win.close-tab", .{ .close_tab = {} });
|
||||
try self.syncActionAccelerator("win.close-tab", .{ .close_tab = .this });
|
||||
try self.syncActionAccelerator("win.split-right", .{ .new_split = .right });
|
||||
try self.syncActionAccelerator("win.split-down", .{ .new_split = .down });
|
||||
try self.syncActionAccelerator("win.split-left", .{ .new_split = .left });
|
||||
|
||||
@@ -108,7 +108,6 @@ pub fn updateConfig(self: *CommandPalette, config: *const configpkg.Config) !voi
|
||||
// or don't make sense for GTK
|
||||
switch (command.action) {
|
||||
.close_all_windows,
|
||||
.close_other_tabs,
|
||||
.toggle_secure_input,
|
||||
.check_for_updates,
|
||||
.redo,
|
||||
|
||||
@@ -1076,7 +1076,7 @@ fn gtkActionCloseTab(
|
||||
_: ?*glib.Variant,
|
||||
self: *Window,
|
||||
) callconv(.c) void {
|
||||
self.performBindingAction(.{ .close_tab = {} });
|
||||
self.performBindingAction(.{ .close_tab = .this });
|
||||
}
|
||||
|
||||
fn gtkActionSplitRight(
|
||||
|
||||
Reference in New Issue
Block a user