From c149ba19079a890d9df992964377e09999e75429 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 28 Jul 2025 08:19:56 -0700 Subject: [PATCH] apprt/gtk-ng: port SIGUSR2 to reload config --- src/apprt/gtk-ng/class/application.zig | 43 ++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/apprt/gtk-ng/class/application.zig b/src/apprt/gtk-ng/class/application.zig index 3b4250956..636700284 100644 --- a/src/apprt/gtk-ng/class/application.zig +++ b/src/apprt/gtk-ng/class/application.zig @@ -128,6 +128,9 @@ pub const Application = extern struct { /// outside of our own lifecycle and that's okay. config_errors_dialog: WeakRef(ConfigErrorsDialog) = .{}, + /// glib source for our signal handler. + signal_source: ?c_uint = null, + pub var offset: c_int = 0; }; @@ -698,6 +701,9 @@ pub const Application = extern struct { // Setup our style manager (light/dark mode) self.startupStyleManager(); + // Setup some signal handlers + self.startupSignals(); + // Setup our action map self.startupActionMap(); @@ -786,6 +792,17 @@ pub const Application = extern struct { ); } + /// Setup signal handlers + fn startupSignals(self: *Self) void { + const priv = self.private(); + assert(priv.signal_source == null); + priv.signal_source = glib.unixSignalAdd( + std.posix.SIG.USR2, + handleSigusr2, + self, + ); + } + /// Setup our action map. fn startupActionMap(self: *Self) void { const t_variant_type = glib.ext.VariantType.newFor(u64); @@ -914,6 +931,12 @@ pub const Application = extern struct { diag.close(); diag.unref(); // strong ref from get() } + if (priv.signal_source) |v| { + if (glib.Source.remove(v) == 0) { + log.warn("unable to remove signal source", .{}); + } + priv.signal_source = null; + } gobject.Object.virtual_methods.dispose.call( Class.parent, @@ -932,6 +955,26 @@ pub const Application = extern struct { //--------------------------------------------------------------- // Signal Handlers + /// SIGUSR2 signal handler via g_unix_signal_add + fn handleSigusr2(ud: ?*anyopaque) callconv(.c) c_int { + const self: *Self = @ptrCast(@alignCast(ud orelse + return @intFromBool(glib.SOURCE_CONTINUE))); + + log.info("received SIGUSR2, reloading configuration", .{}); + Action.reloadConfig( + self, + .app, + .{}, + ) catch |err| { + // If we fail to reload the configuration, then we want the + // user to know it. For now we log but we should show another + // GUI. + log.warn("error reloading config: {}", .{err}); + }; + + return @intFromBool(glib.SOURCE_CONTINUE); + } + fn handleCloseConfirmation( _: *CloseConfirmationDialog, self: *Self,