From 7f3724ec6f7ba90174d3946b0b69f2854f1381cd Mon Sep 17 00:00:00 2001 From: "Jeffrey C. Ollie" Date: Mon, 27 Jan 2025 10:46:31 -0600 Subject: [PATCH] gtk/adw: add context menu to tab titles to rename tab --- src/apprt/gtk/RenameTabAdw.zig | 124 ++++++++++++++++++++++ src/apprt/gtk/Surface.zig | 2 +- src/apprt/gtk/Tab.zig | 53 ++++++++- src/apprt/gtk/Window.zig | 11 ++ src/apprt/gtk/builder_check.zig | 10 ++ src/apprt/gtk/gresource.zig | 2 + src/apprt/gtk/notebook.zig | 21 +++- src/apprt/gtk/notebook_adw.zig | 92 ++++++++++++---- src/apprt/gtk/notebook_gtk.zig | 6 +- src/apprt/gtk/ui/menu-adw-notebook-tab.ui | 13 +++ src/apprt/gtk/ui/window-adw-rename-tab.ui | 33 ++++++ src/build/SharedDeps.zig | 2 + 12 files changed, 337 insertions(+), 32 deletions(-) create mode 100644 src/apprt/gtk/RenameTabAdw.zig create mode 100644 src/apprt/gtk/ui/menu-adw-notebook-tab.ui create mode 100644 src/apprt/gtk/ui/window-adw-rename-tab.ui diff --git a/src/apprt/gtk/RenameTabAdw.zig b/src/apprt/gtk/RenameTabAdw.zig new file mode 100644 index 000000000..8e78a7f4d --- /dev/null +++ b/src/apprt/gtk/RenameTabAdw.zig @@ -0,0 +1,124 @@ +const RenameTabAdw = @This(); + +const std = @import("std"); +const assert = std.debug.assert; + +const c = @import("c.zig").c; +const Builder = @import("Builder.zig"); +const Tab = @import("Tab.zig"); +const NotebookAdw = @import("notebook_adw.zig").NotebookAdw; + +const log = std.log.scoped(.gtk_rename_tab); + +tab: ?*Tab = null, +dialog: ?*c.AdwDialog = null, +title: ?*c.AdwEntryRow = null, + +pub fn init(self: *RenameTabAdw) void { + self.* = .{}; +} + +pub fn deinit(self: *RenameTabAdw) void { + if (self.dialog) |dialog| { + _ = c.adw_dialog_close(dialog); + } +} + +pub fn show(self: *RenameTabAdw, tab: *Tab) void { + if (self.tab) |old_tab| { + if (old_tab == tab) { + if (self.dialog) |dialog| { + c.gtk_window_present(@ptrCast(@alignCast(dialog))); + return; + } + } + } + + if (self.dialog) |dialog| { + _ = c.adw_dialog_close(dialog); + } + + self.* = .{}; + + assert(tab.window.notebook == .adw); + + const builder = Builder.init("window-adw-rename-tab"); + defer builder.deinit(); + + const dialog = builder.getObject(c.AdwDialog, "rename-tab"); + + const title = builder.getObject(c.AdwEntryRow, "title"); + + if (tab.manual_title) |manual_label| { + var value: c.GValue = std.mem.zeroes(c.GValue); + defer c.g_value_unset(&value); + _ = c.g_value_init(&value, c.G_TYPE_STRING); + c.g_value_set_string(&value, manual_label.ptr); + c.g_object_set_property(@ptrCast(@alignCast(title)), "text", &value); + } + + self.* = .{ + .tab = tab, + .dialog = dialog, + .title = title, + }; + + _ = c.g_signal_connect_data(dialog, "closed", c.G_CALLBACK(&adwDialogClosed), self, null, c.G_CONNECT_DEFAULT); + _ = c.g_signal_connect_data(title, "apply", c.G_CALLBACK(&adwEntryRowApply), self, null, c.G_CONNECT_DEFAULT); + _ = c.g_signal_connect_data(title, "entry-activated", c.G_CALLBACK(&adwEntryRowApply), self, null, c.G_CONNECT_DEFAULT); + + c.adw_dialog_present(dialog, @ptrCast(@alignCast(tab.box))); +} + +fn adwDialogClosed(dialog: *c.AdwDialog, ud: ?*anyopaque) callconv(.C) void { + const self: *RenameTabAdw = @ptrCast(@alignCast(ud orelse return)); + + assert(dialog == self.dialog); + + if (self.tab) |tab| { + tab.window.focusCurrentTab(); + } + + self.* = .{}; +} + +fn adwEntryRowApply( + _: *c.GObject, + ud: ?*anyopaque, +) callconv(.C) void { + const self: *RenameTabAdw = @ptrCast(@alignCast(ud orelse return)); + const tab = self.tab orelse return; + const title = self.title orelse return; + + var value: c.GValue = std.mem.zeroes(c.GValue); + defer c.g_value_unset(&value); + _ = c.g_value_init(&value, c.G_TYPE_STRING); + c.g_object_get_property(@ptrCast(@alignCast(title)), "text", &value); + + const text = c.g_value_get_string(&value); + + tab.setManualTitle(std.mem.span(text)); + + _ = c.adw_dialog_close(self.dialog); +} + +fn adwEntryRowEntryActivated( + _: *c.GObject, + ud: ?*anyopaque, +) callconv(.C) void { + const self: *RenameTabAdw = @ptrCast(@alignCast(ud orelse return)); + const tab = self.tab orelse return; + const title = self.title orelse return; + + var value: c.GValue = std.mem.zeroes(c.GValue); + defer c.g_value_unset(&value); + _ = c.g_value_init(&value, c.G_TYPE_STRING); + + c.g_object_get_property(@ptrCast(@alignCast(title)), "text", &value); + + const text = c.g_value_get_string(&value); + + tab.setManualTitle(std.mem.span(text)); + + _ = c.adw_dialog_close(self.dialog); +} diff --git a/src/apprt/gtk/Surface.zig b/src/apprt/gtk/Surface.zig index bff1529d5..348cf33d4 100644 --- a/src/apprt/gtk/Surface.zig +++ b/src/apprt/gtk/Surface.zig @@ -908,7 +908,7 @@ fn updateTitleLabels(self: *Surface) void { // If we have a tab and are the focused child, then we have to update the tab if (self.container.tab()) |tab| { - if (tab.focus_child == self) tab.setLabelText(title); + if (tab.focus_child == self) tab.setTitleText(title); } // If we have a window and are focused, then we have to update the window title. diff --git a/src/apprt/gtk/Tab.zig b/src/apprt/gtk/Tab.zig index d320daa7c..e97948f7f 100644 --- a/src/apprt/gtk/Tab.zig +++ b/src/apprt/gtk/Tab.zig @@ -37,6 +37,12 @@ elem: Surface.Container.Elem, // can easily re-focus that terminal. focus_child: ?*Surface, +/// Manually set title, will override titles set by ESC sequences. +manual_title: ?[:0]const u8 = null, + +/// The last title set by ESC sequences. +auto_title: ?[:0]const u8 = null, + pub fn create(alloc: Allocator, window: *Window, parent_: ?*CoreSurface) !*Tab { var tab = try alloc.create(Tab); errdefer alloc.destroy(tab); @@ -88,6 +94,8 @@ pub fn init(self: *Tab, window: *Window, parent_: ?*CoreSurface) !void { /// Deinits tab by deiniting child elem. pub fn deinit(self: *Tab, alloc: Allocator) void { + if (self.manual_title) |manual_title| alloc.free(manual_title); + if (self.auto_title) |auto_title| alloc.free(auto_title); self.elem.deinit(alloc); } @@ -108,8 +116,49 @@ pub fn replaceElem(self: *Tab, elem: Surface.Container.Elem) void { self.elem = elem; } -pub fn setLabelText(self: *Tab, title: [:0]const u8) void { - self.window.notebook.setTabLabel(self, title); +pub fn setManualTitle(self: *Tab, title: []const u8) void { + const alloc = self.window.app.core_app.alloc; + + self.unsetManualTitle(); + + const stripped = std.mem.trim(u8, title, &std.ascii.whitespace); + if (stripped.len == 0) { + if (self.auto_title) |auto_title| { + self.window.notebook.setTabTitle(self, auto_title); + } + return; + } + + const manual_title = alloc.dupeZ(u8, title) catch |err| { + log.warn("unable to copy manual title: {}", .{err}); + return; + }; + self.manual_title = manual_title; + + self.window.notebook.setTabTitle(self, manual_title); +} + +pub fn unsetManualTitle(self: *Tab) void { + const alloc = self.window.app.core_app.alloc; + + if (self.manual_title) |manual_title| { + alloc.free(manual_title); + self.manual_title = null; + } +} + +pub fn setTitleText(self: *Tab, title: [:0]const u8) void { + const alloc = self.window.app.core_app.alloc; + if (self.manual_title) |manual_title| { + self.window.notebook.setTabTitle(self, manual_title); + return; + } + if (self.auto_title) |auto_title| { + alloc.free(auto_title); + self.auto_title = null; + } + self.auto_title = alloc.dupeZ(u8, title) catch null; + self.window.notebook.setTabTitle(self, title); } pub fn setTooltipText(self: *Tab, tooltip: [:0]const u8) void { diff --git a/src/apprt/gtk/Window.zig b/src/apprt/gtk/Window.zig index bfccc7072..096e6aa6c 100644 --- a/src/apprt/gtk/Window.zig +++ b/src/apprt/gtk/Window.zig @@ -510,6 +510,7 @@ fn initActions(self: *Window) void { .{ "paste", >kActionPaste }, .{ "reset", >kActionReset }, .{ "clear", >kActionClear }, + .{ "rename-tab", >kActionRenameTab }, }; inline for (actions) |entry| { @@ -528,6 +529,7 @@ fn initActions(self: *Window) void { } pub fn deinit(self: *Window) void { + self.notebook.deinit(); self.winproto.deinit(self.app.core_app.alloc); if (self.adw_tab_overview_focus_timer) |timer| { @@ -1138,6 +1140,15 @@ fn gtkActionClear( }; } +fn gtkActionRenameTab( + _: *c.GSimpleAction, + _: *c.GVariant, + ud: ?*anyopaque, +) callconv(.C) void { + const self: *Window = @ptrCast(@alignCast(ud orelse return)); + self.notebook.showRenameTab(); +} + /// Returns the surface to use for an action. pub fn actionSurface(self: *Window) ?*CoreSurface { const tab = self.notebook.currentTab() orelse return null; diff --git a/src/apprt/gtk/builder_check.zig b/src/apprt/gtk/builder_check.zig index a4d330f19..0a8e61482 100644 --- a/src/apprt/gtk/builder_check.zig +++ b/src/apprt/gtk/builder_check.zig @@ -1,7 +1,11 @@ const std = @import("std"); +const build_options = @import("build_options"); pub const c = @cImport({ @cInclude("gtk/gtk.h"); + if (build_options.adwaita) { + @cInclude("libadwaita-1/adwaita.h"); + } }); pub fn main() !void { @@ -17,6 +21,12 @@ pub fn main() !void { }; defer alloc.free(filename); + if (comptime build_options.adwaita) { + c.adw_init(); + } else { + if (std.mem.indexOf(u8, filename, "adw")) |_| return; + } + const builder = c.gtk_builder_new_from_file(filename.ptr); defer c.g_object_unref(builder); } diff --git a/src/apprt/gtk/gresource.zig b/src/apprt/gtk/gresource.zig index 7ab6db61b..ed96612f2 100644 --- a/src/apprt/gtk/gresource.zig +++ b/src/apprt/gtk/gresource.zig @@ -54,9 +54,11 @@ const icons = [_]struct { }; pub const ui_files = [_][]const u8{ + "menu-adw-notebook-tab", "menu-surface-context_menu", "menu-window-menubar", "menu-window-titlebar_menu", + "window-adw-rename-tab", }; pub const gresource_xml = comptimeGenerateGResourceXML(); diff --git a/src/apprt/gtk/notebook.zig b/src/apprt/gtk/notebook.zig index 4676c2529..3767eee5d 100644 --- a/src/apprt/gtk/notebook.zig +++ b/src/apprt/gtk/notebook.zig @@ -12,8 +12,6 @@ const log = std.log.scoped(.gtk); const AdwTabView = if (adwaita.versionAtLeast(0, 0, 0)) c.AdwTabView else anyopaque; -/// An abstraction over the GTK notebook and Adwaita tab view to manage -/// all the terminal tabs in a window. /// An abstraction over the GTK notebook and Adwaita tab view to manage /// all the terminal tabs in a window. pub const Notebook = union(enum) { @@ -28,6 +26,12 @@ pub const Notebook = union(enum) { return NotebookGtk.init(self); } + pub fn deinit(self: *Notebook) void { + switch (self.*) { + inline else => |*n| n.deinit(), + } + } + pub fn asWidget(self: *Notebook) *c.GtkWidget { return switch (self.*) { .adw => |*adw| adw.asWidget(), @@ -121,10 +125,10 @@ pub const Notebook = union(enum) { } } - pub fn setTabLabel(self: *Notebook, tab: *Tab, title: [:0]const u8) void { + pub fn setTabTitle(self: *Notebook, tab: *Tab, title: [:0]const u8) void { switch (self.*) { - .adw => |*adw| adw.setTabLabel(tab, title), - .gtk => |*gtk| gtk.setTabLabel(tab, title), + .adw => |*adw| adw.setTabTitle(tab, title), + .gtk => |*gtk| gtk.setTabTitle(tab, title), } } @@ -158,6 +162,13 @@ pub const Notebook = union(enum) { .gtk => |*gtk| gtk.closeTab(tab), } } + + pub fn showRenameTab(self: *Notebook) void { + switch (self.*) { + .adw => |*adw| adw.showRenameTab(), + .gtk => {}, + } + } }; pub fn createWindow(currentWindow: *Window) !*Window { diff --git a/src/apprt/gtk/notebook_adw.zig b/src/apprt/gtk/notebook_adw.zig index 790b3aa35..6917e398e 100644 --- a/src/apprt/gtk/notebook_adw.zig +++ b/src/apprt/gtk/notebook_adw.zig @@ -7,6 +7,8 @@ const Tab = @import("Tab.zig"); const Notebook = @import("notebook.zig").Notebook; const createWindow = @import("notebook.zig").createWindow; const adwaita = @import("adwaita.zig"); +const Builder = @import("Builder.zig"); +const RenameTabAdw = if (adwaita.versionAtLeast(0, 0, 0)) @import("RenameTabAdw.zig") else struct {}; const log = std.log.scoped(.gtk); @@ -14,6 +16,9 @@ const AdwTabView = if (adwaita.versionAtLeast(0, 0, 0)) c.AdwTabView else anyopa const AdwTabPage = if (adwaita.versionAtLeast(0, 0, 0)) c.AdwTabPage else anyopaque; pub const NotebookAdw = struct { + /// The window that we belong to + window: *Window, + /// the tab view tab_view: *AdwTabView, @@ -25,7 +30,14 @@ pub const NotebookAdw = struct { /// confirming or not. forcing_close: bool = false, + /// The last tab that was selected with the "setup-menu" signal. + last_setup_menu_tab: ?*Tab = null, + + /// rename tab window + rename_tab: RenameTabAdw = .{}, + pub fn init(notebook: *Notebook) void { + if (comptime !adwaita.versionAtLeast(0, 0, 0)) unreachable; const window: *Window = @fieldParentPtr("notebook", notebook); const app = window.app; assert(adwaita.enabled(&app.config)); @@ -33,33 +45,46 @@ pub const NotebookAdw = struct { const tab_view: *c.AdwTabView = c.adw_tab_view_new().?; c.gtk_widget_add_css_class(@ptrCast(@alignCast(tab_view)), "notebook"); - if (comptime adwaita.versionAtLeast(1, 2, 0) and adwaita.versionAtLeast(1, 2, 0)) { + if (adwaita.versionAtLeast(1, 2, 0)) { // Adwaita enables all of the shortcuts by default. // We want to manage keybindings ourselves. c.adw_tab_view_remove_shortcuts(tab_view, c.ADW_TAB_VIEW_SHORTCUT_ALL_SHORTCUTS); } + const builder = Builder.init("menu-adw-notebook-tab"); + defer builder.deinit(); + + c.adw_tab_view_set_menu_model(tab_view, builder.getObject(c.GMenuModel, "menu")); + notebook.* = .{ .adw = .{ + .window = window, .tab_view = tab_view, }, }; - _ = c.g_signal_connect_data(tab_view, "page-attached", c.G_CALLBACK(&adwPageAttached), window, null, c.G_CONNECT_DEFAULT); - _ = c.g_signal_connect_data(tab_view, "close-page", c.G_CALLBACK(&adwClosePage), window, null, c.G_CONNECT_DEFAULT); - _ = c.g_signal_connect_data(tab_view, "create-window", c.G_CALLBACK(&adwTabViewCreateWindow), window, null, c.G_CONNECT_DEFAULT); - _ = c.g_signal_connect_data(tab_view, "notify::selected-page", c.G_CALLBACK(&adwSelectPage), window, null, c.G_CONNECT_DEFAULT); + const self = ¬ebook.adw; + + _ = c.g_signal_connect_data(tab_view, "page-attached", c.G_CALLBACK(&adwPageAttached), self, null, c.G_CONNECT_DEFAULT); + _ = c.g_signal_connect_data(tab_view, "close-page", c.G_CALLBACK(&adwClosePage), self, null, c.G_CONNECT_DEFAULT); + _ = c.g_signal_connect_data(tab_view, "create-window", c.G_CALLBACK(&adwTabViewCreateWindow), self, null, c.G_CONNECT_DEFAULT); + _ = c.g_signal_connect_data(tab_view, "notify::selected-page", c.G_CALLBACK(&adwSelectPage), self, null, c.G_CONNECT_DEFAULT); + _ = c.g_signal_connect_data(tab_view, "setup-menu", c.G_CALLBACK(&adwTabViewSetupMenu), self, null, c.G_CONNECT_DEFAULT); + } + + pub fn deinit(self: *NotebookAdw) void { + if (comptime !adwaita.versionAtLeast(0, 0, 0)) unreachable; + self.rename_tab.deinit(); } pub fn asWidget(self: *NotebookAdw) *c.GtkWidget { + if (comptime !adwaita.versionAtLeast(0, 0, 0)) unreachable; return @ptrCast(@alignCast(self.tab_view)); } pub fn nPages(self: *NotebookAdw) c_int { - if (comptime adwaita.versionAtLeast(0, 0, 0)) - return c.adw_tab_view_get_n_pages(self.tab_view) - else - unreachable; + if (comptime !adwaita.versionAtLeast(0, 0, 0)) unreachable; + return c.adw_tab_view_get_n_pages(self.tab_view); } /// Returns the index of the currently selected page. @@ -98,7 +123,7 @@ pub const NotebookAdw = struct { _ = c.adw_tab_view_reorder_page(self.tab_view, page, position); } - pub fn setTabLabel(self: *NotebookAdw, tab: *Tab, title: [:0]const u8) void { + pub fn setTabTitle(self: *NotebookAdw, tab: *Tab, title: [:0]const u8) void { if (comptime !adwaita.versionAtLeast(0, 0, 0)) unreachable; const page = c.adw_tab_view_get_page(self.tab_view, @ptrCast(tab.box)); c.adw_tab_page_set_title(page, title.ptr); @@ -155,16 +180,23 @@ pub const NotebookAdw = struct { c.gtk_window_destroy(window); } } + + pub fn showRenameTab(self: *NotebookAdw) void { + if (comptime !adwaita.versionAtLeast(0, 0, 0)) unreachable; + const tab = self.last_setup_menu_tab orelse return; + assert(tab.window == self.window); + self.rename_tab.show(tab); + } }; fn adwPageAttached(_: *AdwTabView, page: *c.AdwTabPage, _: c_int, ud: ?*anyopaque) callconv(.C) void { - const window: *Window = @ptrCast(@alignCast(ud.?)); + const self: *NotebookAdw = @ptrCast(@alignCast(ud orelse return)); const child = c.adw_tab_page_get_child(page); const tab: *Tab = @ptrCast(@alignCast(c.g_object_get_data(@ptrCast(child), Tab.GHOSTTY_TAB) orelse return)); - tab.window = window; + tab.window = self.window; - window.focusCurrentTab(); + self.window.focusCurrentTab(); } fn adwClosePage( @@ -172,20 +204,20 @@ fn adwClosePage( page: *c.AdwTabPage, ud: ?*anyopaque, ) callconv(.C) c.gboolean { + const self: *NotebookAdw = @ptrCast(@alignCast(ud orelse return 0)); + const child = c.adw_tab_page_get_child(page); const tab: *Tab = @ptrCast(@alignCast(c.g_object_get_data( @ptrCast(child), Tab.GHOSTTY_TAB, ) orelse return 0)); - const window: *Window = @ptrCast(@alignCast(ud.?)); - const notebook = window.notebook.adw; c.adw_tab_view_close_page_finish( - notebook.tab_view, + self.tab_view, page, - @intFromBool(notebook.forcing_close), + @intFromBool(self.forcing_close), ); - if (!notebook.forcing_close) tab.closeWithConfirmation(); + if (!self.forcing_close) tab.closeWithConfirmation(); return 1; } @@ -193,8 +225,8 @@ fn adwTabViewCreateWindow( _: *AdwTabView, ud: ?*anyopaque, ) callconv(.C) ?*AdwTabView { - const currentWindow: *Window = @ptrCast(@alignCast(ud.?)); - const window = createWindow(currentWindow) catch |err| { + const self: *NotebookAdw = @ptrCast(@alignCast(ud orelse return null)); + const window = createWindow(self.window) catch |err| { log.warn("error creating new window error={}", .{err}); return null; }; @@ -202,8 +234,22 @@ fn adwTabViewCreateWindow( } fn adwSelectPage(_: *c.GObject, _: *c.GParamSpec, ud: ?*anyopaque) void { - const window: *Window = @ptrCast(@alignCast(ud.?)); - const page = c.adw_tab_view_get_selected_page(window.notebook.adw.tab_view) orelse return; + const self: *NotebookAdw = @ptrCast(@alignCast(ud orelse return)); + + const page = c.adw_tab_view_get_selected_page(self.tab_view) orelse return; const title = c.adw_tab_page_get_title(page); - window.setTitle(std.mem.span(title)); + self.window.setTitle(std.mem.span(title)); +} + +fn adwTabViewSetupMenu(tab_view: *AdwTabView, page: *AdwTabPage, ud: ?*anyopaque) callconv(.C) void { + const self: *NotebookAdw = @ptrCast(@alignCast(ud orelse return)); + + assert(self.tab_view == tab_view); + + const child = c.adw_tab_page_get_child(page); + const tab: *Tab = @ptrCast(@alignCast( + c.g_object_get_data(@ptrCast(child), Tab.GHOSTTY_TAB) orelse return, + )); + + self.last_setup_menu_tab = tab; } diff --git a/src/apprt/gtk/notebook_gtk.zig b/src/apprt/gtk/notebook_gtk.zig index 5f145dc84..4730d4ebd 100644 --- a/src/apprt/gtk/notebook_gtk.zig +++ b/src/apprt/gtk/notebook_gtk.zig @@ -59,6 +59,10 @@ pub const NotebookGtk = struct { _ = c.g_signal_connect_data(gtk_notebook, "create-window", c.G_CALLBACK(>kNotebookCreateWindow), window, null, c.G_CONNECT_DEFAULT); } + pub fn deinit(self: NotebookGtk) void { + _ = self; + } + /// return the underlying widget as a generic GtkWidget pub fn asWidget(self: *NotebookGtk) *c.GtkWidget { return @ptrCast(@alignCast(self.notebook)); @@ -101,7 +105,7 @@ pub const NotebookGtk = struct { c.gtk_notebook_reorder_child(self.notebook, @ptrCast(tab.box), position); } - pub fn setTabLabel(_: *NotebookGtk, tab: *Tab, title: [:0]const u8) void { + pub fn setTabTitle(_: *NotebookGtk, tab: *Tab, title: [:0]const u8) void { c.gtk_label_set_text(tab.label_text, title.ptr); } diff --git a/src/apprt/gtk/ui/menu-adw-notebook-tab.ui b/src/apprt/gtk/ui/menu-adw-notebook-tab.ui new file mode 100644 index 000000000..8eb1f87aa --- /dev/null +++ b/src/apprt/gtk/ui/menu-adw-notebook-tab.ui @@ -0,0 +1,13 @@ + + + + +
+ + Rename + win.rename-tab + +
+
+
+ diff --git a/src/apprt/gtk/ui/window-adw-rename-tab.ui b/src/apprt/gtk/ui/window-adw-rename-tab.ui new file mode 100644 index 000000000..9ad7d5edc --- /dev/null +++ b/src/apprt/gtk/ui/window-adw-rename-tab.ui @@ -0,0 +1,33 @@ + + + + + + 350 + Set Tab Title + + + + + + + + 18 + 18 + 18 + 18 + + + Title + true + true + + + + + + + + + + diff --git a/src/build/SharedDeps.zig b/src/build/SharedDeps.zig index 6fe11147f..546b3c133 100644 --- a/src/build/SharedDeps.zig +++ b/src/build/SharedDeps.zig @@ -475,7 +475,9 @@ pub fn add( .root_source_file = b.path("src/apprt/gtk/builder_check.zig"), .target = b.host, }); + builder_check.root_module.addOptions("build_options", self.options); builder_check.linkSystemLibrary2("gtk4", dynamic_link_opts); + if (self.config.adwaita) builder_check.linkSystemLibrary2("libadwaita-1", dynamic_link_opts); builder_check.linkLibC(); for (gresource.dependencies) |pathname| {