mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 01:06:08 +03:00
apprt/gtk: use AdwTabOverview
An additional way to manage tabs. Signed-off-by: Tristan Partin <tristan@partin.io>
This commit is contained in:

committed by
Mitchell Hashimoto

parent
423d25ac93
commit
f35671417c
@ -37,6 +37,10 @@ elem: Surface.Container.Elem,
|
||||
// can easily re-focus that terminal.
|
||||
focus_child: *Surface,
|
||||
|
||||
/// If the notebook implementation is AdwTabView, then this is the tab's
|
||||
/// AdwTabPage.
|
||||
tab_page: *c.GObject,
|
||||
|
||||
pub fn create(alloc: Allocator, window: *Window, parent_: ?*CoreSurface) !*Tab {
|
||||
var tab = try alloc.create(Tab);
|
||||
errdefer alloc.destroy(tab);
|
||||
@ -53,6 +57,7 @@ pub fn init(self: *Tab, window: *Window, parent_: ?*CoreSurface) !void {
|
||||
.box = undefined,
|
||||
.elem = undefined,
|
||||
.focus_child = undefined,
|
||||
.tab_page = undefined,
|
||||
};
|
||||
|
||||
// Create a Box in which we'll later keep either Surface or Split.
|
||||
@ -76,7 +81,7 @@ pub fn init(self: *Tab, window: *Window, parent_: ?*CoreSurface) !void {
|
||||
|
||||
// Set the userdata of the box to point to this tab.
|
||||
c.g_object_set_data(@ptrCast(box_widget), GHOSTTY_TAB, self);
|
||||
try window.notebook.addTab(self, "Ghostty");
|
||||
self.tab_page = try window.notebook.addTab(self, "Ghostty");
|
||||
|
||||
// Attach all events
|
||||
_ = c.g_signal_connect_data(box_widget, "destroy", c.G_CALLBACK(>kDestroy), self, null, c.G_CONNECT_DEFAULT);
|
||||
|
@ -97,6 +97,16 @@ pub fn init(self: *Window, app: *App) !void {
|
||||
const display = c.gdk_display_get_default();
|
||||
c.gtk_style_context_add_provider_for_display(display, @ptrCast(app.css_provider), c.GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
|
||||
// Create our box which will hold our widgets.
|
||||
const box = c.gtk_box_new(c.GTK_ORIENTATION_VERTICAL, 0);
|
||||
|
||||
var tab_overview: *c.GtkWidget = undefined;
|
||||
if (self.isAdwWindow()) {
|
||||
tab_overview = c.adw_tab_overview_new();
|
||||
c.adw_tab_overview_set_enable_new_tab(@ptrCast(tab_overview), 1);
|
||||
_ = c.g_signal_connect_data(tab_overview, "create-tab", c.G_CALLBACK(&newTabFromOverview), self, null, c.G_CONNECT_DEFAULT);
|
||||
}
|
||||
|
||||
// gtk-titlebar can be used to disable the header bar (but keep
|
||||
// the window manager's decorations). We create this no matter if we
|
||||
// are decorated or not because we can have a keybind to toggle the
|
||||
@ -117,6 +127,14 @@ pub fn init(self: *Window, app: *App) !void {
|
||||
else
|
||||
c.gtk_header_bar_pack_end(@ptrCast(header), btn);
|
||||
}
|
||||
if (self.isAdwWindow()) {
|
||||
const btn = c.gtk_toggle_button_new();
|
||||
c.gtk_widget_set_tooltip_text(btn, "Show Open Tabs");
|
||||
c.gtk_button_set_icon_name(@ptrCast(btn), "view-grid-symbolic");
|
||||
c.gtk_widget_set_focus_on_click(btn, c.FALSE);
|
||||
c.adw_header_bar_pack_end(@ptrCast(header), btn);
|
||||
_ = c.g_object_bind_property(btn, "active", tab_overview, "open", c.G_BINDING_BIDIRECTIONAL | c.G_BINDING_SYNC_CREATE);
|
||||
}
|
||||
{
|
||||
const btn = c.gtk_button_new_from_icon_name("tab-new-symbolic");
|
||||
c.gtk_widget_set_tooltip_text(btn, "New Tab");
|
||||
@ -135,9 +153,6 @@ pub fn init(self: *Window, app: *App) !void {
|
||||
c.gtk_window_set_decorated(gtk_window, 0);
|
||||
}
|
||||
|
||||
// Create our box which will hold our widgets.
|
||||
const box = c.gtk_box_new(c.GTK_ORIENTATION_VERTICAL, 0);
|
||||
|
||||
// In debug we show a warning and apply the 'devel' class to the window.
|
||||
// This is a really common issue where people build from source in debug and performance is really bad.
|
||||
if (comptime std.debug.runtime_safety) {
|
||||
@ -180,6 +195,7 @@ pub fn init(self: *Window, app: *App) !void {
|
||||
initActions(self);
|
||||
|
||||
if (self.hasAdwToolbar()) {
|
||||
c.adw_tab_overview_set_view(@ptrCast(tab_overview), self.notebook.adw_tab_view);
|
||||
const toolbar_view: *c.AdwToolbarView = @ptrCast(c.adw_toolbar_view_new());
|
||||
|
||||
const header_widget: *c.GtkWidget = @ptrCast(@alignCast(self.header.?));
|
||||
@ -210,7 +226,8 @@ pub fn init(self: *Window, app: *App) !void {
|
||||
c.gtk_widget_set_visible(header_widget, 0);
|
||||
}
|
||||
|
||||
c.adw_application_window_set_content(@ptrCast(gtk_window), @ptrCast(@alignCast(toolbar_view)));
|
||||
c.adw_tab_overview_set_child(@ptrCast(tab_overview), @ptrCast(@alignCast(toolbar_view)));
|
||||
c.adw_application_window_set_content(@ptrCast(gtk_window), @ptrCast(@alignCast(tab_overview)));
|
||||
} else {
|
||||
// The box is our main child
|
||||
c.gtk_window_set_child(gtk_window, box);
|
||||
@ -379,6 +396,16 @@ fn gtkTabNewClick(_: *c.GtkButton, ud: ?*anyopaque) callconv(.C) void {
|
||||
};
|
||||
}
|
||||
|
||||
/// Create a new tab from the AdwTabOverview. We can't copy gtkTabNewClick
|
||||
/// because we need to return an AdwTabPage from this function.
|
||||
fn newTabFromOverview(_: *c.GtkWidget, ud: ?*anyopaque) callconv(.C) ?*c.GObject {
|
||||
const self: *Window = @ptrCast(@alignCast(ud orelse return null));
|
||||
const alloc = self.app.core_app.alloc;
|
||||
const surface = self.actionSurface() orelse return null;
|
||||
const tab = Tab.create(alloc, self, surface) catch return null;
|
||||
return tab.tab_page;
|
||||
}
|
||||
|
||||
fn gtkRefocusTerm(v: *c.GtkWindow, ud: ?*anyopaque) callconv(.C) bool {
|
||||
_ = v;
|
||||
log.debug("refocus term request", .{});
|
||||
|
@ -198,8 +198,9 @@ pub const Notebook = union(enum) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn addTab(self: Notebook, tab: *Tab, title: [:0]const u8) !void {
|
||||
pub fn addTab(self: Notebook, tab: *Tab, title: [:0]const u8) !*c.GObject {
|
||||
const box_widget: *c.GtkWidget = @ptrCast(tab.box);
|
||||
var tab_page: *c.GObject = undefined;
|
||||
switch (self) {
|
||||
.adw_tab_view => |tab_view| {
|
||||
if (comptime !adwaita.versionAtLeast(0, 0, 0)) unreachable;
|
||||
@ -209,6 +210,8 @@ pub const Notebook = union(enum) {
|
||||
|
||||
// Switch to the new tab
|
||||
c.adw_tab_view_set_selected_page(tab_view, page);
|
||||
|
||||
tab_page = @ptrCast(@alignCast(page));
|
||||
},
|
||||
.gtk_notebook => |notebook| {
|
||||
// Build the tab label
|
||||
@ -267,6 +270,8 @@ pub const Notebook = union(enum) {
|
||||
c.gtk_notebook_set_current_page(notebook, page_idx);
|
||||
},
|
||||
}
|
||||
|
||||
return tab_page;
|
||||
}
|
||||
|
||||
pub fn closeTab(self: Notebook, tab: *Tab) void {
|
||||
|
Reference in New Issue
Block a user