From 98380f3c42b114501e3b11099fb59389fa127fd4 Mon Sep 17 00:00:00 2001 From: Tristan Partin Date: Wed, 20 Nov 2024 23:39:12 -0600 Subject: [PATCH 1/2] apprt/gtk: abstract AdwHeaderBar and GtkHeaderBar This will make further changes a little bit more readable. Signed-off-by: Tristan Partin --- src/apprt/gtk/Window.zig | 26 ++++++---------- src/apprt/gtk/headerbar.zig | 61 +++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 17 deletions(-) create mode 100644 src/apprt/gtk/headerbar.zig diff --git a/src/apprt/gtk/Window.zig b/src/apprt/gtk/Window.zig index 2559d704a..32d989211 100644 --- a/src/apprt/gtk/Window.zig +++ b/src/apprt/gtk/Window.zig @@ -23,6 +23,7 @@ const c = @import("c.zig").c; const adwaita = @import("adwaita.zig"); const gtk_key = @import("key.zig"); const Notebook = @import("notebook.zig").Notebook; +const HeaderBar = @import("headerbar.zig").HeaderBar; const version = @import("version.zig"); const log = std.log.scoped(.gtk); @@ -35,7 +36,7 @@ window: *c.GtkWindow, /// The header bar for the window. This is possibly null since it can be /// disabled using gtk-titlebar. This is either an AdwHeaderBar or /// GtkHeaderBar depending on if adw is enabled and linked. -header: ?*c.GtkWidget, +header: ?HeaderBar, /// The tab overview for the window. This is possibly null since there is no /// taboverview without a AdwApplicationWindow (libadwaita >= 1.4.0). @@ -153,20 +154,14 @@ pub fn init(self: *Window, app: *App) !void { // are decorated or not because we can have a keybind to toggle the // decorations. if (app.config.@"gtk-titlebar") { - const header: *c.GtkWidget = if (self.isAdwWindow()) - @ptrCast(c.adw_header_bar_new()) - else - @ptrCast(c.gtk_header_bar_new()); + const header = HeaderBar.create(self); { const btn = c.gtk_menu_button_new(); 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()) { - 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); + header.packEnd(btn); } // If we're using an AdwWindow then we can support the tab overview. @@ -198,17 +193,14 @@ pub fn init(self: *Window, app: *App) !void { }; c.gtk_widget_set_focus_on_click(btn, c.FALSE); - c.adw_header_bar_pack_end(@ptrCast(header), btn); + header.packEnd(btn); } { const btn = c.gtk_button_new_from_icon_name("tab-new-symbolic"); c.gtk_widget_set_tooltip_text(btn, "New Tab"); _ = c.g_signal_connect_data(btn, "clicked", c.G_CALLBACK(>kTabNewClick), self, null, c.G_CONNECT_DEFAULT); - if (self.isAdwWindow()) - c.adw_header_bar_pack_end(@ptrCast(header), btn) - else - c.gtk_header_bar_pack_end(@ptrCast(header), btn); + header.packEnd(btn); } self.header = header; @@ -291,7 +283,7 @@ pub fn init(self: *Window, app: *App) !void { 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.?)); + const header_widget: *c.GtkWidget = self.header.?.asWidget(); c.adw_toolbar_view_add_top_bar(toolbar_view, header_widget); if (self.app.config.@"gtk-tabs-location" != .hidden) { @@ -374,7 +366,7 @@ pub fn init(self: *Window, app: *App) !void { // The box is our main child c.gtk_window_set_child(gtk_window, box); - if (self.header) |h| c.gtk_window_set_titlebar(gtk_window, @ptrCast(@alignCast(h))); + if (self.header) |h| c.gtk_window_set_titlebar(gtk_window, h.asWidget()); } // Show the window @@ -525,7 +517,7 @@ pub fn toggleWindowDecorations(self: *Window) void { // and hides it with decorations, but libadwaita doesn't. This makes it // explicit. if (self.header) |v| { - const widget: *c.GtkWidget = @alignCast(@ptrCast(v)); + const widget = v.asWidget(); c.gtk_widget_set_visible(widget, @intFromBool(new_decorated)); } } diff --git a/src/apprt/gtk/headerbar.zig b/src/apprt/gtk/headerbar.zig new file mode 100644 index 000000000..e60f7a04d --- /dev/null +++ b/src/apprt/gtk/headerbar.zig @@ -0,0 +1,61 @@ +const std = @import("std"); +const c = @import("c.zig").c; + +const Window = @import("Window.zig"); +const adwaita = @import("adwaita.zig"); + +const AdwHeaderBar = if (adwaita.versionAtLeast(0, 0, 0)) c.AdwHeaderBar else anyopaque; + +pub const HeaderBar = union(enum) { + adw: *AdwHeaderBar, + gtk: *c.GtkHeaderBar, + + pub fn create(window: *Window) HeaderBar { + const app = window.app; + + if (comptime adwaita.versionAtLeast(1, 4, 0)) { + if (adwaita.enabled(&app.config)) return initAdw(); + } + + return initGtk(); + } + + fn initAdw() HeaderBar { + const headerbar = c.adw_header_bar_new(); + + return .{ .adw = @ptrCast(headerbar) }; + } + + fn initGtk() HeaderBar { + const headerbar = c.gtk_header_bar_new(); + + return .{ .gtk = @ptrCast(headerbar) }; + } + + pub fn asWidget(self: HeaderBar) *c.GtkWidget { + return switch (self) { + .adw => |headerbar| @ptrCast(@alignCast(headerbar)), + .gtk => |headerbar| @ptrCast(@alignCast(headerbar)), + }; + } + + pub fn packEnd(self: HeaderBar, widget: *c.GtkWidget) void { + switch (self) { + .adw => |headerbar| if (comptime adwaita.versionAtLeast(0, 0, 0)) + c.adw_header_bar_pack_end(@ptrCast(@alignCast(headerbar)), widget) + else + unreachable, + .gtk => |headerbar| c.gtk_header_bar_pack_end(@ptrCast(@alignCast(headerbar)), widget), + } + } + + pub fn packStart(self: HeaderBar, widget: *c.GtkWidget) void { + switch (self) { + .adw => |headerbar| if (comptime adwaita.versionAtLeast(0, 0, 0)) + c.adw_header_bar_pack_start(@ptrCast(@alignCast(headerbar)), widget) + else + unreachable, + .gtk => |headerbar| c.gtk_header_bar_pack_start(@ptrCast(@alignCast(headerbar)), widget), + } + } +}; From fdd330d22d409135299adc3958694f7a73818b18 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 15 Dec 2024 13:59:02 -0800 Subject: [PATCH 2/2] apprt/gtk: stylistic changes --- src/apprt/gtk/Window.zig | 2 +- src/apprt/gtk/headerbar.zig | 44 ++++++++++++++++++++++--------------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/apprt/gtk/Window.zig b/src/apprt/gtk/Window.zig index 32d989211..0f6a14c8c 100644 --- a/src/apprt/gtk/Window.zig +++ b/src/apprt/gtk/Window.zig @@ -154,7 +154,7 @@ pub fn init(self: *Window, app: *App) !void { // are decorated or not because we can have a keybind to toggle the // decorations. if (app.config.@"gtk-titlebar") { - const header = HeaderBar.create(self); + const header = HeaderBar.init(self); { const btn = c.gtk_menu_button_new(); diff --git a/src/apprt/gtk/headerbar.zig b/src/apprt/gtk/headerbar.zig index e60f7a04d..b1567ce27 100644 --- a/src/apprt/gtk/headerbar.zig +++ b/src/apprt/gtk/headerbar.zig @@ -4,17 +4,17 @@ const c = @import("c.zig").c; const Window = @import("Window.zig"); const adwaita = @import("adwaita.zig"); -const AdwHeaderBar = if (adwaita.versionAtLeast(0, 0, 0)) c.AdwHeaderBar else anyopaque; +const AdwHeaderBar = if (adwaita.versionAtLeast(0, 0, 0)) c.AdwHeaderBar else void; pub const HeaderBar = union(enum) { adw: *AdwHeaderBar, gtk: *c.GtkHeaderBar, - pub fn create(window: *Window) HeaderBar { - const app = window.app; - - if (comptime adwaita.versionAtLeast(1, 4, 0)) { - if (adwaita.enabled(&app.config)) return initAdw(); + pub fn init(window: *Window) HeaderBar { + if ((comptime adwaita.versionAtLeast(1, 4, 0)) and + adwaita.enabled(&window.app.config)) + { + return initAdw(); } return initGtk(); @@ -22,13 +22,11 @@ pub const HeaderBar = union(enum) { fn initAdw() HeaderBar { const headerbar = c.adw_header_bar_new(); - return .{ .adw = @ptrCast(headerbar) }; } fn initGtk() HeaderBar { const headerbar = c.gtk_header_bar_new(); - return .{ .gtk = @ptrCast(headerbar) }; } @@ -41,21 +39,31 @@ pub const HeaderBar = union(enum) { pub fn packEnd(self: HeaderBar, widget: *c.GtkWidget) void { switch (self) { - .adw => |headerbar| if (comptime adwaita.versionAtLeast(0, 0, 0)) - c.adw_header_bar_pack_end(@ptrCast(@alignCast(headerbar)), widget) - else - unreachable, - .gtk => |headerbar| c.gtk_header_bar_pack_end(@ptrCast(@alignCast(headerbar)), widget), + .adw => |headerbar| if (comptime adwaita.versionAtLeast(0, 0, 0)) { + c.adw_header_bar_pack_end( + @ptrCast(@alignCast(headerbar)), + widget, + ); + }, + .gtk => |headerbar| c.gtk_header_bar_pack_end( + @ptrCast(@alignCast(headerbar)), + widget, + ), } } pub fn packStart(self: HeaderBar, widget: *c.GtkWidget) void { switch (self) { - .adw => |headerbar| if (comptime adwaita.versionAtLeast(0, 0, 0)) - c.adw_header_bar_pack_start(@ptrCast(@alignCast(headerbar)), widget) - else - unreachable, - .gtk => |headerbar| c.gtk_header_bar_pack_start(@ptrCast(@alignCast(headerbar)), widget), + .adw => |headerbar| if (comptime adwaita.versionAtLeast(0, 0, 0)) { + c.adw_header_bar_pack_start( + @ptrCast(@alignCast(headerbar)), + widget, + ); + }, + .gtk => |headerbar| c.gtk_header_bar_pack_start( + @ptrCast(@alignCast(headerbar)), + widget, + ), } } };