Commit 59482273 authored by Mike Wey's avatar Mike Wey

Remove the GC root for chidren of containers.

Keeping the GC root can cause a reference cycle when signals are involved.

Fixes: #254
parent 35ea3f49
......@@ -268,6 +268,32 @@ public class Container : Widget
{
this.gtkContainer = gtkContainer;
super(cast(GtkWidget*)gtkContainer, ownedRef);
Signals.connect(this, "add", cast(GCallback)&gtkd_container_add, null);
Signals.connect(this, "remove", cast(GCallback)&gtkd_container_remove, null);
}
Widget[] children;
static extern(C) void gtkd_container_add(GtkContainer* c, GtkWidget* w)
{
Container container = ObjectG.getDObject!(Container)(c);
Widget widget = ObjectG.getDObject!(Widget)(w);
container.children ~= widget;
widget.removeGcRoot();
}
static extern(C) void gtkd_container_remove(GtkContainer* c, GtkWidget* w)
{
import gobject.c.functions : g_object_get_data;
if ( auto container = cast(Container)g_object_get_data(cast(GObject*)c, "GObject") )
if ( auto widget = cast(Widget)g_object_get_data(cast(GObject*)w, "GObject") )
{
import std.algorithm : remove;
container.children.remove!(a => a is widget)();
}
}
/**
......
......@@ -1015,6 +1015,41 @@ code: end
struct: Container
code: start
/**
* Sets our main struct and passes it to the parent class.
*/
public this (GtkContainer* gtkContainer, bool ownedRef = false)
{
this.gtkContainer = gtkContainer;
super(cast(GtkWidget*)gtkContainer, ownedRef);
Signals.connect(this, "add", cast(GCallback)&gtkd_container_add, null);
Signals.connect(this, "remove", cast(GCallback)&gtkd_container_remove, null);
}
Widget[] children;
static extern(C) void gtkd_container_add(GtkContainer* c, GtkWidget* w)
{
Container container = ObjectG.getDObject!(Container)(c);
Widget widget = ObjectG.getDObject!(Widget)(w);
container.children ~= widget;
widget.removeGcRoot();
}
static extern(C) void gtkd_container_remove(GtkContainer* c, GtkWidget* w)
{
import gobject.c.functions : g_object_get_data;
if ( auto container = cast(Container)g_object_get_data(cast(GObject*)c, "GObject") )
if ( auto widget = cast(Widget)g_object_get_data(cast(GObject*)w, "GObject") )
{
import std.algorithm : remove;
container.children.remove!(a => a is widget)();
}
}
/**
* Removes all widgets from the container
*/
......
Subproject commit 265f5da9ab537fb240db81230adfa89869d07ccd
Subproject commit f65e45fd38be3e20b21524c1d43657493e502e78
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment