Commit e551f1d1 authored by Tristan Van Berkom's avatar Tristan Van Berkom
Browse files

* 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.
parent b9a0f374
......@@ -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:
......
......@@ -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");
}
......
......@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment