[glade3] * gladeui/glade-widget.[ch], gladeui/glade-project.c, plugins/gtk+/glade-gtk.c: Cleanup object r
- From: Tristan Van Berkom <tvb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glade3] * gladeui/glade-widget.[ch], gladeui/glade-project.c, plugins/gtk+/glade-gtk.c: Cleanup object r
- Date: Wed, 15 Dec 2010 12:43:08 +0000 (UTC)
commit 6b3a5ec94873110f731f1b4ef959b72dbeb96206
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date: Wed Dec 15 21:45:58 2010 +0900
* gladeui/glade-widget.[ch], gladeui/glade-project.c, plugins/gtk+/glade-gtk.c: Cleanup
object ref count cycles, now GladeProject just releases all widgets from the project
and keeps a reference to the GladeWidget instead of the GObject, GladeWidget is now
GInitiallyUnowned and GladeProject assumes ownership when objects are added to the
project (glade-gtk.c in this patch avoids needlessly adding a widget to the project
that will be implicitly added, now glade-gtk.c does not directly manually add any
widgets to the project).
ChangeLog | 8 +++
gladeui/glade-project.c | 67 ++++++---------------------
gladeui/glade-widget.c | 115 ++++++++++++++++++++++++++++++----------------
gladeui/glade-widget.h | 4 +-
plugins/gtk+/glade-gtk.c | 8 +---
5 files changed, 101 insertions(+), 101 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 8ae401d..ae11647 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,14 @@
* plugins/gtk+/glade-gtk.c: Fixed errors when undoing the addition of notebook pages.
The problem at length was an issue of orphaned project widgets left in the project model.
+ * gladeui/glade-widget.[ch], gladeui/glade-project.c, plugins/gtk+/glade-gtk.c: Cleanup
+ object ref count cycles, now GladeProject just releases all widgets from the project
+ and keeps a reference to the GladeWidget instead of the GObject, GladeWidget is now
+ GInitiallyUnowned and GladeProject assumes ownership when objects are added to the
+ project (glade-gtk.c in this patch avoids needlessly adding a widget to the project
+ that will be implicitly added, now glade-gtk.c does not directly manually add any
+ widgets to the project).
+
2010-12-14 Tristan Van Berkom <tristanvb openismus com>
* Reverted 3.0 commit, now targetting this branch to the final GTK+ 2.x chapter
diff --git a/gladeui/glade-project.c b/gladeui/glade-project.c
index 5efa157..43df9bc 100644
--- a/gladeui/glade-project.c
+++ b/gladeui/glade-project.c
@@ -263,9 +263,7 @@ static void
glade_project_dispose (GObject *object)
{
GladeProject *project = GLADE_PROJECT (object);
- GList *list;
- GladeWidget *gwidget;
- GladeProperty *property;
+ GList *list, *tree;
/* Emit close signal */
g_signal_emit (object, glade_project_signals [CLOSE], 0);
@@ -275,41 +273,11 @@ glade_project_dispose (GObject *object)
glade_project_list_unref (project->priv->undo_stack);
project->priv->undo_stack = NULL;
- /* Unparent all widgets in the heirarchy first
- * (Since we are bookkeeping exact reference counts, we
- * dont want the hierarchy to just get destroyed)
- */
- for (list = project->priv->objects; list; list = list->next)
- {
- gwidget = glade_widget_get_from_gobject (list->data);
-
- if (gwidget->parent &&
- gwidget->internal == NULL &&
- glade_widget_adaptor_has_child (gwidget->parent->adaptor,
- gwidget->parent->object,
- gwidget->object))
- glade_widget_remove_child (gwidget->parent, gwidget);
-
- /* Release references by way of object properties... */
- while (gwidget->prop_refs)
- {
- property = GLADE_PROPERTY (gwidget->prop_refs->data);
- glade_property_set (property, NULL);
- }
- }
-
/* Remove objects from the project */
- for (list = project->priv->objects; list; list = list->next)
- {
- gwidget = glade_widget_get_from_gobject (list->data);
- g_object_unref (G_OBJECT (list->data)); /* Remove the GladeProject reference */
- g_object_unref (G_OBJECT (gwidget)); /* Remove the overall "Glade" reference */
- }
- g_list_free (list);
- g_list_free (project->priv->objects);
- g_list_free (project->priv->tree);
- project->priv->tree = NULL;
- project->priv->objects = NULL;
+ tree = g_list_copy (project->priv->tree);
+ for (list = tree; list; list = list->next)
+ glade_project_remove_object (project, list->data);
+ g_list_free (tree);
G_OBJECT_CLASS (glade_project_parent_class)->dispose (object);
}
@@ -1472,9 +1440,7 @@ glade_project_load_from_file (GladeProject *project, const gchar *path)
continue;
if ((widget = glade_widget_read (project, NULL, node, NULL)) != NULL)
- {
glade_project_add_object (project, NULL, widget->object);
- }
}
if (!has_gtk_dep)
@@ -2895,7 +2861,7 @@ glade_project_add_object (GladeProject *project,
GladeWidget *gwidget;
GList *list, *children;
gchar *name;
- GtkTreeIter iter;
+ GtkTreeIter iter;
GtkTreePath *path;
g_return_if_fail (GLADE_IS_PROJECT (project));
@@ -2911,10 +2877,12 @@ glade_project_add_object (GladeProject *project,
*/
if ((gwidget = glade_widget_get_from_gobject (object)) == NULL)
return;
-
- /* set the project */
- if (gwidget->project != project)
- glade_widget_set_project (gwidget, project);
+
+ if (glade_project_has_object (project, object))
+ {
+ g_warning ("Trying to add an object to the project that is already in the project\n");
+ return;
+ }
/* Create a name context for newly added toplevels... */
if (!gwidget->parent)
@@ -2938,7 +2906,7 @@ glade_project_add_object (GladeProject *project,
glade_project_reserve_widget_name (project, gwidget, gwidget->name);
glade_widget_set_project (gwidget, (gpointer)project);
- g_object_ref (object);
+ g_object_ref_sink (gwidget);
if (glade_widget_get_parent (gwidget) == NULL)
{
@@ -2947,8 +2915,7 @@ glade_project_add_object (GladeProject *project,
}
/* Be sure to update the list before emitting signals */
- project->priv->objects = g_list_prepend (project->priv->objects,
- object);
+ project->priv->objects = g_list_prepend (project->priv->objects, object);
if (!project->priv->loading)
{
@@ -2996,8 +2963,6 @@ glade_project_has_object (GladeProject *project, GObject *object)
return (g_list_find (project->priv->objects, object)) != NULL;
}
-
-GladeWidget *project_debug_widget;
/**
* glade_project_remove_object:
* @project: a #GladeProject
@@ -3026,8 +2991,6 @@ glade_project_remove_object (GladeProject *project, GObject *object)
if ((gwidget = glade_widget_get_from_gobject (object)) == NULL)
return;
- project_debug_widget = gwidget;
-
/* Recurse and remove deepest children first */
if ((children =
glade_widget_get_children (gwidget)) != NULL)
@@ -3062,7 +3025,7 @@ glade_project_remove_object (GladeProject *project, GObject *object)
}
project->priv->objects = g_list_remove (project->priv->objects, object);
- g_object_unref (object);
+ g_object_unref (gwidget);
project->priv->stamp++;
diff --git a/gladeui/glade-widget.c b/gladeui/glade-widget.c
index 15efdbd..e0116c8 100644
--- a/gladeui/glade-widget.c
+++ b/gladeui/glade-widget.c
@@ -102,7 +102,7 @@ static guint glade_widget_signals[LAST_SIGNAL] = {0};
static GQuark glade_widget_name_quark = 0;
-G_DEFINE_TYPE (GladeWidget, glade_widget, G_TYPE_OBJECT)
+G_DEFINE_TYPE (GladeWidget, glade_widget, G_TYPE_INITIALLY_UNOWNED)
/*******************************************************************************
GladeWidget class methods
@@ -802,6 +802,8 @@ glade_widget_finalize (GObject *object)
g_return_if_fail (GLADE_IS_WIDGET (object));
+ g_print ("Finalizing a widget with name %s\n", widget->name);
+
g_free (widget->name);
g_free (widget->internal);
g_free (widget->support_warning);
@@ -812,35 +814,64 @@ glade_widget_finalize (GObject *object)
if (widget->pack_props_hash)
g_hash_table_destroy (widget->pack_props_hash);
- G_OBJECT_CLASS(glade_widget_parent_class)->finalize(object);
+ G_OBJECT_CLASS (glade_widget_parent_class)->finalize(object);
+}
+
+static void
+reset_object_property (GladeProperty *property,
+ GladeProject *project)
+{
+ if (glade_property_class_is_object (property->klass,
+ glade_project_get_format (project)))
+ glade_property_reset (property);
}
static void
glade_widget_dispose (GObject *object)
{
GladeWidget *widget = GLADE_WIDGET (object);
+ GladeWidget *child;
+ GList *children, *list;
g_return_if_fail (GLADE_IS_WIDGET (object));
- /* At this point, any callbacks on "object" generated by destroy
- * wont come with a GladeWidget
- */
- g_object_set_qdata (G_OBJECT (object), glade_widget_name_quark, NULL);
-
- /* We do not keep a reference to internal widgets */
- if (widget->internal == NULL)
+ /* Release references by way of object properties... */
+ while (widget->prop_refs)
{
- if (GTK_IS_OBJECT (widget->object))
- gtk_object_destroy (GTK_OBJECT (widget->object));
- else
- g_object_unref (widget->object);
+ GladeProperty *property = GLADE_PROPERTY (widget->prop_refs->data);
+ glade_property_set (property, NULL);
}
+ /* We have to make sure properties release thier references on other widgets first
+ * hence the reset (for object properties) */
if (widget->properties)
{
+ g_list_foreach (widget->properties, (GFunc)reset_object_property, widget->project);
g_list_foreach (widget->properties, (GFunc)g_object_unref, NULL);
g_list_free (widget->properties);
}
+
+ /* Unparent all children */
+ if ((children =
+ glade_widget_get_children (widget)) != NULL)
+ {
+ for (list = children; list; list = list->next)
+ {
+ child = glade_widget_get_from_gobject (list->data);
+
+ if (child->internal == NULL)
+ glade_widget_remove_child (widget, child);
+ }
+ g_list_free (children);
+ }
+
+ /* We do not keep a reference to internal widgets */
+ glade_widget_set_object (widget, NULL);
+
+ /* At this point, any callbacks on "object" generated by destroy
+ * wont come with a GladeWidget
+ */
+ g_object_set_qdata (G_OBJECT (object), glade_widget_name_quark, NULL);
if (widget->packing_properties)
{
@@ -859,7 +890,7 @@ glade_widget_dispose (GObject *object)
g_list_foreach (widget->packing_actions, (GFunc)g_object_unref, NULL);
g_list_free (widget->packing_actions);
}
-
+
G_OBJECT_CLASS (glade_widget_parent_class)->dispose (object);
}
@@ -3336,42 +3367,46 @@ glade_widget_set_object (GladeWidget *gwidget, GObject *new_object)
GObject *old_object;
g_return_if_fail (GLADE_IS_WIDGET (gwidget));
- g_return_if_fail (G_IS_OBJECT (new_object));
- g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (new_object),
+ g_return_if_fail (new_object == NULL ||
+ g_type_is_a (G_OBJECT_TYPE (new_object),
gwidget->adaptor->type));
adaptor = gwidget->adaptor;
old_object = gwidget->object;
-
- /* Add internal reference to new widget if its not internal */
- if (gwidget->internal)
- gwidget->object = G_OBJECT(new_object);
- else if (GTK_IS_OBJECT (new_object))
- gwidget->object = g_object_ref (G_OBJECT(new_object));
- else
- /* If this is a base GObject; assume ownership of the initial ref count */
- gwidget->object = new_object;
-
- g_object_set_qdata (G_OBJECT (new_object), glade_widget_name_quark, gwidget);
- if (g_type_is_a (gwidget->adaptor->type, GTK_TYPE_WIDGET))
+ if (new_object)
{
- /* Disable any built-in DnD
- */
- gtk_drag_dest_unset (GTK_WIDGET (new_object));
- gtk_drag_source_unset (GTK_WIDGET (new_object));
+ /* Add internal reference to new widget if its not internal */
+ if (gwidget->internal)
+ gwidget->object = G_OBJECT(new_object);
+ else if (GTK_IS_OBJECT (new_object))
+ gwidget->object = g_object_ref (G_OBJECT(new_object));
+ else
+ /* If this is a base GObject; assume ownership of the initial ref count */
+ gwidget->object = new_object;
+
+ g_object_set_qdata (G_OBJECT (new_object), glade_widget_name_quark, gwidget);
- /* Take care of drawing selection directly on widgets
- * for the time being
- */
- glade_widget_connect_signal_handlers
- (GTK_WIDGET(new_object),
- G_CALLBACK (glade_widget_event_private),
- gwidget);
+ if (g_type_is_a (gwidget->adaptor->type, GTK_TYPE_WIDGET))
+ {
+ /* Disable any built-in DnD
+ */
+ gtk_drag_dest_unset (GTK_WIDGET (new_object));
+ gtk_drag_source_unset (GTK_WIDGET (new_object));
+
+ /* Take care of drawing selection directly on widgets
+ * for the time being
+ */
+ glade_widget_connect_signal_handlers
+ (GTK_WIDGET(new_object),
+ G_CALLBACK (glade_widget_event_private),
+ gwidget);
+ }
}
/* Remove internal reference to old widget */
- if (gwidget->internal == NULL && old_object) {
+ if (gwidget->internal == NULL && old_object)
+ {
g_object_set_qdata (G_OBJECT (old_object), glade_widget_name_quark, NULL);
g_object_unref (G_OBJECT (old_object));
}
diff --git a/gladeui/glade-widget.h b/gladeui/glade-widget.h
index 3094d6d..bbc3f1d 100644
--- a/gladeui/glade-widget.h
+++ b/gladeui/glade-widget.h
@@ -23,7 +23,7 @@ typedef struct _GladeWidgetClass GladeWidgetClass;
struct _GladeWidget
{
- GObject parent_instance;
+ GInitiallyUnowned parent_instance;
GladeWidgetAdaptor *adaptor; /* An adaptor class for the object type */
@@ -117,7 +117,7 @@ struct _GladeWidget
struct _GladeWidgetClass
{
- GObjectClass parent_class;
+ GInitiallyUnownedClass parent_class;
void (*add_child) (GladeWidget *, GladeWidget *, gboolean);
void (*remove_child) (GladeWidget *, GladeWidget *);
diff --git a/plugins/gtk+/glade-gtk.c b/plugins/gtk+/glade-gtk.c
index f2b145f..d8ac55a 100644
--- a/plugins/gtk+/glade-gtk.c
+++ b/plugins/gtk+/glade-gtk.c
@@ -3944,12 +3944,6 @@ glade_gtk_notebook_set_n_pages (GObject *object, const GValue *value)
if (old_size == 0 && new_size > 1)
{
gtab = glade_gtk_notebook_generate_tab (widget, position + 1);
-
- /* Must tell the project that were adding a widget (so that
- * saving works properly & it appears in the inspector properly)
- */
- glade_project_add_object (glade_widget_get_project (widget),
- NULL, gtab->object);
/* Must pass through GladeWidget api so that packing props
* are correctly assigned.
@@ -3960,7 +3954,7 @@ glade_gtk_notebook_set_n_pages (GObject *object, const GValue *value)
{
GtkWidget *tab_placeholder = glade_placeholder_new ();
- g_object_set_data (tab_placeholder, "special-child-type", "tab");
+ g_object_set_data (G_OBJECT (tab_placeholder), "special-child-type", "tab");
gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), placeholder,
tab_placeholder);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]