mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
feat: add handling logic to store and retrieve closed tabs
This commit is contained in:
@ -345,6 +345,7 @@ class AppDelegate: NSObject,
|
|||||||
|
|
||||||
syncMenuShortcut(config, action: "new_window", menuItem: self.menuNewWindow)
|
syncMenuShortcut(config, action: "new_window", menuItem: self.menuNewWindow)
|
||||||
syncMenuShortcut(config, action: "new_tab", menuItem: self.menuNewTab)
|
syncMenuShortcut(config, action: "new_tab", menuItem: self.menuNewTab)
|
||||||
|
syncMenuShortcut(config, action: "reopen_last_tab", menuItem: self.menuReopenLastTab)
|
||||||
syncMenuShortcut(config, action: "close_surface", menuItem: self.menuClose)
|
syncMenuShortcut(config, action: "close_surface", menuItem: self.menuClose)
|
||||||
syncMenuShortcut(config, action: "close_window", menuItem: self.menuCloseWindow)
|
syncMenuShortcut(config, action: "close_window", menuItem: self.menuCloseWindow)
|
||||||
syncMenuShortcut(config, action: "close_all_windows", menuItem: self.menuCloseAllWindows)
|
syncMenuShortcut(config, action: "close_all_windows", menuItem: self.menuCloseAllWindows)
|
||||||
|
@ -197,6 +197,13 @@ extension Ghostty {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func reopenLastTab(surface: ghostty_surface_t) {
|
||||||
|
let action = "reopen_last_tab"
|
||||||
|
if (!ghostty_surface_binding_action(surface, action, UInt(action.count))) {
|
||||||
|
logger.warning("action failed action=\(action)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func newWindow(surface: ghostty_surface_t) {
|
func newWindow(surface: ghostty_surface_t) {
|
||||||
let action = "new_window"
|
let action = "new_window"
|
||||||
if (!ghostty_surface_binding_action(surface, action, UInt(action.count))) {
|
if (!ghostty_surface_binding_action(surface, action, UInt(action.count))) {
|
||||||
@ -460,6 +467,9 @@ extension Ghostty {
|
|||||||
case GHOSTTY_ACTION_NEW_TAB:
|
case GHOSTTY_ACTION_NEW_TAB:
|
||||||
newTab(app, target: target)
|
newTab(app, target: target)
|
||||||
|
|
||||||
|
case GHOSTTY_ACTION_REOPEN_LAST_TAB:
|
||||||
|
reopenLastTab(app, target: target)
|
||||||
|
|
||||||
case GHOSTTY_ACTION_NEW_SPLIT:
|
case GHOSTTY_ACTION_NEW_SPLIT:
|
||||||
newSplit(app, target: target, direction: action.action.new_split)
|
newSplit(app, target: target, direction: action.action.new_split)
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ const objc = @import("objc");
|
|||||||
const log = std.log.scoped(.app);
|
const log = std.log.scoped(.app);
|
||||||
|
|
||||||
const SurfaceList = std.ArrayListUnmanaged(*apprt.Surface);
|
const SurfaceList = std.ArrayListUnmanaged(*apprt.Surface);
|
||||||
|
const LastClosedTabs = @import("terminal/closedtabs.zig").LastClosedTabs;
|
||||||
|
|
||||||
/// General purpose allocator
|
/// General purpose allocator
|
||||||
alloc: Allocator,
|
alloc: Allocator,
|
||||||
@ -31,6 +32,9 @@ alloc: Allocator,
|
|||||||
/// The list of surfaces that are currently active.
|
/// The list of surfaces that are currently active.
|
||||||
surfaces: SurfaceList,
|
surfaces: SurfaceList,
|
||||||
|
|
||||||
|
/// Storage for recently closed tabs
|
||||||
|
last_closed_tabs: LastClosedTabs = .{},
|
||||||
|
|
||||||
/// This is true if the app that Ghostty is in is focused. This may
|
/// This is true if the app that Ghostty is in is focused. This may
|
||||||
/// mean that no surfaces (terminals) are focused but the app is still
|
/// mean that no surfaces (terminals) are focused but the app is still
|
||||||
/// focused, i.e. may an about window. On macOS, this concept is known
|
/// focused, i.e. may an about window. On macOS, this concept is known
|
||||||
@ -101,6 +105,7 @@ pub fn create(
|
|||||||
.quit = false,
|
.quit = false,
|
||||||
.font_grid_set = font_grid_set,
|
.font_grid_set = font_grid_set,
|
||||||
.config_conditional_state = .{},
|
.config_conditional_state = .{},
|
||||||
|
.last_closed_tabs = .{},
|
||||||
};
|
};
|
||||||
errdefer app.surfaces.deinit(alloc);
|
errdefer app.surfaces.deinit(alloc);
|
||||||
|
|
||||||
@ -112,6 +117,9 @@ pub fn destroy(self: *App) void {
|
|||||||
for (self.surfaces.items) |surface| surface.deinit();
|
for (self.surfaces.items) |surface| surface.deinit();
|
||||||
self.surfaces.deinit(self.alloc);
|
self.surfaces.deinit(self.alloc);
|
||||||
|
|
||||||
|
// Clean up our last closed tabs
|
||||||
|
self.last_closed_tabs.deinit(self.alloc);
|
||||||
|
|
||||||
// Clean up our font group cache
|
// Clean up our font group cache
|
||||||
// We should have zero items in the grid set at this point because
|
// We should have zero items in the grid set at this point because
|
||||||
// destroy only gets called when the app is shutting down and this
|
// destroy only gets called when the app is shutting down and this
|
||||||
@ -444,7 +452,6 @@ pub fn performAction(
|
|||||||
.close_all_windows => try rt_app.performAction(.app, .close_all_windows, {}),
|
.close_all_windows => try rt_app.performAction(.app, .close_all_windows, {}),
|
||||||
.toggle_quick_terminal => try rt_app.performAction(.app, .toggle_quick_terminal, {}),
|
.toggle_quick_terminal => try rt_app.performAction(.app, .toggle_quick_terminal, {}),
|
||||||
.toggle_visibility => try rt_app.performAction(.app, .toggle_visibility, {}),
|
.toggle_visibility => try rt_app.performAction(.app, .toggle_visibility, {}),
|
||||||
.reopen_last_tab => try rt_app.performAction(.app, .reopen_last_tab, {}),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -724,6 +724,25 @@ pub fn deinit(self: *Surface) void {
|
|||||||
/// Close this surface. This will trigger the runtime to start the
|
/// Close this surface. This will trigger the runtime to start the
|
||||||
/// close process, which should ultimately deinitialize this surface.
|
/// close process, which should ultimately deinitialize this surface.
|
||||||
pub fn close(self: *Surface) void {
|
pub fn close(self: *Surface) void {
|
||||||
|
// Save tab data before closing
|
||||||
|
const cwd = self.io.terminal.getPwd();
|
||||||
|
const cwd_copy = if (cwd) |c| self.alloc.dupe(u8, c) catch null else null;
|
||||||
|
|
||||||
|
const title = self.rt_surface.getTitle();
|
||||||
|
const title_copy = if (title) |t| self.alloc.dupe(u8, t) catch null else null;
|
||||||
|
|
||||||
|
// Save to last closed tabs
|
||||||
|
self.app.last_closed_tabs.push(.{
|
||||||
|
.title = title_copy,
|
||||||
|
.cwd = cwd_copy,
|
||||||
|
}, self.alloc);
|
||||||
|
|
||||||
|
log.debug("closing tab - pwd: {s}, title: {s}", .{
|
||||||
|
cwd_copy orelse "(null)",
|
||||||
|
title_copy orelse "(null)",
|
||||||
|
});
|
||||||
|
|
||||||
|
log.debug("close from surface ptr={X}", .{@intFromPtr(self)});
|
||||||
self.rt_surface.close(self.needsConfirmQuit());
|
self.rt_surface.close(self.needsConfirmQuit());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4007,6 +4026,12 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
|
|||||||
{},
|
{},
|
||||||
),
|
),
|
||||||
|
|
||||||
|
.reopen_last_tab => try self.rt_app.performAction(
|
||||||
|
.{ .surface = self },
|
||||||
|
.reopen_last_tab,
|
||||||
|
{},
|
||||||
|
),
|
||||||
|
|
||||||
inline .previous_tab,
|
inline .previous_tab,
|
||||||
.next_tab,
|
.next_tab,
|
||||||
.last_tab,
|
.last_tab,
|
||||||
|
@ -22,8 +22,7 @@ const CoreApp = @import("../App.zig");
|
|||||||
const CoreSurface = @import("../Surface.zig");
|
const CoreSurface = @import("../Surface.zig");
|
||||||
const configpkg = @import("../config.zig");
|
const configpkg = @import("../config.zig");
|
||||||
const Config = @import("../config.zig").Config;
|
const Config = @import("../config.zig").Config;
|
||||||
|
const LastClosedTab = @import("../terminal/closedtabs.zig").LastClosedTab;
|
||||||
const LastClosedTabs = @import("../terminal/closedtabs.zig").LastClosedTabs;
|
|
||||||
|
|
||||||
// Get native API access on certain platforms so we can do more customization.
|
// Get native API access on certain platforms so we can do more customization.
|
||||||
const glfwNative = glfw.Native(.{
|
const glfwNative = glfw.Native(.{
|
||||||
@ -40,9 +39,6 @@ pub const App = struct {
|
|||||||
/// Mac-specific state.
|
/// Mac-specific state.
|
||||||
darwin: if (Darwin.enabled) Darwin else void,
|
darwin: if (Darwin.enabled) Darwin else void,
|
||||||
|
|
||||||
/// Store information about the last closed tabs
|
|
||||||
last_closed_tabs: LastClosedTabs = .{},
|
|
||||||
|
|
||||||
pub const Options = struct {};
|
pub const Options = struct {};
|
||||||
|
|
||||||
pub fn init(core_app: *CoreApp, _: Options) !App {
|
pub fn init(core_app: *CoreApp, _: Options) !App {
|
||||||
@ -110,7 +106,6 @@ pub const App = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn terminate(self: *App) void {
|
pub fn terminate(self: *App) void {
|
||||||
self.last_closed_tabs.deinit(self.app.alloc);
|
|
||||||
self.config.deinit();
|
self.config.deinit();
|
||||||
glfw.terminate();
|
glfw.terminate();
|
||||||
}
|
}
|
||||||
@ -165,7 +160,10 @@ pub const App = struct {
|
|||||||
.surface => |v| v,
|
.surface => |v| v,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
.reopen_last_tab => try self.reopenLastTab(),
|
.reopen_last_tab => try self.reopenLastTab(switch (target) {
|
||||||
|
.app => null,
|
||||||
|
.surface => |v| v,
|
||||||
|
}),
|
||||||
|
|
||||||
.size_limit => switch (target) {
|
.size_limit => switch (target) {
|
||||||
.app => {},
|
.app => {},
|
||||||
@ -325,26 +323,8 @@ pub const App = struct {
|
|||||||
win.setMonitor(monitor, 0, 0, video_mode.getWidth(), video_mode.getHeight(), 0);
|
win.setMonitor(monitor, 0, 0, video_mode.getWidth(), video_mode.getHeight(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Log that a reopen last tab action was triggered
|
fn addTab(self: *App, parent: *CoreSurface, window: *Surface) !void {
|
||||||
fn reopenLastTab(self: *App) !void {
|
|
||||||
_ = self;
|
_ = 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) {
|
|
||||||
log.warn("tabbing is not supported on this platform", .{});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const parent = parent_ orelse {
|
|
||||||
_ = try self.newSurface(null);
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create the new window
|
|
||||||
const window = try self.newSurface(parent);
|
|
||||||
|
|
||||||
// Add the new window the parent window
|
// Add the new window the parent window
|
||||||
const parent_win = glfwNative.getCocoaWindow(parent.rt_surface.window).?;
|
const parent_win = glfwNative.getCocoaWindow(parent.rt_surface.window).?;
|
||||||
@ -370,6 +350,66 @@ pub const App = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Log that a reopen last tab action was triggered
|
||||||
|
fn reopenLastTab(self: *App, parent_: ?*CoreSurface) !void {
|
||||||
|
if (!Darwin.enabled) {
|
||||||
|
log.warn("tabbing is not supported on this platform", .{});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const parent: *CoreSurface = parent_ orelse {
|
||||||
|
log.warn("No parent surface found", .{});
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get the last closed tab from the app-level storage
|
||||||
|
const last_tab: *LastClosedTab = parent.app.last_closed_tabs.getLast() orelse {
|
||||||
|
log.warn("No last closed tab found", .{});
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a new tab
|
||||||
|
const window = try self.newSurface(parent);
|
||||||
|
|
||||||
|
// Set the working directory and title if available
|
||||||
|
if (last_tab.cwd) |cwd| {
|
||||||
|
try window.core_surface.io.terminal.setPwd(cwd);
|
||||||
|
}
|
||||||
|
if (last_tab.title) |title| {
|
||||||
|
// Ensure we have a null-terminated string for the title
|
||||||
|
const title_z = try window.core_surface.alloc.dupeZ(u8, title);
|
||||||
|
errdefer window.core_surface.alloc.free(title_z);
|
||||||
|
try window.core_surface.rt_surface.setTitle(title_z);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug("Reopening last tab - pwd: {s}, title: {s}", .{
|
||||||
|
last_tab.cwd orelse "(null)",
|
||||||
|
last_tab.title orelse "(null)",
|
||||||
|
});
|
||||||
|
|
||||||
|
try self.addTab(parent, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new tab in the parent surface.
|
||||||
|
fn newTab(self: *App, parent_: ?*CoreSurface) !void {
|
||||||
|
if (!Darwin.enabled) {
|
||||||
|
log.warn("tabbing is not supported on this platform", .{});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const parent = parent_ orelse {
|
||||||
|
_ = try self.newSurface(null);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
log.debug("New tab: {?}", .{parent});
|
||||||
|
|
||||||
|
// Create the new window
|
||||||
|
const window = try self.newSurface(parent);
|
||||||
|
|
||||||
|
try self.addTab(parent, window);
|
||||||
|
}
|
||||||
|
|
||||||
fn newSurface(self: *App, parent_: ?*CoreSurface) !*Surface {
|
fn newSurface(self: *App, parent_: ?*CoreSurface) !*Surface {
|
||||||
// Grab a surface allocation because we're going to need it.
|
// Grab a surface allocation because we're going to need it.
|
||||||
var surface = try self.app.alloc.create(Surface);
|
var surface = try self.app.alloc.create(Surface);
|
||||||
@ -610,26 +650,6 @@ pub const Surface = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Surface) void {
|
pub fn deinit(self: *Surface) void {
|
||||||
// Save the closing tab information
|
|
||||||
const title = if (self.title_text) |t|
|
|
||||||
self.core_surface.alloc.dupe(u8, t) catch null
|
|
||||||
else
|
|
||||||
null;
|
|
||||||
errdefer if (title) |t| self.core_surface.alloc.free(t);
|
|
||||||
|
|
||||||
const cwd = self.core_surface.alloc.dupe(u8, "~") catch null;
|
|
||||||
errdefer if (cwd) |c| self.core_surface.alloc.free(c);
|
|
||||||
|
|
||||||
self.app.last_closed_tabs.push(.{
|
|
||||||
.title = title,
|
|
||||||
.cwd = cwd,
|
|
||||||
}, self.core_surface.alloc);
|
|
||||||
|
|
||||||
log.debug("all last closed tab: {?}", .{self.app.last_closed_tabs.this});
|
|
||||||
log.debug("last closed tab: {?}", .{self.app.last_closed_tabs.getLast()});
|
|
||||||
|
|
||||||
if (self.title_text) |t| self.core_surface.alloc.free(t);
|
|
||||||
|
|
||||||
// Remove ourselves from the list of known surfaces in the app.
|
// Remove ourselves from the list of known surfaces in the app.
|
||||||
self.app.app.deleteSurface(self);
|
self.app.app.deleteSurface(self);
|
||||||
|
|
||||||
|
@ -459,6 +459,7 @@ pub fn performAction(
|
|||||||
.toggle_fullscreen => self.toggleFullscreen(target, value),
|
.toggle_fullscreen => self.toggleFullscreen(target, value),
|
||||||
|
|
||||||
.new_tab => try self.newTab(target),
|
.new_tab => try self.newTab(target),
|
||||||
|
.reopen_last_tab => try self.reopenLastTab(target),
|
||||||
.goto_tab => self.gotoTab(target, value),
|
.goto_tab => self.gotoTab(target, value),
|
||||||
.move_tab => self.moveTab(target, value),
|
.move_tab => self.moveTab(target, value),
|
||||||
.new_split => try self.newSplit(target, value),
|
.new_split => try self.newSplit(target, value),
|
||||||
@ -514,6 +515,23 @@ fn newTab(_: *App, target: apprt.Target) !void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn reopenLastTab(_: *App, target: apprt.Target) void {
|
||||||
|
switch (target) {
|
||||||
|
.app => {},
|
||||||
|
.surface => |v| {
|
||||||
|
const window = v.rt_surface.container.window() orelse {
|
||||||
|
log.info(
|
||||||
|
"reopen_last_tab invalid for container={s}",
|
||||||
|
.{@tagName(v.rt_surface.container)},
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
window.reopenLastTab();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn gotoTab(_: *App, target: apprt.Target, tab: apprt.action.GotoTab) void {
|
fn gotoTab(_: *App, target: apprt.Target, tab: apprt.action.GotoTab) void {
|
||||||
switch (target) {
|
switch (target) {
|
||||||
.app => {},
|
.app => {},
|
||||||
@ -927,6 +945,7 @@ fn syncActionAccelerators(self: *App) !void {
|
|||||||
try self.syncActionAccelerator("win.close", .{ .close_surface = {} });
|
try self.syncActionAccelerator("win.close", .{ .close_surface = {} });
|
||||||
try self.syncActionAccelerator("win.new_window", .{ .new_window = {} });
|
try self.syncActionAccelerator("win.new_window", .{ .new_window = {} });
|
||||||
try self.syncActionAccelerator("win.new_tab", .{ .new_tab = {} });
|
try self.syncActionAccelerator("win.new_tab", .{ .new_tab = {} });
|
||||||
|
try self.syncActionAccelerator("win.reopen_last_tab", .{ .reopen_last_tab = {} });
|
||||||
try self.syncActionAccelerator("win.split_right", .{ .new_split = .right });
|
try self.syncActionAccelerator("win.split_right", .{ .new_split = .right });
|
||||||
try self.syncActionAccelerator("win.split_down", .{ .new_split = .down });
|
try self.syncActionAccelerator("win.split_down", .{ .new_split = .down });
|
||||||
try self.syncActionAccelerator("win.split_left", .{ .new_split = .left });
|
try self.syncActionAccelerator("win.split_left", .{ .new_split = .left });
|
||||||
@ -1591,6 +1610,7 @@ fn initMenu(self: *App) void {
|
|||||||
c.g_menu_append_section(menu, null, @ptrCast(@alignCast(section)));
|
c.g_menu_append_section(menu, null, @ptrCast(@alignCast(section)));
|
||||||
c.g_menu_append(section, "New Window", "win.new_window");
|
c.g_menu_append(section, "New Window", "win.new_window");
|
||||||
c.g_menu_append(section, "New Tab", "win.new_tab");
|
c.g_menu_append(section, "New Tab", "win.new_tab");
|
||||||
|
c.g_menu_append(section, "Reopen Last Tab", "win.reopen_last_tab");
|
||||||
c.g_menu_append(section, "Split Right", "win.split_right");
|
c.g_menu_append(section, "Split Right", "win.split_right");
|
||||||
c.g_menu_append(section, "Split Down", "win.split_down");
|
c.g_menu_append(section, "Split Down", "win.split_down");
|
||||||
c.g_menu_append(section, "Close Window", "win.close");
|
c.g_menu_append(section, "Close Window", "win.close");
|
||||||
|
@ -129,6 +129,7 @@ pub fn init(self: *Window, app: *App) !void {
|
|||||||
const tab_overview = c.adw_tab_overview_new();
|
const tab_overview = c.adw_tab_overview_new();
|
||||||
c.adw_tab_overview_set_view(@ptrCast(tab_overview), self.notebook.adw_tab_view);
|
c.adw_tab_overview_set_view(@ptrCast(tab_overview), self.notebook.adw_tab_view);
|
||||||
c.adw_tab_overview_set_enable_new_tab(@ptrCast(tab_overview), 1);
|
c.adw_tab_overview_set_enable_new_tab(@ptrCast(tab_overview), 1);
|
||||||
|
c.adw_tab_overview_set_enable_reopen_last_tab(@ptrCast(tab_overview), 1);
|
||||||
_ = c.g_signal_connect_data(
|
_ = c.g_signal_connect_data(
|
||||||
tab_overview,
|
tab_overview,
|
||||||
"create-tab",
|
"create-tab",
|
||||||
@ -382,6 +383,7 @@ fn initActions(self: *Window) void {
|
|||||||
.{ "close", >kActionClose },
|
.{ "close", >kActionClose },
|
||||||
.{ "new_window", >kActionNewWindow },
|
.{ "new_window", >kActionNewWindow },
|
||||||
.{ "new_tab", >kActionNewTab },
|
.{ "new_tab", >kActionNewTab },
|
||||||
|
.{ "reopen_last_tab", >kActionReopenLastTab },
|
||||||
.{ "split_right", >kActionSplitRight },
|
.{ "split_right", >kActionSplitRight },
|
||||||
.{ "split_down", >kActionSplitDown },
|
.{ "split_down", >kActionSplitDown },
|
||||||
.{ "split_left", >kActionSplitLeft },
|
.{ "split_left", >kActionSplitLeft },
|
||||||
@ -436,6 +438,12 @@ pub fn newTab(self: *Window, parent: ?*CoreSurface) !void {
|
|||||||
// does not (cursor doesn't blink) unless reactivated by refocusing.
|
// does not (cursor doesn't blink) unless reactivated by refocusing.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn reopenLastTab(self: *Window) void {
|
||||||
|
_ = self;
|
||||||
|
|
||||||
|
log.debug("reopen last tab", .{});
|
||||||
|
}
|
||||||
|
|
||||||
/// Close the tab for the given notebook page. This will automatically
|
/// Close the tab for the given notebook page. This will automatically
|
||||||
/// handle closing the window if there are no more tabs.
|
/// handle closing the window if there are no more tabs.
|
||||||
pub fn closeTab(self: *Window, tab: *Tab) void {
|
pub fn closeTab(self: *Window, tab: *Tab) void {
|
||||||
@ -810,6 +818,15 @@ fn gtkActionNewTab(
|
|||||||
gtkTabNewClick(undefined, ud);
|
gtkTabNewClick(undefined, ud);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn gtkActionReopenLastTab(
|
||||||
|
_: *c.GSimpleAction,
|
||||||
|
_: *c.GVariant,
|
||||||
|
ud: ?*anyopaque,
|
||||||
|
) callconv(.C) void {
|
||||||
|
const self: *Window = @ptrCast(@alignCast(ud orelse return));
|
||||||
|
self.reopenLastTab();
|
||||||
|
}
|
||||||
|
|
||||||
fn gtkActionSplitRight(
|
fn gtkActionSplitRight(
|
||||||
_: *c.GSimpleAction,
|
_: *c.GSimpleAction,
|
||||||
_: *c.GVariant,
|
_: *c.GVariant,
|
||||||
|
@ -628,7 +628,6 @@ pub const Action = union(enum) {
|
|||||||
.quit,
|
.quit,
|
||||||
.toggle_quick_terminal,
|
.toggle_quick_terminal,
|
||||||
.toggle_visibility,
|
.toggle_visibility,
|
||||||
.reopen_last_tab,
|
|
||||||
=> .app,
|
=> .app,
|
||||||
|
|
||||||
// These are app but can be special-cased in a surface context.
|
// These are app but can be special-cased in a surface context.
|
||||||
@ -673,6 +672,7 @@ pub const Action = union(enum) {
|
|||||||
// come from. For example `new_window` needs to be sourced to
|
// come from. For example `new_window` needs to be sourced to
|
||||||
// a surface so inheritance can be done correctly.
|
// a surface so inheritance can be done correctly.
|
||||||
.new_tab,
|
.new_tab,
|
||||||
|
.reopen_last_tab,
|
||||||
.previous_tab,
|
.previous_tab,
|
||||||
.next_tab,
|
.next_tab,
|
||||||
.last_tab,
|
.last_tab,
|
||||||
@ -896,6 +896,7 @@ pub const Key = enum(c_int) {
|
|||||||
paste_from_clipboard,
|
paste_from_clipboard,
|
||||||
new_tab,
|
new_tab,
|
||||||
new_window,
|
new_window,
|
||||||
|
reopen_last_tab,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Trigger is the associated key state that can trigger an action.
|
/// Trigger is the associated key state that can trigger an action.
|
||||||
|
Reference in New Issue
Block a user