diff --git a/src/apprt/gtk-ng/class/application.zig b/src/apprt/gtk-ng/class/application.zig index c569646cc..af68b63df 100644 --- a/src/apprt/gtk-ng/class/application.zig +++ b/src/apprt/gtk-ng/class/application.zig @@ -1727,20 +1727,20 @@ const Action = struct { // Find a quick terminal window. const list = gtk.Window.listToplevels(); defer list.free(); - const elem_: ?*glib.List = list.findCustom(null, struct { - fn callback(data: ?*const anyopaque, _: ?*const anyopaque) callconv(.c) c_int { - const ptr = data orelse return 1; - const gtk_window: *gtk.Window = @ptrCast(@alignCast(@constCast(ptr))); - const window = gobject.ext.cast( + if (ext.listFind(gtk.Window, list, struct { + fn find(gtk_win: *gtk.Window) bool { + const win = gobject.ext.cast( Window, - gtk_window, - ) orelse return 1; - if (window.isQuickTerminal()) return 0; - return 1; + gtk_win, + ) orelse return false; + return win.isQuickTerminal(); } - }.callback); - const elem = elem_ orelse return null; - return @ptrCast(@alignCast(elem.f_data)); + }.find)) |w| return gobject.ext.cast( + Window, + w, + ).?; + + return null; } pub fn toggleMaximize(target: apprt.Target) void { diff --git a/src/apprt/gtk-ng/ext.zig b/src/apprt/gtk-ng/ext.zig index 551d54b23..3e80a9998 100644 --- a/src/apprt/gtk-ng/ext.zig +++ b/src/apprt/gtk-ng/ext.zig @@ -6,6 +6,7 @@ const std = @import("std"); const assert = std.debug.assert; +const glib = @import("glib"); const gobject = @import("gobject"); const gtk = @import("gtk"); @@ -23,6 +24,24 @@ pub fn boxedFree(comptime T: type, ptr: ?*T) void { ); } +/// A wrapper around `glib.List.findCustom` to find an element in the list. +/// The type `T` must be the guaranteed type of every list element. +pub fn listFind( + comptime T: type, + list: *glib.List, + comptime func: *const fn (*T) bool, +) ?*T { + const elem_: ?*glib.List = list.findCustom(null, struct { + fn callback(data: ?*const anyopaque, _: ?*const anyopaque) callconv(.c) c_int { + const ptr = data orelse return 1; + const v: *T = @ptrCast(@alignCast(@constCast(ptr))); + return if (func(v)) 0 else 1; + } + }.callback); + const elem = elem_ orelse return null; + return @ptrCast(@alignCast(elem.f_data)); +} + /// Wrapper around `gtk.Widget.getAncestor` to get the widget ancestor /// of the given type `T`, or null if it doesn't exist. pub fn getAncestor(comptime T: type, widget: *gtk.Widget) ?*T {