apprt/gtk: hook up search_total/search_selected apprt actions

pull/9756/head
Mitchell Hashimoto 2025-11-29 15:22:29 -08:00
parent fc9b578ef4
commit 0ea85fc483
No known key found for this signature in database
GPG Key ID: 523D5DC389D273BC
4 changed files with 90 additions and 4 deletions

View File

@ -729,6 +729,8 @@ pub const Application = extern struct {
.start_search => Action.startSearch(target),
.end_search => Action.endSearch(target),
.search_total => Action.searchTotal(target, value),
.search_selected => Action.searchSelected(target, value),
// Unimplemented
.secure_input,
@ -744,8 +746,6 @@ pub const Application = extern struct {
.check_for_updates,
.undo,
.redo,
.search_total,
.search_selected,
=> {
log.warn("unimplemented action={}", .{action});
return false;
@ -2356,6 +2356,20 @@ const Action = struct {
}
}
pub fn searchTotal(target: apprt.Target, value: apprt.action.SearchTotal) void {
switch (target) {
.app => {},
.surface => |v| v.rt_surface.surface.setSearchTotal(value.total),
}
}
pub fn searchSelected(target: apprt.Target, value: apprt.action.SearchSelected) void {
switch (target) {
.app => {},
.surface => |v| v.rt_surface.surface.setSearchSelected(value.selected),
}
}
pub fn setTitle(
target: apprt.Target,
value: apprt.action.SetTitle,

View File

@ -46,6 +46,36 @@ pub const SearchOverlay = extern struct {
},
);
};
pub const @"search-total" = struct {
pub const name = "search-total";
const impl = gobject.ext.defineProperty(
name,
Self,
i64,
.{
.default = -1,
.minimum = -1,
.maximum = std.math.maxInt(i64),
.accessor = C.privateShallowFieldAccessor("search_total"),
},
);
};
pub const @"search-selected" = struct {
pub const name = "search-selected";
const impl = gobject.ext.defineProperty(
name,
Self,
i64,
.{
.default = -1,
.minimum = -1,
.maximum = std.math.maxInt(i64),
.accessor = C.privateShallowFieldAccessor("search_selected"),
},
);
};
};
pub const signals = struct {
@ -81,6 +111,12 @@ pub const SearchOverlay = extern struct {
/// True when a search is active, meaning we should show the overlay.
active: bool = false,
/// Total number of search matches (-1 means unknown/none).
search_total: i64 = -1,
/// Currently selected match index (-1 means none selected).
search_selected: i64 = -1,
pub var offset: c_int = 0;
};
@ -95,6 +131,31 @@ pub const SearchOverlay = extern struct {
priv.search_entry.as(gtk.Editable).selectRegion(0, -1);
}
/// Set the total number of search matches.
pub fn setSearchTotal(self: *Self, total: ?usize) void {
const value: i64 = if (total) |t| @intCast(t) else -1;
var gvalue = gobject.ext.Value.newFrom(value);
defer gvalue.unset();
self.as(gobject.Object).setProperty(properties.@"search-total".name, &gvalue);
}
/// Set the currently selected match index.
pub fn setSearchSelected(self: *Self, selected: ?usize) void {
const value: i64 = if (selected) |s| @intCast(s) else -1;
var gvalue = gobject.ext.Value.newFrom(value);
defer gvalue.unset();
self.as(gobject.Object).setProperty(properties.@"search-selected".name, &gvalue);
}
fn closureMatchLabel(_: *Self, selected: i64, total: i64) callconv(.c) ?[*:0]const u8 {
var buf: [32]u8 = undefined;
const label = std.fmt.bufPrintZ(&buf, "{}/{}", .{
if (selected >= 0) selected else 0,
if (total >= 0) total else 0,
}) catch return null;
return glib.ext.dupeZ(u8, label);
}
//---------------------------------------------------------------
// Template callbacks
@ -162,10 +223,13 @@ pub const SearchOverlay = extern struct {
// Template Callbacks
class.bindTemplateCallback("stop_search", &stopSearch);
class.bindTemplateCallback("search_changed", &searchChanged);
class.bindTemplateCallback("match_label_closure", &closureMatchLabel);
// Properties
gobject.ext.registerProperties(class, &.{
properties.active.impl,
properties.@"search-total".impl,
properties.@"search-selected".impl,
});
// Signals

View File

@ -1969,6 +1969,14 @@ pub const Surface = extern struct {
}
}
pub fn setSearchTotal(self: *Self, total: ?usize) void {
self.private().search_overlay.setSearchTotal(total);
}
pub fn setSearchSelected(self: *Self, selected: ?usize) void {
self.private().search_overlay.setSearchSelected(selected);
}
fn propConfig(
self: *Self,
_: *gobject.ParamSpec,

View File

@ -25,12 +25,12 @@ template $GhosttySearchOverlay: Adw.Bin {
search-changed => $search_changed();
}
Label match_label {
Label {
styles [
"dim-label",
]
label: "0/0";
label: bind $match_label_closure(template.search-selected, template.search-total) as <string>;
width-chars: 6;
xalign: 1.0;
}