diff --git a/include/ghostty.h b/include/ghostty.h index 61c3aad32..73d956110 100644 --- a/include/ghostty.h +++ b/include/ghostty.h @@ -557,6 +557,10 @@ typedef struct { bool soft; } ghostty_action_reload_config_s; +// apprt.action.ReopenLastTab +typedef struct { +} ghostty_action_reopen_last_tab_s; + // apprt.Action.Key typedef enum { GHOSTTY_ACTION_NEW_WINDOW, @@ -594,6 +598,7 @@ typedef enum { GHOSTTY_ACTION_COLOR_CHANGE, GHOSTTY_ACTION_RELOAD_CONFIG, GHOSTTY_ACTION_CONFIG_CHANGE, + GHOSTTY_ACTION_REOPEN_LAST_TAB, } ghostty_action_tag_e; typedef union { @@ -620,6 +625,7 @@ typedef union { ghostty_action_color_change_s color_change; ghostty_action_reload_config_s reload_config; ghostty_action_config_change_s config_change; + ghostty_action_reopen_last_tab_s reopen_last_tab; } ghostty_action_u; typedef struct { diff --git a/src/App.zig b/src/App.zig index 279c4e497..32d921c3d 100644 --- a/src/App.zig +++ b/src/App.zig @@ -444,6 +444,7 @@ pub fn performAction( .close_all_windows => try rt_app.performAction(.app, .close_all_windows, {}), .toggle_quick_terminal => try rt_app.performAction(.app, .toggle_quick_terminal, {}), .toggle_visibility => try rt_app.performAction(.app, .toggle_visibility, {}), + .reopen_last_tab => try rt_app.performAction(.app, .reopen_last_tab, {}), } } diff --git a/src/apprt/action.zig b/src/apprt/action.zig index 527535ffa..2e0fde28a 100644 --- a/src/apprt/action.zig +++ b/src/apprt/action.zig @@ -217,6 +217,9 @@ pub const Action = union(Key) { /// for changes. config_change: ConfigChange, + /// Reopen the most recently closed tab. + reopen_last_tab, + /// Sync with: ghostty_action_tag_e pub const Key = enum(c_int) { new_window, @@ -254,6 +257,7 @@ pub const Action = union(Key) { color_change, reload_config, config_change, + reopen_last_tab, }; /// Sync with: ghostty_action_u diff --git a/src/apprt/glfw.zig b/src/apprt/glfw.zig index 64b0cbe81..cb2189339 100644 --- a/src/apprt/glfw.zig +++ b/src/apprt/glfw.zig @@ -159,6 +159,8 @@ pub const App = struct { .surface => |v| v, }), + .reopen_last_tab => try self.reopenLastTab(), + .size_limit => switch (target) { .app => {}, .surface => |surface| try surface.rt_surface.setSizeLimits(.{ @@ -317,6 +319,12 @@ pub const App = struct { win.setMonitor(monitor, 0, 0, video_mode.getWidth(), video_mode.getHeight(), 0); } + /// Log that a reopen last tab action was triggered + fn reopenLastTab(self: *App) !void { + _ = self; + std.log.debug("Reopen last tab action triggered", .{}); + } + /// Create a new tab in the parent surface. fn newTab(self: *App, parent_: ?*CoreSurface) !void { if (!Darwin.enabled) { diff --git a/src/config/Config.zig b/src/config/Config.zig index 8726fd67c..425738f69 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -2046,6 +2046,13 @@ pub fn default(alloc_gpa: Allocator) Allocator.Error!Config { .{ .open_config = {} }, ); + // keybind for reopening last closed tab + try result.keybind.set.put( + alloc, + .{ .key = .{ .translated = .t }, .mods = inputpkg.ctrlOrSuper(.{ .shift = true }) }, + .{ .reopen_last_tab = {} }, + ); + { // On macOS we default to super but Linux ctrl+shift since // ctrl+c is to kill the process. diff --git a/src/input/Binding.zig b/src/input/Binding.zig index 85721339d..577746038 100644 --- a/src/input/Binding.zig +++ b/src/input/Binding.zig @@ -430,6 +430,9 @@ pub const Action = union(enum) { /// crash: CrashThread, + /// Reopen the most recently closed tab + reopen_last_tab: void, + pub const Key = @typeInfo(Action).Union.tag_type.?; pub const CrashThread = enum { @@ -625,6 +628,7 @@ pub const Action = union(enum) { .quit, .toggle_quick_terminal, .toggle_visibility, + .reopen_last_tab, => .app, // These are app but can be special-cased in a surface context.