From fdcaeebb9943f8057963bb97df94cfffecf8c011 Mon Sep 17 00:00:00 2001 From: rhodes-b <59537185+rhodes-b@users.noreply.github.com> Date: Sun, 21 Sep 2025 20:35:20 -0500 Subject: [PATCH] bind is-split property between split_tree class and surface class --- src/apprt/gtk/class/split_tree.zig | 47 ++++++++++++++++++++++++++++++ src/apprt/gtk/class/surface.zig | 38 +++++++++++------------- src/apprt/gtk/ui/1.2/surface.blp | 2 +- src/datastruct/split_tree.zig | 16 +--------- 4 files changed, 66 insertions(+), 37 deletions(-) diff --git a/src/apprt/gtk/class/split_tree.zig b/src/apprt/gtk/class/split_tree.zig index 3b6dcb4a9..35161b4d6 100644 --- a/src/apprt/gtk/class/split_tree.zig +++ b/src/apprt/gtk/class/split_tree.zig @@ -112,6 +112,25 @@ pub const SplitTree = extern struct { }, ); }; + + pub const @"is-split" = struct { + pub const name = "is-split"; + const impl = gobject.ext.defineProperty( + name, + Self, + bool, + .{ + .default = false, + .accessor = gobject.ext.typedAccessor( + Self, + bool, + .{ + .setter = setIsSplit, + }, + ), + }, + ); + }; }; pub const signals = struct { @@ -153,6 +172,9 @@ pub const SplitTree = extern struct { /// close dialog. pending_close: ?Surface.Tree.Node.Handle, + /// True if the current split tree contains more than one surface + is_split: bool = false, + pub var offset: c_int = 0; }; @@ -210,6 +232,14 @@ pub const SplitTree = extern struct { } } + // Bind is-split property for new surface + _ = self.as(gobject.Object).bindProperty( + "is-split", + surface.as(gobject.Object), + "is-split", + .{ .sync_create = true }, + ); + // Create our tree var single_tree = try Surface.Tree.init(alloc, surface); defer single_tree.deinit(); @@ -511,6 +541,12 @@ pub const SplitTree = extern struct { )); } + fn setIsSplit(self: *Self, v: bool) void { + const priv = self.private(); + priv.is_split = v; + self.as(gobject.Object).notifyByPspec(properties.@"is-split".impl.param_spec); + } + //--------------------------------------------------------------- // Virtual methods @@ -808,6 +844,16 @@ pub const SplitTree = extern struct { )); } + // Determine if tree has more than one surface + const root_handle: Surface.Tree.Node.Handle = .root; + const root = tree.nodes[root_handle.idx()]; + const is_split: bool = switch (root) { + .leaf => false, + .split => true, + }; + + self.setIsSplit(is_split); + // If we have a last focused surface, we need to refocus it, because // during the frame between setting the bin to null and rebuilding, // GTK will reset our focus state (as it should!) @@ -873,6 +919,7 @@ pub const SplitTree = extern struct { properties.@"has-surfaces".impl, properties.@"is-zoomed".impl, properties.tree.impl, + properties.@"is-split".impl, }); // Bindings diff --git a/src/apprt/gtk/class/surface.zig b/src/apprt/gtk/class/surface.zig index 087f2d286..e1efab620 100644 --- a/src/apprt/gtk/class/surface.zig +++ b/src/apprt/gtk/class/surface.zig @@ -275,21 +275,19 @@ pub const Surface = extern struct { ); }; - pub const @"n-siblings" = struct { - pub const name = "n-siblings"; + pub const @"is-split" = struct { + pub const name = "is-split"; const impl = gobject.ext.defineProperty( name, Self, - u64, + bool, .{ - .default = 0, - .minimum = 0, - .maximum = std.math.maxInt(c_uint), + .default = false, .accessor = gobject.ext.privateFieldAccessor( Self, Private, &Private.offset, - "n_siblings", + "is_split", ), }, ); @@ -522,10 +520,9 @@ pub const Surface = extern struct { /// A weak reference to an inspector window. inspector: ?*InspectorWindow = null, - /// Number of siblings related to this surface. This is used for - /// the unfocused-split-* options which are only applied when their is - /// more than once surface (split) in a tab - n_siblings: u64 = 0, + // True if the current surface is a split, this is used to apply + // unfocused-split-* options + is_split: bool = false, // Template binds child_exited_overlay: *ChildExited, @@ -630,9 +627,9 @@ pub const Surface = extern struct { fn closureShouldUnfocusedSplitBeShown( _: *Self, focused: c_int, - n_siblings: c_int, + is_split: c_int, ) callconv(.c) c_int { - return @intFromBool(focused == 0 and n_siblings > 0); + return @intFromBool(focused == 0 and is_split != 0); } pub fn toggleFullscreen(self: *Self) void { @@ -1526,13 +1523,6 @@ pub const Surface = extern struct { return self.private().focused; } - /// Set number of siblings related to this surface. - pub fn setNSiblings(self: *Self, siblings: u64) void { - const priv = self.private(); - priv.n_siblings = siblings; - self.as(gobject.Object).notifyByPspec(properties.@"n-siblings".impl.param_spec); - } - /// Change the configuration for this surface. pub fn setConfig(self: *Self, config: *Config) void { const priv = self.private(); @@ -1630,6 +1620,12 @@ pub const Surface = extern struct { self.as(gobject.Object).notifyByPspec(properties.@"error".impl.param_spec); } + // pub fn setIsSplit(self: *Self, v: bool) void { + // const priv = self.private(); + // priv.is_split = v; + // self.as(gobject.Object).notifyByPspec(properties.@"is-split".impl.param_spec); + // } + fn propConfig( self: *Self, _: *gobject.ParamSpec, @@ -2824,7 +2820,7 @@ pub const Surface = extern struct { properties.title.impl, properties.@"title-override".impl, properties.zoom.impl, - properties.@"n-siblings".impl, + properties.@"is-split".impl, }); // Signals diff --git a/src/apprt/gtk/ui/1.2/surface.blp b/src/apprt/gtk/ui/1.2/surface.blp index 35d897525..ad971e991 100644 --- a/src/apprt/gtk/ui/1.2/surface.blp +++ b/src/apprt/gtk/ui/1.2/surface.blp @@ -119,7 +119,7 @@ Overlay terminal_page { // Apply unfocused-split-fill and unfocused-split-opacity to current surface // this is only applied when a tab has more than one surface Revealer { - reveal-child: bind $should_unfocused_split_be_shown(template.focused, template.n-siblings) as ; + reveal-child: bind $should_unfocused_split_be_shown(template.focused, template.is-split) as ; transition-duration: 0; DrawingArea { diff --git a/src/datastruct/split_tree.zig b/src/datastruct/split_tree.zig index 212711e3d..28b45ceed 100644 --- a/src/datastruct/split_tree.zig +++ b/src/datastruct/split_tree.zig @@ -507,16 +507,12 @@ pub fn SplitTree(comptime V: type) type { // We need to increase the reference count of all the nodes. try refNodes(gpa, nodes); - const result: Self = .{ + return .{ .arena = arena, .nodes = nodes, // Splitting always resets zoom state. .zoomed = null, }; - - result.updateNodesNumberSiblings(); - - return result; } /// Remove a node from the tree. @@ -560,8 +556,6 @@ pub fn SplitTree(comptime V: type) type { // Increase the reference count of all the nodes. try refNodes(gpa, nodes); - result.updateNodesNumberSiblings(); - return result; } @@ -871,14 +865,6 @@ pub fn SplitTree(comptime V: type) type { }; } - /// Set the number of siblings for each split in the tree - fn updateNodesNumberSiblings(self: *const Self) void { - var it = self.iterator(); - while (it.next()) |entry| { - entry.view.setNSiblings(self.nodes.len - 1); - } - } - /// Spatial representation of the split tree. See spatial. pub const Spatial = struct { /// The slots of the spatial representation in the same order