Which children are unparented by gtk_widget_dispose_template?
example.c has an example of a simple widget loaded from a template:
<?xml version='1.0' encoding='UTF-8'?>
<interface>
<template class='MyWidget' parent='GtkWidget'>
<child>
<object class='GtkBox' id='box'/>
</child>
</template>
</interface>
It also has a constant named BIND_CHILD
. If BIND_CHILD
is set to 1
, then the struct _MyWidget
contains a GtkBox *box;
field, which is bound to the child widget using gtk_widget_class_bind_template_child
. But if BIND_CHILD
is set to 0
, then both the field and the bind call are omitted, and GTK will print a warning at runtime:
(example:656466): Gtk-WARNING **: 20:25:35.195: Finalizing MyWidget 0x5555557471a0, but it still has children left:
- GtkBox 0x55555574f580
In general, if a widget loaded from a template has a direct child which hasn't been bound using gtk_widget_class_bind_template_child
(or similar), then calling gtk_widget_dispose_template
will not unparent that child, and GTK will complain when the parent is finalized.
Effectively, this means that the author must either (a) bind every direct child of the widget, or (b) explicitly unparent all children which haven't been bound. As a corollary, if a direct child is missing an id
in the template XML, then the author is almost certainly doing it wrong.
However, this requirement isn't documented anywhere in GtkWidget
, gtk_widget_class_set_template
, gtk_widget_dispose_template
(which "is used to clear all the template children from a widget instance"), or in the "Widget Templates" tutorial (which says "It is not necessary to bind all the template children defined in the UI file."). It would be helpful if the docs clarified that gtk_widget_dispose_template
only unparents bound children, or if this is not the intended behavior, then it would be helpful if it were fixed.
(I noticed this issue in one of the widgets in gnome-system-monitor
, but since I didn't see any reason why gtk_widget_dispose_template
shouldn't unparent the direct child, it took me a long time to figure out what was going on.)