mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
@ -143,6 +143,7 @@ typedef enum {
|
||||
typedef enum {
|
||||
GHOSTTY_TAB_PREVIOUS = -1,
|
||||
GHOSTTY_TAB_NEXT = -2,
|
||||
GHOSTTY_TAB_LAST = -3,
|
||||
} ghostty_tab_e;
|
||||
|
||||
typedef enum {
|
||||
|
@ -725,6 +725,8 @@ class TerminalController: NSWindowController, NSWindowDelegate,
|
||||
} else {
|
||||
finalIndex = selectedIndex + 1
|
||||
}
|
||||
} else if (tabIndex == GHOSTTY_TAB_LAST.rawValue) {
|
||||
finalIndex = tabbedWindows.count - 1
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
@ -3559,9 +3559,9 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
|
||||
}
|
||||
}
|
||||
|
||||
if (@hasDecl(apprt.Surface, "gotoPreviousTab")) {
|
||||
self.rt_surface.gotoPreviousTab();
|
||||
} else log.warn("runtime doesn't implement gotoPreviousTab", .{});
|
||||
if (@hasDecl(apprt.Surface, "gotoTab")) {
|
||||
self.rt_surface.gotoTab(.previous);
|
||||
} else log.warn("runtime doesn't implement gotoTab", .{});
|
||||
},
|
||||
|
||||
.next_tab => {
|
||||
@ -3572,14 +3572,27 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
|
||||
}
|
||||
}
|
||||
|
||||
if (@hasDecl(apprt.Surface, "gotoNextTab")) {
|
||||
self.rt_surface.gotoNextTab();
|
||||
} else log.warn("runtime doesn't implement gotoNextTab", .{});
|
||||
if (@hasDecl(apprt.Surface, "gotoTab")) {
|
||||
self.rt_surface.gotoTab(.next);
|
||||
} else log.warn("runtime doesn't implement gotoTab", .{});
|
||||
},
|
||||
|
||||
.last_tab => {
|
||||
if (@hasDecl(apprt.Surface, "hasTabs")) {
|
||||
if (!self.rt_surface.hasTabs()) {
|
||||
log.debug("surface has no tabs, ignoring last_tab binding", .{});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (@hasDecl(apprt.Surface, "gotoTab")) {
|
||||
self.rt_surface.gotoTab(.last);
|
||||
} else log.warn("runtime doesn't implement gotoTab", .{});
|
||||
},
|
||||
|
||||
.goto_tab => |n| {
|
||||
if (@hasDecl(apprt.Surface, "gotoTab")) {
|
||||
self.rt_surface.gotoTab(n);
|
||||
self.rt_surface.gotoTab(@enumFromInt(n));
|
||||
} else log.warn("runtime doesn't implement gotoTab", .{});
|
||||
},
|
||||
|
||||
|
@ -28,6 +28,7 @@ pub const ClipboardRequestType = structs.ClipboardRequestType;
|
||||
pub const ColorScheme = structs.ColorScheme;
|
||||
pub const CursorPos = structs.CursorPos;
|
||||
pub const DesktopNotification = structs.DesktopNotification;
|
||||
pub const GotoTab = structs.GotoTab;
|
||||
pub const IMEPos = structs.IMEPos;
|
||||
pub const Selection = structs.Selection;
|
||||
pub const SplitDirection = structs.SplitDirection;
|
||||
|
@ -108,7 +108,7 @@ pub const App = struct {
|
||||
toggle_split_zoom: ?*const fn (SurfaceUD) callconv(.C) void = null,
|
||||
|
||||
/// Goto tab
|
||||
goto_tab: ?*const fn (SurfaceUD, GotoTab) callconv(.C) void = null,
|
||||
goto_tab: ?*const fn (SurfaceUD, apprt.GotoTab) callconv(.C) void = null,
|
||||
|
||||
/// Toggle fullscreen for current window.
|
||||
toggle_fullscreen: ?*const fn (SurfaceUD, configpkg.NonNativeFullscreen) callconv(.C) void = null,
|
||||
@ -135,13 +135,6 @@ pub const App = struct {
|
||||
mouse_over_link: ?*const fn (SurfaceUD, ?[*]const u8, usize) void = null,
|
||||
};
|
||||
|
||||
/// Special values for the goto_tab callback.
|
||||
const GotoTab = enum(i32) {
|
||||
previous = -1,
|
||||
next = -2,
|
||||
_,
|
||||
};
|
||||
|
||||
core_app: *CoreApp,
|
||||
config: *const Config,
|
||||
opts: Options,
|
||||
@ -994,36 +987,13 @@ pub const Surface = struct {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn gotoTab(self: *Surface, n: usize) void {
|
||||
pub fn gotoTab(self: *Surface, tab: apprt.GotoTab) void {
|
||||
const func = self.app.opts.goto_tab orelse {
|
||||
log.info("runtime embedder does not goto_tab", .{});
|
||||
return;
|
||||
};
|
||||
|
||||
const idx = std.math.cast(i32, n) orelse {
|
||||
log.warn("cannot cast tab index to i32 n={}", .{n});
|
||||
return;
|
||||
};
|
||||
|
||||
func(self.userdata, @enumFromInt(idx));
|
||||
}
|
||||
|
||||
pub fn gotoPreviousTab(self: *Surface) void {
|
||||
const func = self.app.opts.goto_tab orelse {
|
||||
log.info("runtime embedder does not goto_tab", .{});
|
||||
return;
|
||||
};
|
||||
|
||||
func(self.userdata, .previous);
|
||||
}
|
||||
|
||||
pub fn gotoNextTab(self: *Surface) void {
|
||||
const func = self.app.opts.goto_tab orelse {
|
||||
log.info("runtime embedder does not goto_tab", .{});
|
||||
return;
|
||||
};
|
||||
|
||||
func(self.userdata, .next);
|
||||
func(self.userdata, tab);
|
||||
}
|
||||
|
||||
pub fn toggleFullscreen(self: *Surface, nonNativeFullscreen: configpkg.NonNativeFullscreen) void {
|
||||
|
@ -795,31 +795,7 @@ pub fn hasTabs(self: *const Surface) bool {
|
||||
return window.hasTabs();
|
||||
}
|
||||
|
||||
pub fn gotoPreviousTab(self: *Surface) void {
|
||||
const window = self.container.window() orelse {
|
||||
log.info(
|
||||
"gotoPreviousTab invalid for container={s}",
|
||||
.{@tagName(self.container)},
|
||||
);
|
||||
return;
|
||||
};
|
||||
|
||||
window.gotoPreviousTab(self);
|
||||
}
|
||||
|
||||
pub fn gotoNextTab(self: *Surface) void {
|
||||
const window = self.container.window() orelse {
|
||||
log.info(
|
||||
"gotoNextTab invalid for container={s}",
|
||||
.{@tagName(self.container)},
|
||||
);
|
||||
return;
|
||||
};
|
||||
|
||||
window.gotoNextTab(self);
|
||||
}
|
||||
|
||||
pub fn gotoTab(self: *Surface, n: usize) void {
|
||||
pub fn gotoTab(self: *Surface, tab: apprt.GotoTab) void {
|
||||
const window = self.container.window() orelse {
|
||||
log.info(
|
||||
"gotoTab invalid for container={s}",
|
||||
@ -828,7 +804,12 @@ pub fn gotoTab(self: *Surface, n: usize) void {
|
||||
return;
|
||||
};
|
||||
|
||||
window.gotoTab(n);
|
||||
switch (tab) {
|
||||
.previous => window.gotoPreviousTab(self),
|
||||
.next => window.gotoNextTab(self),
|
||||
.last => window.gotoLastTab(),
|
||||
else => window.gotoTab(@intCast(@intFromEnum(tab))),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setShouldClose(self: *Surface) void {
|
||||
|
@ -288,6 +288,13 @@ pub fn gotoNextTab(self: *Window, surface: *Surface) void {
|
||||
self.focusCurrentTab();
|
||||
}
|
||||
|
||||
/// Go to the next tab for a surface.
|
||||
pub fn gotoLastTab(self: *Window) void {
|
||||
const max = c.gtk_notebook_get_n_pages(self.notebook) -| 1;
|
||||
c.gtk_notebook_set_current_page(self.notebook, max);
|
||||
self.focusCurrentTab();
|
||||
}
|
||||
|
||||
/// Go to the specific tab index.
|
||||
pub fn gotoTab(self: *Window, n: usize) void {
|
||||
if (n == 0) return;
|
||||
|
@ -62,6 +62,16 @@ pub const DesktopNotification = struct {
|
||||
body: []const u8,
|
||||
};
|
||||
|
||||
/// The tab to jump to. This is non-exhaustive so that integer values represent
|
||||
/// the index (zero-based) of the tab to jump to. Negative values are special
|
||||
/// values.
|
||||
pub const GotoTab = enum(c_int) {
|
||||
previous = -1,
|
||||
next = -2,
|
||||
last = -3,
|
||||
_,
|
||||
};
|
||||
|
||||
// This is made extern (c_int) to make interop easier with our embedded
|
||||
// runtime. The small size cost doesn't make a difference in our union.
|
||||
pub const SplitDirection = enum(c_int) {
|
||||
|
@ -1894,6 +1894,11 @@ pub fn default(alloc_gpa: Allocator) Allocator.Error!Config {
|
||||
.{ .key = .{ .translated = .right_bracket }, .mods = .{ .super = true, .shift = true } },
|
||||
.{ .next_tab = {} },
|
||||
);
|
||||
try result.keybind.set.put(
|
||||
alloc,
|
||||
.{ .key = .{ .physical = inputpkg.Key.zero }, .mods = .{ .super = true } },
|
||||
.{ .last_tab = {} },
|
||||
);
|
||||
try result.keybind.set.put(
|
||||
alloc,
|
||||
.{ .key = .{ .translated = .d }, .mods = .{ .super = true } },
|
||||
|
@ -240,6 +240,9 @@ pub const Action = union(enum) {
|
||||
/// Go to the next tab.
|
||||
next_tab: void,
|
||||
|
||||
/// Go to the last tab (the one with the highest index)
|
||||
last_tab: void,
|
||||
|
||||
/// Go to the tab with the specific number, 1-indexed.
|
||||
goto_tab: usize,
|
||||
|
||||
|
Reference in New Issue
Block a user