From 76496d40fdcc0c6aaadf98e3153effdd10dc2cdf Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 29 Nov 2025 15:27:52 -0800 Subject: [PATCH] apprt/gtk: hook up next/prev match --- src/apprt/gtk/class/search_overlay.zig | 46 +++++++++++++++++++++++++ src/apprt/gtk/class/surface.zig | 16 +++++++++ src/apprt/gtk/ui/1.2/search-overlay.blp | 4 +++ src/apprt/gtk/ui/1.2/surface.blp | 2 ++ 4 files changed, 68 insertions(+) diff --git a/src/apprt/gtk/class/search_overlay.zig b/src/apprt/gtk/class/search_overlay.zig index eee7b7bc1..75a28de80 100644 --- a/src/apprt/gtk/class/search_overlay.zig +++ b/src/apprt/gtk/class/search_overlay.zig @@ -102,6 +102,30 @@ pub const SearchOverlay = extern struct { void, ); }; + + /// Emitted when navigating to the next match. + pub const @"next-match" = struct { + pub const name = "next-match"; + pub const connect = impl.connect; + const impl = gobject.ext.defineSignal( + name, + Self, + &.{}, + void, + ); + }; + + /// Emitted when navigating to the previous match. + pub const @"previous-match" = struct { + pub const name = "previous-match"; + pub const connect = impl.connect; + const impl = gobject.ext.defineSignal( + name, + Self, + &.{}, + void, + ); + }; }; const Private = struct { @@ -168,6 +192,22 @@ pub const SearchOverlay = extern struct { signals.@"search-changed".impl.emit(self, null, .{text}, null); } + fn nextMatch(_: *gtk.Button, self: *Self) callconv(.c) void { + signals.@"next-match".impl.emit(self, null, .{}, null); + } + + fn previousMatch(_: *gtk.Button, self: *Self) callconv(.c) void { + signals.@"previous-match".impl.emit(self, null, .{}, null); + } + + fn nextMatchEntry(_: *gtk.SearchEntry, self: *Self) callconv(.c) void { + signals.@"next-match".impl.emit(self, null, .{}, null); + } + + fn previousMatchEntry(_: *gtk.SearchEntry, self: *Self) callconv(.c) void { + signals.@"previous-match".impl.emit(self, null, .{}, null); + } + //--------------------------------------------------------------- // Virtual methods @@ -224,6 +264,10 @@ pub const SearchOverlay = extern struct { class.bindTemplateCallback("stop_search", &stopSearch); class.bindTemplateCallback("search_changed", &searchChanged); class.bindTemplateCallback("match_label_closure", &closureMatchLabel); + class.bindTemplateCallback("next_match", &nextMatch); + class.bindTemplateCallback("previous_match", &previousMatch); + class.bindTemplateCallback("next_match_entry", &nextMatchEntry); + class.bindTemplateCallback("previous_match_entry", &previousMatchEntry); // Properties gobject.ext.registerProperties(class, &.{ @@ -235,6 +279,8 @@ pub const SearchOverlay = extern struct { // Signals signals.@"stop-search".impl.register(.{}); signals.@"search-changed".impl.register(.{}); + signals.@"next-match".impl.register(.{}); + signals.@"previous-match".impl.register(.{}); // Virtual methods gobject.Object.virtual_methods.dispose.implement(class, &dispose); diff --git a/src/apprt/gtk/class/surface.zig b/src/apprt/gtk/class/surface.zig index 5951b49f6..9a77c4c53 100644 --- a/src/apprt/gtk/class/surface.zig +++ b/src/apprt/gtk/class/surface.zig @@ -3211,6 +3211,20 @@ pub const Surface = extern struct { }; } + fn searchNextMatch(_: *SearchOverlay, self: *Self) callconv(.c) void { + const surface = self.core() orelse return; + _ = surface.performBindingAction(.{ .navigate_search = .next }) catch |err| { + log.warn("unable to perform navigate_search action err={}", .{err}); + }; + } + + fn searchPreviousMatch(_: *SearchOverlay, self: *Self) callconv(.c) void { + const surface = self.core() orelse return; + _ = surface.performBindingAction(.{ .navigate_search = .previous }) catch |err| { + log.warn("unable to perform navigate_search action err={}", .{err}); + }; + } + const C = Common(Self, Private); pub const as = C.as; pub const ref = C.ref; @@ -3285,6 +3299,8 @@ pub const Surface = extern struct { class.bindTemplateCallback("should_unfocused_split_be_shown", &closureShouldUnfocusedSplitBeShown); class.bindTemplateCallback("search_stop", &searchStop); class.bindTemplateCallback("search_changed", &searchChanged); + class.bindTemplateCallback("search_next_match", &searchNextMatch); + class.bindTemplateCallback("search_previous_match", &searchPreviousMatch); // Properties gobject.ext.registerProperties(class, &.{ diff --git a/src/apprt/gtk/ui/1.2/search-overlay.blp b/src/apprt/gtk/ui/1.2/search-overlay.blp index 43ede3178..62401959e 100644 --- a/src/apprt/gtk/ui/1.2/search-overlay.blp +++ b/src/apprt/gtk/ui/1.2/search-overlay.blp @@ -23,6 +23,8 @@ template $GhosttySearchOverlay: Adw.Bin { hexpand: true; stop-search => $stop_search(); search-changed => $search_changed(); + next-match => $next_match_entry(); + previous-match => $previous_match_entry(); } Label { @@ -46,6 +48,7 @@ template $GhosttySearchOverlay: Adw.Bin { Button prev_button { icon-name: "go-up-symbolic"; tooltip-text: _("Previous Match"); + clicked => $next_match(); cursor: Gdk.Cursor { name: "pointer"; @@ -55,6 +58,7 @@ template $GhosttySearchOverlay: Adw.Bin { Button next_button { icon-name: "go-down-symbolic"; tooltip-text: _("Next Match"); + clicked => $previous_match(); cursor: Gdk.Cursor { name: "pointer"; diff --git a/src/apprt/gtk/ui/1.2/surface.blp b/src/apprt/gtk/ui/1.2/surface.blp index 7f1c1b01f..0abc6c356 100644 --- a/src/apprt/gtk/ui/1.2/surface.blp +++ b/src/apprt/gtk/ui/1.2/surface.blp @@ -153,6 +153,8 @@ Overlay terminal_page { valign: start; stop-search => $search_stop(); search-changed => $search_changed(); + next-match => $search_next_match(); + previous-match => $search_previous_match(); } [overlay]