old_parent parameter in parent-set.



Hi devels,

I was receiving a g_critical at g_signal_emit complaining about
ref_count = 0; 

I looked into this and located the problem in gtktoolbar.c 

gtk_widget_set_parent() doesn't add a reference to the parent, therefore
the child doesn't hold any reference to the parent(perhaps this is to
break the circular reference). If for some reason the parent is already
disposed before gtk_widget_unparent is called; eg, in this snippet from
gtktoolbar.c

-------------------
static void
gtk_toolbar_finalize (GObject *object)
{
  GList *list;
  GtkToolbar *toolbar = GTK_TOOLBAR (object);
  GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);

  if (toolbar->tooltips)
    g_object_unref (toolbar->tooltips);

  if (priv->arrow_button)
    gtk_widget_unparent (priv->arrow_button);

  for (list = priv->content; list != NULL; list = list->next)
    {
      ToolbarContent *content = list->data;

      toolbar_content_free (content);
    }

  g_list_free (priv->content);
  g_list_free (toolbar->children);
------------------

the signal pre emission code will give that g_critical error message.

This is not likely to happen since normally there is no signal
handler/emission hooks connected to parent_set signal; and the
skip_emission trick in gsignal.c will totally skip the signal emission.

But theoretically this is a flaw; and if someone adds a emission hook it
starts to kick your ass.

A way to fix would be unparenting children in dispose, where the parent
is still not disposed. and perhaps also document in 'parent-set' signal
and 'gtk_widget_unparent' to tell other widget writers that they should
unparent the widget when the parent is still alive.

I did a grep on Gtk 2.14.4 code:
# grep -A 100 'gtk.*_finalize' *.c|grep unparent
gtkclist.c-  /* Since we don't have a _remove method, unparent the children
gtkclist.c-   * unparent) The destroy will happen when the refcount drops
gtkclist.c-	gtk_widget_unparent (clist->column[i].button);
gtktable.c-	  gtk_widget_unparent (widget);
gtktexttagtable.c-  /* We don't want to emit the remove signal here; so we just unparent
gtktoolbar.c-    gtk_widget_unparent (priv->arrow_button);

among them only gtktoolbar.c seems to be affected.

Regards,

Yu



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]