apprt/gtk-ng: active surface hookups

pull/8207/head
Mitchell Hashimoto 2025-08-09 13:49:25 -07:00
parent 8232cf33b4
commit ec293c1fd0
No known key found for this signature in database
GPG Key ID: 523D5DC389D273BC
4 changed files with 29 additions and 55 deletions

View File

@ -49,8 +49,6 @@ pub const SplitTree = extern struct {
Self,
?*Surface,
.{
.nick = "Active Surface",
.blurb = "The currently active surface.",
.accessor = gobject.ext.typedAccessor(
Self,
?*Surface,
@ -481,6 +479,7 @@ pub const SplitTree = extern struct {
// Remove the surface from the tree.
.surface => {
// TODO: close confirmation
// TODO: invalid free on final close
// Find the surface in the tree.
const tree = self.getTree() orelse return;
@ -517,6 +516,9 @@ pub const SplitTree = extern struct {
// the surface is destroyed.
if (!surface.getFocused()) return;
self.private().last_focused.set(surface);
// Our active surface probably changed
self.as(gobject.Object).notifyByPspec(properties.@"active-surface".impl.param_spec);
}
fn propTree(
@ -566,6 +568,9 @@ pub const SplitTree = extern struct {
v.grabFocus();
}
// Our active surface may have changed
self.as(gobject.Object).notifyByPspec(properties.@"active-surface".impl.param_spec);
return 0;
}
@ -616,6 +621,7 @@ pub const SplitTree = extern struct {
// Properties
gobject.ext.registerProperties(class, &.{
properties.@"active-surface".impl,
properties.@"has-surfaces".impl,
properties.tree.impl,
});

View File

@ -175,42 +175,6 @@ pub const Tab = extern struct {
};
}
fn connectSurfaceHandlers(
self: *Self,
tree: *const Surface.Tree,
) void {
var it = tree.iterator();
while (it.next()) |entry| {
const surface = entry.view;
_ = gobject.Object.signals.notify.connect(
surface,
*Self,
propSurfaceFocused,
self,
.{ .detail = "focused" },
);
}
}
fn disconnectSurfaceHandlers(
self: *Self,
tree: *const Surface.Tree,
) void {
var it = tree.iterator();
while (it.next()) |entry| {
const surface = entry.view;
_ = gobject.signalHandlersDisconnectMatched(
surface.as(gobject.Object),
.{ .data = true },
0,
0,
null,
null,
self,
);
}
}
//---------------------------------------------------------------
// Properties
@ -280,14 +244,10 @@ pub const Tab = extern struct {
fn splitTreeChanged(
_: *SplitTree,
old_tree: ?*const Surface.Tree,
_: ?*const Surface.Tree,
new_tree: ?*const Surface.Tree,
self: *Self,
) callconv(.c) void {
if (old_tree) |tree| {
self.disconnectSurfaceHandlers(tree);
}
// If our tree is empty we close the tab.
const tree: *const Surface.Tree = new_tree orelse &.empty;
if (tree.isEmpty()) {
@ -299,9 +259,6 @@ pub const Tab = extern struct {
);
return;
}
// Non-empty tree, connect handlers we care about.
self.connectSurfaceHandlers(tree);
}
fn propSplitTree(
@ -313,7 +270,7 @@ pub const Tab = extern struct {
}
fn propActiveSurface(
_: *Self,
_: *SplitTree,
_: *gobject.ParamSpec,
self: *Self,
) callconv(.c) void {
@ -322,14 +279,7 @@ pub const Tab = extern struct {
if (self.getActiveSurface()) |surface| {
priv.surface_bindings.setSource(surface.as(gobject.Object));
}
}
fn propSurfaceFocused(
surface: *Surface,
_: *gobject.ParamSpec,
self: *Self,
) callconv(.c) void {
if (!surface.getFocused()) return;
self.as(gobject.Object).notifyByPspec(properties.@"active-surface".impl.param_spec);
}

View File

@ -5,12 +5,12 @@ template $GhosttyTab: Box {
"tab",
]
notify::active-surface => $notify_active_surface();
orientation: vertical;
hexpand: true;
vexpand: true;
$GhosttySplitTree split_tree {
notify::active-surface => $notify_active_surface();
notify::tree => $notify_tree();
changed => $tree_changed();
}

View File

@ -1151,3 +1151,21 @@ test "SplitTree: split twice, remove intermediary" {
t.deinit();
}
}
test "SplitTree: clone empty tree" {
const testing = std.testing;
const alloc = testing.allocator;
var t: TestTree = .empty;
defer t.deinit();
var t2 = try t.clone(alloc);
defer t2.deinit();
{
const str = try std.fmt.allocPrint(alloc, "{}", .{t2});
defer alloc.free(str);
try testing.expectEqualStrings(str,
\\empty
);
}
}