diff --git a/src/apprt/gtk/class/application.zig b/src/apprt/gtk/class/application.zig index cc070240c..0efa7a3e0 100644 --- a/src/apprt/gtk/class/application.zig +++ b/src/apprt/gtk/class/application.zig @@ -727,6 +727,9 @@ pub const Application = extern struct { .show_on_screen_keyboard => return Action.showOnScreenKeyboard(target), .command_finished => return Action.commandFinished(target, value), + .start_search => Action.startSearch(target), + .end_search => Action.endSearch(target), + // Unimplemented .secure_input, .close_all_windows, @@ -741,8 +744,6 @@ pub const Application = extern struct { .check_for_updates, .undo, .redo, - .start_search, - .end_search, .search_total, .search_selected, => { @@ -2341,6 +2342,20 @@ const Action = struct { } } + pub fn startSearch(target: apprt.Target) void { + switch (target) { + .app => {}, + .surface => |v| v.rt_surface.surface.setSearchActive(true), + } + } + + pub fn endSearch(target: apprt.Target) void { + switch (target) { + .app => {}, + .surface => |v| v.rt_surface.surface.setSearchActive(false), + } + } + pub fn setTitle( target: apprt.Target, value: apprt.action.SetTitle, diff --git a/src/apprt/gtk/class/search_overlay.zig b/src/apprt/gtk/class/search_overlay.zig index 1e49750fa..67c6ba38c 100644 --- a/src/apprt/gtk/class/search_overlay.zig +++ b/src/apprt/gtk/class/search_overlay.zig @@ -34,39 +34,39 @@ pub const SearchOverlay = extern struct { }); pub const properties = struct { - pub const duration = struct { - pub const name = "duration"; + pub const active = struct { + pub const name = "active"; const impl = gobject.ext.defineProperty( name, Self, - c_uint, + bool, .{ - .default = 750, - .minimum = 250, - .maximum = std.math.maxInt(c_uint), - .accessor = gobject.ext.privateFieldAccessor( - Self, - Private, - &Private.offset, - "duration", - ), + .default = false, + .accessor = C.privateShallowFieldAccessor("active"), }, ); }; }; const Private = struct { - /// The time that the overlay appears. - duration: c_uint, + /// The search entry widget. + search_entry: *gtk.SearchEntry, + + /// True when a search is active, meaning we should show the overlay. + active: bool = false, pub var offset: c_int = 0; }; fn init(self: *Self, _: *Class) callconv(.c) void { gtk.Widget.initTemplate(self.as(gtk.Widget)); + } + /// Grab focus on the search entry and select all text. + pub fn grabFocus(self: *Self) void { const priv = self.private(); - _ = priv; + _ = priv.search_entry.as(gtk.Widget).grabFocus(); + priv.search_entry.as(gtk.Editable).selectRegion(0, -1); } //--------------------------------------------------------------- @@ -119,16 +119,12 @@ pub const SearchOverlay = extern struct { ); // Bindings - // class.bindTemplateChildPrivate("label", .{}); + class.bindTemplateChildPrivate("search_entry", .{}); // Properties - // gobject.ext.registerProperties(class, &.{ - // properties.duration.impl, - // properties.label.impl, - // properties.@"first-delay".impl, - // properties.@"overlay-halign".impl, - // properties.@"overlay-valign".impl, - // }); + gobject.ext.registerProperties(class, &.{ + properties.active.impl, + }); // 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 587392464..a91ae9d45 100644 --- a/src/apprt/gtk/class/surface.zig +++ b/src/apprt/gtk/class/surface.zig @@ -550,6 +550,9 @@ pub const Surface = extern struct { /// The resize overlay resize_overlay: *ResizeOverlay, + /// The search overlay + search_overlay: *SearchOverlay, + /// The apprt Surface. rt_surface: ApprtSurface = undefined, @@ -1952,6 +1955,20 @@ pub const Surface = extern struct { self.as(gobject.Object).notifyByPspec(properties.@"error".impl.param_spec); } + pub fn setSearchActive(self: *Self, active: bool) void { + const priv = self.private(); + var value = gobject.ext.Value.newFrom(active); + defer value.unset(); + gobject.Object.setProperty( + priv.search_overlay.as(gobject.Object), + SearchOverlay.properties.active.name, + &value, + ); + if (active) { + priv.search_overlay.grabFocus(); + } + } + fn propConfig( self: *Self, _: *gobject.ParamSpec, @@ -3205,6 +3222,7 @@ pub const Surface = extern struct { class.bindTemplateChildPrivate("error_page", .{}); class.bindTemplateChildPrivate("progress_bar_overlay", .{}); class.bindTemplateChildPrivate("resize_overlay", .{}); + class.bindTemplateChildPrivate("search_overlay", .{}); class.bindTemplateChildPrivate("terminal_page", .{}); class.bindTemplateChildPrivate("drop_target", .{}); class.bindTemplateChildPrivate("im_context", .{}); diff --git a/src/apprt/gtk/ui/1.2/search-overlay.blp b/src/apprt/gtk/ui/1.2/search-overlay.blp index 030780260..79e3ef58f 100644 --- a/src/apprt/gtk/ui/1.2/search-overlay.blp +++ b/src/apprt/gtk/ui/1.2/search-overlay.blp @@ -3,6 +3,7 @@ using Gdk 4.0; using Adw 1; template $GhosttySearchOverlay: Adw.Bin { + visible: bind template.active; halign: end; valign: start;