From 3391a567baed79df713a76d86c2fe58c8991f394 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Thu, 10 Jan 2008 10:20:49 +0000 Subject: [PATCH] Merged from trunk: 2007-01-06 Johan Dahlin Merged from trunk: * gtkbuilder.c: remove concept of root objects and just refcount all objects in the builder. Fixes #496651. * docs/reference/gtk/tmpl/gtkbuildable.sgml: add clarification stating that the construct_child function is responsible for returning a reference. * gtkbuilder.c (_gtk_builder_construct): remove g_object_ref() for objects from constructors * gtkuimanager.c (gtk_ui_manager_buildable_construct_child): add g_object_ref() to this construction function (it's the only implementer in GTK) Fixes #496645. svn path=/branches/gtk-2-12/; revision=19334 --- ChangeLog | 18 +++++++++++++ docs/reference/gtk/tmpl/gtkbuildable.sgml | 3 ++- gtk/gtkbuilder.c | 31 ++++++++++++----------- gtk/gtkuimanager.c | 2 +- 4 files changed, 37 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index b00771317b..e247570b09 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2007-01-06 Johan Dahlin + + Merged from trunk: + + * gtkbuilder.c: remove concept of root objects and just refcount + all objects in the builder. Fixes #496651. + + * docs/reference/gtk/tmpl/gtkbuildable.sgml: add clarification stating + that the construct_child function is responsible for returning a + reference. + * gtkbuilder.c (_gtk_builder_construct): remove g_object_ref() for + objects from constructors + * gtkuimanager.c (gtk_ui_manager_buildable_construct_child): add + g_object_ref() to this construction function (it's the only + implementer in GTK) + + Fixes #496645. + 2008-01-08 Matthias Clasen * === Released 2.12.5 === diff --git a/docs/reference/gtk/tmpl/gtkbuildable.sgml b/docs/reference/gtk/tmpl/gtkbuildable.sgml index a140d78688..16857ae60c 100644 --- a/docs/reference/gtk/tmpl/gtkbuildable.sgml +++ b/docs/reference/gtk/tmpl/gtkbuildable.sgml @@ -61,7 +61,8 @@ a GtkBuilder UI definition. @construct_child: Constructs a child of a buildable that has been specified as "constructor" in the UI definition. #GtkUIManager implements this to reference to a widget created in a <ui> tag which is outside - of the normal GtkBuilder UI definition hierarchy. + of the normal GtkBuilder UI definition hierarchy. A reference to the + constructed object is returned and becomes owned by the caller. @custom_tag_start: Implement this if the buildable needs to parse content below <child>. To handle an element, the implementation must fill in the @parser structure and @user_data and return %TRUE. diff --git a/gtk/gtkbuilder.c b/gtk/gtkbuilder.c index 22feceb720..5f6e1dff88 100644 --- a/gtk/gtkbuilder.c +++ b/gtk/gtkbuilder.c @@ -67,7 +67,6 @@ struct _GtkBuilderPrivate GHashTable *objects; GSList *delayed_properties; GSList *signals; - GSList *root_objects; gchar *filename; }; @@ -114,7 +113,7 @@ gtk_builder_init (GtkBuilder *builder) GtkBuilderPrivate); builder->priv->domain = NULL; builder->priv->objects = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); + g_free, g_object_unref); } @@ -135,9 +134,6 @@ gtk_builder_finalize (GObject *object) g_slist_foreach (priv->signals, (GFunc) _free_signal_info, NULL); g_slist_free (priv->signals); - g_slist_foreach (priv->root_objects, (GFunc) g_object_unref, NULL); - g_slist_free (priv->root_objects); - G_OBJECT_CLASS (gtk_builder_parent_class)->finalize (object); } @@ -406,7 +402,7 @@ _gtk_builder_construct (GtkBuilder *builder, g_assert (obj != NULL); if (construct_parameters->len) g_warning ("Can't pass in construct-only parameters to %s", info->id); - + g_object_ref (obj); } else if (info->parent && ((ChildInfo*)info->parent)->internal_child != NULL) { @@ -414,6 +410,7 @@ _gtk_builder_construct (GtkBuilder *builder, obj = gtk_builder_get_internal_child (builder, info, childname); if (construct_parameters->len) g_warning ("Can't pass in construct-only parameters to %s", childname); + g_object_ref (obj); } else { @@ -421,6 +418,18 @@ _gtk_builder_construct (GtkBuilder *builder, construct_parameters->len, (GParameter *)construct_parameters->data); + /* No matter what, make sure we have a reference. + * + * If it's an initially unowned object, sink it. + * If it's not initially unowned then we have the reference already. + * + * In the case that this is a window it will be sunk already and + * this is effectively a call to g_object_ref(). That's what + * we want. + */ + if (G_IS_INITIALLY_UNOWNED (obj)) + g_object_ref_sink (obj); + GTK_NOTE (BUILDER, g_print ("created %s of type %s\n", info->id, info->class_name)); @@ -472,15 +481,7 @@ _gtk_builder_construct (GtkBuilder *builder, g_strdup (info->id), g_free); - - if (!info->parent && !GTK_IS_WINDOW (obj)) - { - if (g_object_is_floating (obj)) - g_object_ref_sink (obj); - - builder->priv->root_objects = - g_slist_prepend (builder->priv->root_objects, obj); - } + /* we already own a reference to obj. put it in the hash table. */ g_hash_table_insert (builder->priv->objects, g_strdup (info->id), obj); return obj; diff --git a/gtk/gtkuimanager.c b/gtk/gtkuimanager.c index 95aa71da67..664640dd23 100644 --- a/gtk/gtkuimanager.c +++ b/gtk/gtkuimanager.c @@ -497,7 +497,7 @@ gtk_ui_manager_buildable_construct_child (GtkBuildable *buildable, g_signal_connect (widget, "hierarchy-changed", G_CALLBACK (child_hierarchy_changed_cb), GTK_UI_MANAGER (buildable)); - return G_OBJECT (widget); + return g_object_ref (widget); } static void