From ec2aa8e3221a7e9b3b2afae972d843215495d200 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 2 Nov 2023 12:17:33 -0700 Subject: [PATCH] apprt/gtk: maintain container pointers --- src/apprt/gtk/Split.zig | 37 +++++++++++++++++++++++++++---------- src/apprt/gtk/Surface.zig | 12 ++++++++++++ 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/apprt/gtk/Split.zig b/src/apprt/gtk/Split.zig index fcf7f5d05..ee997af64 100644 --- a/src/apprt/gtk/Split.zig +++ b/src/apprt/gtk/Split.zig @@ -156,10 +156,10 @@ pub fn replaceChildInPosition(self: *Split, child: Child, position: Position) vo } /// Remove both children, setting *c.GtkSplit start/end children to null. -pub fn removeChildren(self: *Split) void { - self.removeChildInPosition(.start); - self.removeChildInPosition(.end); -} +// pub fn removeChildren(self: *Split) void { +// self.removeChildInPosition(.start); +// self.removeChildInPosition(.end); +//} /// Deinit the Split by deiniting its child Split, if they exist. pub fn deinit(self: *Split, alloc: Allocator) void { @@ -189,6 +189,18 @@ fn removeChildInPosition(self: *Split, position: Position) void { } } +/// Remove the top left child. +pub fn removeTopLeft(self: *Split) void { + // Remove our children since we are going to no longer be + // a split anyways. This prevents widgets with multiple parents. + self.removeChildren(); + + // Our container must become whatever our bottom right is + self.container.replace(self.bottom_right); + + // TODO: memory management of top left +} + // TODO: ehhhhhh pub fn replace( self: *Split, @@ -203,12 +215,6 @@ pub fn replace( // position but we want to keep it in place so save and restore it. const pos = c.gtk_paned_get_position(self.paned); defer c.gtk_paned_set_position(self.paned, pos); - - // We have to set both to null. If we overwrite the pane with - // the same value, then GTK bugs out (the GL area unrealizes - // and never rerealizes). - c.gtk_paned_set_start_child(@ptrCast(self.paned), null); - c.gtk_paned_set_end_child(@ptrCast(self.paned), null); self.updateChildren(); } @@ -216,6 +222,12 @@ pub fn replace( /// This should be called anytime the top/left or bottom/right /// element is changed. fn updateChildren(self: *const Split) void { + // We have to set both to null. If we overwrite the pane with + // the same value, then GTK bugs out (the GL area unrealizes + // and never rerealizes). + self.removeChildren(); + + // Set our current children c.gtk_paned_set_start_child( @ptrCast(self.paned), self.top_left.widget(), @@ -226,6 +238,11 @@ fn updateChildren(self: *const Split) void { ); } +fn removeChildren(self: *const Split) void { + c.gtk_paned_set_start_child(@ptrCast(self.paned), null); + c.gtk_paned_set_end_child(@ptrCast(self.paned), null); +} + fn addChild1(self: *Split, child: Child) void { assert(self.child1 == .none); diff --git a/src/apprt/gtk/Surface.zig b/src/apprt/gtk/Surface.zig index eaf320bb4..e13871050 100644 --- a/src/apprt/gtk/Surface.zig +++ b/src/apprt/gtk/Surface.zig @@ -72,6 +72,13 @@ pub const Container = union(enum) { .split => |s| @ptrCast(@alignCast(s.paned)), }; } + + pub fn containerPtr(self: Elem) *Container { + return switch (self) { + .surface => |s| &s.container, + .split => |s| &s.container, + }; + } }; /// Returns the window that this surface is attached to. @@ -112,6 +119,7 @@ pub const Container = union(enum) { /// from a surface to a split or a split back to a surface or /// a split to a nested split and so on. pub fn replace(self: Container, elem: Elem) void { + // Move the element into the container switch (self) { .none => {}, .tab_ => |t| t.replaceElem(elem), @@ -120,6 +128,9 @@ pub const Container = union(enum) { s.replace(ptr, elem); }, } + + // Update the reverse reference to the container + elem.containerPtr().* = self; } /// Remove ourselves from the container. This is used by @@ -129,6 +140,7 @@ pub const Container = union(enum) { switch (self) { .none => {}, .tab_ => |t| t.closeElem(), + .split_tl => self.split().?.removeTopLeft(), else => @panic("TOOD"), } }