[glade3/glade-3-8] * gladeui/glade-widget.[ch]: Hide glade_widget_set_object(), improved reference count balancing
- From: Tristan Van Berkom <tvb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glade3/glade-3-8] * gladeui/glade-widget.[ch]: Hide glade_widget_set_object(), improved reference count balancing
- Date: Sun, 19 Dec 2010 11:03:01 +0000 (UTC)
commit 327b18ec942ddf78b7c016491cef76f203bfaa84
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date: Sun Dec 19 20:07:12 2010 +0900
* gladeui/glade-widget.[ch]: Hide glade_widget_set_object(), improved reference count
balancing and fixed segfaults upon closing projects that contain filechooser dialogs
referenced by filechooserbuttons.
ChangeLog | 4 ++
gladeui/glade-widget.c | 118 ++++++++++++++++++++++++++---------------------
gladeui/glade-widget.h | 3 -
3 files changed, 69 insertions(+), 56 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index eedb248..26c88be 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,10 @@
* plugins/gtk+/glade-gtk.c: Removed alpha_sort_box_children(), project needs to be
sorted with box children by position, loading process depends on this.
+ * gladeui/glade-widget.[ch]: Hide glade_widget_set_object(), improved reference count
+ balancing and fixed segfaults upon closing projects that contain filechooser dialogs
+ referenced by filechooserbuttons.
+
2010-12-18 Tristan Van Berkom <tristanvb openismus com>
* src/Makefile.am, gladeui/Makefile.am, plugins/gtk+/Makefile.am, plugins/gnome/Makefile.am:
diff --git a/gladeui/glade-widget.c b/gladeui/glade-widget.c
index d5acc5d..ac67f1b 100644
--- a/gladeui/glade-widget.c
+++ b/gladeui/glade-widget.c
@@ -63,8 +63,11 @@ static void glade_widget_set_adaptor (GladeWidget *w
GladeWidgetAdaptor *adaptor);
static void glade_widget_set_properties (GladeWidget *widget,
GList *properties);
-static gboolean glade_window_is_embedded (GtkWindow *window);
-static gboolean glade_widget_embed (GladeWidget *widget);
+static gboolean glade_window_is_embedded (GtkWindow *window);
+static gboolean glade_widget_embed (GladeWidget *widget);
+static void glade_widget_set_object (GladeWidget *gwidget,
+ GObject *new_object,
+ gboolean destroy);
enum
{
@@ -166,6 +169,8 @@ glade_widget_remove_child_impl (GladeWidget *widget,
(widget->adaptor, widget->object, child->object);
g_object_unref (child);
+
+ child->parent = NULL;
}
static void
@@ -532,7 +537,7 @@ glade_widget_build_object (GladeWidget *widget,
if (reason == GLADE_CREATE_LOAD)
{
object = glade_widget_adaptor_construct_object (widget->adaptor, 0, NULL);
- glade_widget_set_object (widget, object);
+ glade_widget_set_object (widget, object, TRUE);
return object;
}
@@ -547,7 +552,8 @@ glade_widget_build_object (GladeWidget *widget,
free_params (params, n_params);
- glade_widget_set_object (widget, object);
+ /* Dont destroy toplevels when rebuilding, handle that separately */
+ glade_widget_set_object (widget, object, reason != GLADE_CREATE_REBUILD);
if (template)
params = glade_widget_template_params (widget, FALSE, &n_params);
@@ -747,9 +753,9 @@ glade_widget_constructor (GType type,
if (gwidget->object == NULL)
{
- object = glade_widget_build_object(gwidget,
- gwidget->construct_template,
- gwidget->construct_reason);
+ object = glade_widget_build_object (gwidget,
+ gwidget->construct_template,
+ gwidget->construct_reason);
}
/* Copy sync parentless widget props here after a dup
@@ -849,16 +855,6 @@ glade_widget_dispose (GObject *object)
glade_widget_push_superuser ();
- /* Release references by way of object properties... */
- while (widget->prop_refs)
- {
- GladeProperty *property = GLADE_PROPERTY (widget->prop_refs->data);
- glade_property_set (property, NULL);
- }
-
- if (widget->properties)
- g_list_foreach (widget->properties, (GFunc)reset_object_property, widget->project);
-
/* Unparent all children */
if ((children =
glade_widget_get_children (widget)) != NULL)
@@ -873,6 +869,16 @@ glade_widget_dispose (GObject *object)
g_list_free (children);
}
+ /* Release references by way of object properties... */
+ while (widget->prop_refs)
+ {
+ GladeProperty *property = GLADE_PROPERTY (widget->prop_refs->data);
+ glade_property_set (property, NULL);
+ }
+
+ if (widget->properties)
+ g_list_foreach (widget->properties, (GFunc)reset_object_property, widget->project);
+
/* We have to make sure properties release thier references on other widgets first
* hence the reset (for object properties) */
if (widget->properties)
@@ -882,13 +888,7 @@ glade_widget_dispose (GObject *object)
widget->properties = NULL;
}
- /* 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);
+ glade_widget_set_object (widget, NULL, TRUE);
if (widget->packing_properties)
{
@@ -939,7 +939,7 @@ glade_widget_set_real_property (GObject *object,
break;
case PROP_OBJECT:
if (g_value_get_object (value))
- glade_widget_set_object (widget, g_value_get_object (value));
+ glade_widget_set_object (widget, g_value_get_object (value), TRUE);
break;
case PROP_PROJECT:
glade_widget_set_project (widget, GLADE_PROJECT (g_value_get_object (value)));
@@ -2418,8 +2418,8 @@ glade_widget_rebuild (GladeWidget *gwidget)
/* Hold a reference to the old widget while we transport properties
* and children from it
*/
- old_object = g_object_ref(glade_widget_get_object (gwidget));
- new_object = glade_widget_build_object(gwidget, gwidget, GLADE_CREATE_REBUILD);
+ old_object = g_object_ref (glade_widget_get_object (gwidget));
+ new_object = glade_widget_build_object (gwidget, gwidget, GLADE_CREATE_REBUILD);
/* Only call this once the object has a proper GladeWidget */
glade_widget_adaptor_post_create (adaptor, new_object, GLADE_CREATE_REBUILD);
@@ -2431,10 +2431,10 @@ glade_widget_rebuild (GladeWidget *gwidget)
old_object, new_object);
/* Must call dispose for cases like dialogs and toplevels */
- if (g_type_is_a (adaptor->type, GTK_TYPE_OBJECT))
- gtk_object_destroy (GTK_OBJECT (old_object));
+ if (GTK_IS_WINDOW (old_object))
+ gtk_widget_destroy (GTK_WIDGET (old_object));
else
- g_object_run_dispose (G_OBJECT (old_object));
+ g_object_unref (old_object);
/* Reparent any children of the old object to the new object
* (this function will consume and free the child list).
@@ -2470,7 +2470,8 @@ glade_widget_rebuild (GladeWidget *gwidget)
/* Sync packing.
*/
- glade_widget_sync_packing_props (gwidget);
+ if (gwidget->parent)
+ glade_widget_sync_packing_props (gwidget);
/* If the widget was in a project (and maybe the selection), then
* restore that stuff.
@@ -3327,17 +3328,8 @@ glade_widget_event_private (GtkWidget *widget,
return FALSE;
}
-/**
- * glade_widget_set_object:
- * @gwidget: A #GladeWidget
- * @new_object: the new #GObject for @gwidget
- *
- * Set the runtime object for this GladeWidget wrapper
- * (this is used deep in the core and is probably unsafe
- * to use elsewhere).
- */
-void
-glade_widget_set_object (GladeWidget *gwidget, GObject *new_object)
+static void
+glade_widget_set_object (GladeWidget *gwidget, GObject *new_object, gboolean destroy)
{
GladeWidgetAdaptor *adaptor;
GObject *old_object;
@@ -3347,19 +3339,22 @@ glade_widget_set_object (GladeWidget *gwidget, GObject *new_object)
g_type_is_a (G_OBJECT_TYPE (new_object),
gwidget->adaptor->type));
- adaptor = gwidget->adaptor;
- old_object = gwidget->object;
+ if (gwidget->object == new_object)
+ return;
+
+ adaptor = gwidget->adaptor;
+ old_object = gwidget->object;
+ gwidget->object = new_object;
if (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;
+ if (gwidget->internal == NULL)
+ {
+ /* Assume ownership of floating objects */
+ if (g_object_is_floating (new_object))
+ g_object_ref_sink (new_object);
+ }
g_object_set_qdata (G_OBJECT (new_object), glade_widget_name_quark, gwidget);
@@ -3381,10 +3376,27 @@ glade_widget_set_object (GladeWidget *gwidget, GObject *new_object)
}
/* Remove internal reference to old widget */
- if (gwidget->internal == NULL && old_object)
+ if (old_object)
{
+ /* From this point on, the GladeWidget is no longer retrievable with
+ * glade_widget_get_from_gobject() */
g_object_set_qdata (G_OBJECT (old_object), glade_widget_name_quark, NULL);
- g_object_unref (G_OBJECT (old_object));
+
+ if (gwidget->internal == NULL)
+ {
+
+#if _YOU_WANT_TO_LOOK_AT_PROJECT_REFCOUNT_BALANCING_
+ g_print ("Killing '%s::%s' widget's object with reference count %d\n",
+ gwidget->adaptor->name, gwidget->name ? gwidget->name : "(unknown)",
+ old_object->ref_count);
+#endif
+
+ if (GTK_IS_WINDOW (old_object) && destroy)
+ gtk_widget_destroy (GTK_WIDGET (old_object));
+ else
+ g_object_unref (old_object);
+
+ }
}
g_object_notify (G_OBJECT (gwidget), "object");
}
diff --git a/gladeui/glade-widget.h b/gladeui/glade-widget.h
index 3d909f7..541e2f1 100644
--- a/gladeui/glade-widget.h
+++ b/gladeui/glade-widget.h
@@ -398,9 +398,6 @@ void glade_widget_set_internal (GladeWidget *widget,
const gchar *internal);
G_CONST_RETURN gchar *glade_widget_get_internal (GladeWidget *widget);
-
-void glade_widget_set_object (GladeWidget *gwidget,
- GObject *new_object);
GObject *glade_widget_get_object (GladeWidget *widget);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]