From 0d32e7d814264c8f84c397235fae206774eeac90 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 29 Nov 2025 15:10:38 -0800 Subject: [PATCH] apprt/gtk: escape to stop search and hide overlay --- src/apprt/gtk/class/search_overlay.zig | 28 +++++++++++++++++++++++++ src/apprt/gtk/class/surface.zig | 9 ++++++++ src/apprt/gtk/ui/1.2/search-overlay.blp | 1 + src/apprt/gtk/ui/1.2/surface.blp | 1 + 4 files changed, 39 insertions(+) diff --git a/src/apprt/gtk/class/search_overlay.zig b/src/apprt/gtk/class/search_overlay.zig index 67c6ba38c..75aedc154 100644 --- a/src/apprt/gtk/class/search_overlay.zig +++ b/src/apprt/gtk/class/search_overlay.zig @@ -48,6 +48,20 @@ pub const SearchOverlay = extern struct { }; }; + pub const signals = struct { + /// Emitted when the search is stopped (e.g., Escape pressed). + pub const @"stop-search" = struct { + pub const name = "stop-search"; + pub const connect = impl.connect; + const impl = gobject.ext.defineSignal( + name, + Self, + &.{}, + void, + ); + }; + }; + const Private = struct { /// The search entry widget. search_entry: *gtk.SearchEntry, @@ -69,6 +83,13 @@ pub const SearchOverlay = extern struct { priv.search_entry.as(gtk.Editable).selectRegion(0, -1); } + //--------------------------------------------------------------- + // Template callbacks + + fn stopSearch(_: *gtk.SearchEntry, self: *Self) callconv(.c) void { + signals.@"stop-search".impl.emit(self, null, .{}, null); + } + //--------------------------------------------------------------- // Virtual methods @@ -121,11 +142,17 @@ pub const SearchOverlay = extern struct { // Bindings class.bindTemplateChildPrivate("search_entry", .{}); + // Template Callbacks + class.bindTemplateCallback("stop_search", &stopSearch); + // Properties gobject.ext.registerProperties(class, &.{ properties.active.impl, }); + // Signals + signals.@"stop-search".impl.register(.{}); + // Virtual methods gobject.Object.virtual_methods.dispose.implement(class, &dispose); gobject.Object.virtual_methods.finalize.implement(class, &finalize); @@ -133,5 +160,6 @@ pub const SearchOverlay = extern struct { pub const as = C.Class.as; pub const bindTemplateChildPrivate = C.Class.bindTemplateChildPrivate; + pub const bindTemplateCallback = C.Class.bindTemplateCallback; }; }; diff --git a/src/apprt/gtk/class/surface.zig b/src/apprt/gtk/class/surface.zig index a91ae9d45..405beea3e 100644 --- a/src/apprt/gtk/class/surface.zig +++ b/src/apprt/gtk/class/surface.zig @@ -3188,6 +3188,14 @@ pub const Surface = extern struct { self.setTitleOverride(if (title.len == 0) null else title); } + fn searchStop(_: *SearchOverlay, self: *Self) callconv(.c) void { + // Note: at the time of writing this, this behavior doesn't match + // macOS. But I think it makes more sense on Linux/GTK to do this. + // We may follow suit on macOS in the future. + self.setSearchActive(false); + _ = self.private().gl_area.as(gtk.Widget).grabFocus(); + } + const C = Common(Self, Private); pub const as = C.as; pub const ref = C.ref; @@ -3260,6 +3268,7 @@ pub const Surface = extern struct { class.bindTemplateCallback("notify_vadjustment", &propVAdjustment); class.bindTemplateCallback("should_border_be_shown", &closureShouldBorderBeShown); class.bindTemplateCallback("should_unfocused_split_be_shown", &closureShouldUnfocusedSplitBeShown); + class.bindTemplateCallback("search_stop", &searchStop); // 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 79e3ef58f..b9d282df5 100644 --- a/src/apprt/gtk/ui/1.2/search-overlay.blp +++ b/src/apprt/gtk/ui/1.2/search-overlay.blp @@ -21,6 +21,7 @@ template $GhosttySearchOverlay: Adw.Bin { placeholder-text: _("Find…"); width-chars: 20; hexpand: true; + stop-search => $stop_search(); } Label match_label { diff --git a/src/apprt/gtk/ui/1.2/surface.blp b/src/apprt/gtk/ui/1.2/surface.blp index 3b382259d..9803b47e0 100644 --- a/src/apprt/gtk/ui/1.2/surface.blp +++ b/src/apprt/gtk/ui/1.2/surface.blp @@ -151,6 +151,7 @@ Overlay terminal_page { $GhosttySearchOverlay search_overlay { halign: end; valign: start; + stop-search => $search_stop(); } [overlay]