mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
Merge pull request #2298 from Pangoraw/toggle_tab_overview
add binding to toggle tab overview
This commit is contained in:
@ -505,6 +505,7 @@ typedef enum {
|
||||
GHOSTTY_ACTION_NEW_SPLIT,
|
||||
GHOSTTY_ACTION_CLOSE_ALL_WINDOWS,
|
||||
GHOSTTY_ACTION_TOGGLE_FULLSCREEN,
|
||||
GHOSTTY_ACTION_TOGGLE_TAB_OVERVIEW,
|
||||
GHOSTTY_ACTION_TOGGLE_WINDOW_DECORATIONS,
|
||||
GHOSTTY_ACTION_GOTO_TAB,
|
||||
GHOSTTY_ACTION_GOTO_SPLIT,
|
||||
|
@ -484,6 +484,8 @@ extension Ghostty {
|
||||
|
||||
case GHOSTTY_ACTION_CLOSE_ALL_WINDOWS:
|
||||
fallthrough
|
||||
case GHOSTTY_ACTION_TOGGLE_TAB_OVERVIEW:
|
||||
fallthrough
|
||||
case GHOSTTY_ACTION_TOGGLE_WINDOW_DECORATIONS:
|
||||
fallthrough
|
||||
case GHOSTTY_ACTION_PRESENT_TERMINAL:
|
||||
|
@ -3830,6 +3830,12 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
|
||||
{},
|
||||
),
|
||||
|
||||
.toggle_tab_overview => try self.rt_app.performAction(
|
||||
.{ .surface = self },
|
||||
.toggle_tab_overview,
|
||||
{},
|
||||
),
|
||||
|
||||
.toggle_secure_input => try self.rt_app.performAction(
|
||||
.{ .surface = self },
|
||||
.secure_input,
|
||||
|
@ -87,6 +87,9 @@ pub const Action = union(Key) {
|
||||
/// Toggle fullscreen mode.
|
||||
toggle_fullscreen: Fullscreen,
|
||||
|
||||
/// Toggle tab overview.
|
||||
toggle_tab_overview,
|
||||
|
||||
/// Toggle whether window directions are shown.
|
||||
toggle_window_decorations,
|
||||
|
||||
@ -171,6 +174,7 @@ pub const Action = union(Key) {
|
||||
new_split,
|
||||
close_all_windows,
|
||||
toggle_fullscreen,
|
||||
toggle_tab_overview,
|
||||
toggle_window_decorations,
|
||||
goto_tab,
|
||||
goto_split,
|
||||
|
@ -194,6 +194,7 @@ pub const App = struct {
|
||||
.toggle_split_zoom,
|
||||
.present_terminal,
|
||||
.close_all_windows,
|
||||
.toggle_tab_overview,
|
||||
.toggle_window_decorations,
|
||||
.goto_tab,
|
||||
.inspector,
|
||||
|
@ -372,6 +372,7 @@ pub fn performAction(
|
||||
.mouse_visibility => self.setMouseVisibility(target, value),
|
||||
.mouse_shape => try self.setMouseShape(target, value),
|
||||
.mouse_over_link => self.setMouseOverLink(target, value),
|
||||
.toggle_tab_overview => self.toggleTabOverview(target),
|
||||
.toggle_window_decorations => self.toggleWindowDecorations(target),
|
||||
.quit_timer => self.quitTimer(value),
|
||||
|
||||
@ -534,6 +535,23 @@ fn toggleFullscreen(
|
||||
}
|
||||
}
|
||||
|
||||
fn toggleTabOverview(_: *App, target: apprt.Target) void {
|
||||
switch (target) {
|
||||
.app => {},
|
||||
.surface => |v| {
|
||||
const window = v.rt_surface.container.window() orelse {
|
||||
log.info(
|
||||
"toggleTabOverview invalid for container={s}",
|
||||
.{@tagName(v.rt_surface.container)},
|
||||
);
|
||||
return;
|
||||
};
|
||||
|
||||
window.toggleTabOverview();
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn toggleWindowDecorations(
|
||||
_: *App,
|
||||
target: apprt.Target,
|
||||
|
@ -35,6 +35,10 @@ window: *c.GtkWindow,
|
||||
/// GtkHeaderBar depending on if adw is enabled and linked.
|
||||
header: ?*c.GtkWidget,
|
||||
|
||||
/// The tab overview for the window. This is possibly null since there is no
|
||||
/// taboverview without a AdwApplicationWindow (libadwaita >= 1.4.0).
|
||||
tab_overview: ?*c.GtkWidget,
|
||||
|
||||
/// The notebook (tab grouping) for this window.
|
||||
/// can be either c.GtkNotebook or c.AdwTabView.
|
||||
notebook: Notebook,
|
||||
@ -68,6 +72,7 @@ pub fn init(self: *Window, app: *App) !void {
|
||||
.app = app,
|
||||
.window = undefined,
|
||||
.header = null,
|
||||
.tab_overview = null,
|
||||
.notebook = undefined,
|
||||
.context_menu = undefined,
|
||||
.toast_overlay = undefined,
|
||||
@ -114,7 +119,7 @@ pub fn init(self: *Window, app: *App) !void {
|
||||
const box = c.gtk_box_new(c.GTK_ORIENTATION_VERTICAL, 0);
|
||||
|
||||
// If we are using an AdwWindow then we can support the tab overview.
|
||||
const tab_overview_: ?*c.GtkWidget = if (self.isAdwWindow()) overview: {
|
||||
self.tab_overview = if (self.isAdwWindow()) overview: {
|
||||
const tab_overview = c.adw_tab_overview_new();
|
||||
c.adw_tab_overview_set_enable_new_tab(@ptrCast(tab_overview), 1);
|
||||
_ = c.g_signal_connect_data(
|
||||
@ -152,14 +157,15 @@ pub fn init(self: *Window, app: *App) !void {
|
||||
c.gtk_widget_set_tooltip_text(btn, "Main Menu");
|
||||
c.gtk_menu_button_set_icon_name(@ptrCast(btn), "open-menu-symbolic");
|
||||
c.gtk_menu_button_set_menu_model(@ptrCast(btn), @ptrCast(@alignCast(app.menu)));
|
||||
if (self.isAdwWindow())
|
||||
c.adw_header_bar_pack_end(@ptrCast(header), btn)
|
||||
else
|
||||
c.gtk_header_bar_pack_end(@ptrCast(header), btn);
|
||||
if (self.isAdwWindow()) {
|
||||
if (comptime !adwaita.versionAtLeast(1, 4, 0)) unreachable;
|
||||
c.adw_header_bar_pack_end(@ptrCast(header), btn);
|
||||
} else c.gtk_header_bar_pack_end(@ptrCast(header), btn);
|
||||
}
|
||||
|
||||
// If we're using an AdwWindow then we can support the tab overview.
|
||||
if (tab_overview_) |tab_overview| {
|
||||
if (self.tab_overview) |tab_overview| {
|
||||
if (comptime !adwaita.versionAtLeast(1, 4, 0)) unreachable;
|
||||
assert(self.isAdwWindow());
|
||||
|
||||
const btn = c.gtk_toggle_button_new();
|
||||
@ -235,7 +241,8 @@ pub fn init(self: *Window, app: *App) !void {
|
||||
};
|
||||
|
||||
// If we have a tab overview then we can set it on our notebook.
|
||||
if (tab_overview_) |tab_overview| {
|
||||
if (self.tab_overview) |tab_overview| {
|
||||
if (comptime !adwaita.versionAtLeast(1, 4, 0)) unreachable;
|
||||
assert(self.notebook == .adw_tab_view);
|
||||
c.adw_tab_overview_set_view(@ptrCast(tab_overview), self.notebook.adw_tab_view);
|
||||
}
|
||||
@ -256,7 +263,8 @@ pub fn init(self: *Window, app: *App) !void {
|
||||
// Our actions for the menu
|
||||
initActions(self);
|
||||
|
||||
if (self.hasAdwToolbar()) {
|
||||
if (self.isAdwWindow()) {
|
||||
if (comptime !adwaita.versionAtLeast(1, 4, 0)) unreachable;
|
||||
const toolbar_view: *c.AdwToolbarView = @ptrCast(c.adw_toolbar_view_new());
|
||||
|
||||
const header_widget: *c.GtkWidget = @ptrCast(@alignCast(self.header.?));
|
||||
@ -289,7 +297,7 @@ pub fn init(self: *Window, app: *App) !void {
|
||||
|
||||
// Set our application window content. The content depends on if
|
||||
// we're using an AdwTabOverview or not.
|
||||
if (tab_overview_) |tab_overview| {
|
||||
if (self.tab_overview) |tab_overview| {
|
||||
c.adw_tab_overview_set_child(
|
||||
@ptrCast(tab_overview),
|
||||
@ptrCast(@alignCast(toolbar_view)),
|
||||
@ -391,18 +399,9 @@ pub fn deinit(self: *Window) void {
|
||||
/// paths that are not enabled.
|
||||
inline fn isAdwWindow(self: *Window) bool {
|
||||
return (comptime adwaita.versionAtLeast(1, 4, 0)) and
|
||||
adwaita.enabled(&self.app.config) and
|
||||
self.app.config.@"gtk-titlebar" and
|
||||
adwaita.versionAtLeast(1, 4, 0);
|
||||
}
|
||||
|
||||
/// This must be `inline` so that the comptime check noops conditional
|
||||
/// paths that are not enabled.
|
||||
inline fn hasAdwToolbar(self: *Window) bool {
|
||||
return ((comptime adwaita.versionAtLeast(1, 4, 0)) and
|
||||
adwaita.enabled(&self.app.config) and
|
||||
adwaita.versionAtLeast(1, 4, 0) and
|
||||
self.app.config.@"gtk-titlebar");
|
||||
self.app.config.@"gtk-titlebar";
|
||||
}
|
||||
|
||||
/// Add a new tab to this window.
|
||||
@ -458,6 +457,15 @@ pub fn gotoTab(self: *Window, n: usize) void {
|
||||
}
|
||||
}
|
||||
|
||||
/// Toggle tab overview (if present)
|
||||
pub fn toggleTabOverview(self: *Window) void {
|
||||
if (self.tab_overview) |tab_overview_widget| {
|
||||
if (comptime !adwaita.versionAtLeast(1, 4, 0)) unreachable;
|
||||
const tab_overview: *c.AdwTabOverview = @ptrCast(@alignCast(tab_overview_widget));
|
||||
c.adw_tab_overview_set_open(tab_overview, 1 - c.adw_tab_overview_get_open(tab_overview));
|
||||
}
|
||||
}
|
||||
|
||||
/// Toggle fullscreen for this window.
|
||||
pub fn toggleFullscreen(self: *Window) void {
|
||||
const is_fullscreen = c.gtk_window_is_fullscreen(self.window);
|
||||
|
@ -298,6 +298,10 @@ pub const Action = union(enum) {
|
||||
/// Go to the tab with the specific number, 1-indexed.
|
||||
goto_tab: usize,
|
||||
|
||||
/// Toggle the tab overview.
|
||||
/// This only works with libadwaita enabled currently.
|
||||
toggle_tab_overview: void,
|
||||
|
||||
/// Create a new split in the given direction. The new split will appear in
|
||||
/// the direction given.
|
||||
new_split: SplitDirection,
|
||||
@ -607,6 +611,7 @@ pub const Action = union(enum) {
|
||||
.next_tab,
|
||||
.last_tab,
|
||||
.goto_tab,
|
||||
.toggle_tab_overview,
|
||||
.new_split,
|
||||
.goto_split,
|
||||
.toggle_split_zoom,
|
||||
|
Reference in New Issue
Block a user