forked from AuroraMiddleware/gtk
inspector: life-cycle fixes
When closing the inspector before the main window, we must take care to sever all signal connections and weak refs, otherwise things will go bad when the window is closed later.
This commit is contained in:
parent
ed5f6d4333
commit
1041f93f7f
@ -225,20 +225,23 @@ gtk_inspector_classes_list_init (GtkInspectorClassesList *cl)
|
||||
gtk_widget_init_template (GTK_WIDGET (cl));
|
||||
}
|
||||
|
||||
static void remove_dead_object (gpointer data, GObject *dead_object);
|
||||
static void gtk_inspector_classes_list_remove_dead_object (gpointer data, GObject *dead_object);
|
||||
|
||||
static void
|
||||
cleanup_context (GtkInspectorClassesList *cl)
|
||||
{
|
||||
if (cl->priv->context)
|
||||
g_object_weak_unref (G_OBJECT (cl->priv->context), remove_dead_object, cl);
|
||||
{
|
||||
g_object_weak_unref (G_OBJECT (cl->priv->context),gtk_inspector_classes_list_remove_dead_object, cl);
|
||||
cl->priv->context = NULL;
|
||||
}
|
||||
|
||||
gtk_list_store_clear (cl->priv->model);
|
||||
cl->priv->context = NULL;
|
||||
if (cl->priv->model)
|
||||
gtk_list_store_clear (cl->priv->model);
|
||||
}
|
||||
|
||||
static void
|
||||
remove_dead_object (gpointer data, GObject *dead_object)
|
||||
gtk_inspector_classes_list_remove_dead_object (gpointer data, GObject *dead_object)
|
||||
{
|
||||
GtkInspectorClassesList *cl = data;
|
||||
|
||||
@ -267,7 +270,7 @@ gtk_inspector_classes_list_set_object (GtkInspectorClassesList *cl,
|
||||
|
||||
cl->priv->context = gtk_widget_get_style_context (GTK_WIDGET (object));
|
||||
|
||||
g_object_weak_ref (G_OBJECT (cl->priv->context), remove_dead_object, cl);
|
||||
g_object_weak_ref (G_OBJECT (cl->priv->context), gtk_inspector_classes_list_remove_dead_object, cl);
|
||||
|
||||
hash_context = get_hash_context (cl);
|
||||
if (hash_context)
|
||||
@ -290,10 +293,23 @@ gtk_inspector_classes_list_set_object (GtkInspectorClassesList *cl,
|
||||
read_classes_from_style_context (cl);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_inspector_classes_list_finalize (GObject *object)
|
||||
{
|
||||
GtkInspectorClassesList *cl = GTK_INSPECTOR_CLASSES_LIST (object);
|
||||
|
||||
cleanup_context (cl);
|
||||
|
||||
G_OBJECT_CLASS (gtk_inspector_classes_list_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_inspector_classes_list_class_init (GtkInspectorClassesListClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gtk_inspector_classes_list_finalize;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/inspector/classes-list.ui");
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorClassesList, model);
|
||||
|
@ -67,6 +67,9 @@ struct _GtkInspectorCssEditorPrivate
|
||||
guint timeout;
|
||||
};
|
||||
|
||||
static void gtk_inspector_css_editor_remove_dead_object (gpointer data,
|
||||
GObject *dead_object);
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorCssEditor, gtk_inspector_css_editor, GTK_TYPE_BOX)
|
||||
|
||||
static void
|
||||
@ -333,6 +336,30 @@ create_provider (GtkInspectorCssEditor *ce)
|
||||
G_CALLBACK (show_parsing_error), ce);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_provider (GtkInspectorCssEditor *ce)
|
||||
{
|
||||
if (ce->priv->global)
|
||||
{
|
||||
gtk_style_context_remove_provider_for_screen (gdk_screen_get_default (),
|
||||
GTK_STYLE_PROVIDER (ce->priv->provider));
|
||||
g_object_unref (ce->priv->provider);
|
||||
ce->priv->provider = NULL;
|
||||
}
|
||||
else if (ce->priv->context)
|
||||
{
|
||||
GtkStyleProvider *provider;
|
||||
|
||||
provider = g_object_get_data (G_OBJECT (ce->priv->context),
|
||||
GTK_INSPECTOR_CSS_EDITOR_PROVIDER);
|
||||
gtk_style_context_remove_provider (ce->priv->context, provider);
|
||||
g_object_set_data (G_OBJECT (ce->priv->context),
|
||||
GTK_INSPECTOR_CSS_EDITOR_PROVIDER,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gtk_inspector_css_editor_init (GtkInspectorCssEditor *ce)
|
||||
{
|
||||
@ -398,6 +425,16 @@ finalize (GObject *object)
|
||||
if (ce->priv->timeout != 0)
|
||||
g_source_remove (ce->priv->timeout);
|
||||
|
||||
destroy_provider (ce);
|
||||
if (ce->priv->context)
|
||||
{
|
||||
g_object_weak_unref (G_OBJECT (ce->priv->context), gtk_inspector_css_editor_remove_dead_object, ce);
|
||||
g_object_set_data (G_OBJECT (ce->priv->context),
|
||||
GTK_INSPECTOR_CSS_EDITOR_TEXT,
|
||||
NULL);
|
||||
ce->priv->context = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gtk_inspector_css_editor_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@ -427,7 +464,7 @@ gtk_inspector_css_editor_class_init (GtkInspectorCssEditorClass *klass)
|
||||
}
|
||||
|
||||
static void
|
||||
remove_dead_object (gpointer data, GObject *dead_object)
|
||||
gtk_inspector_css_editor_remove_dead_object (gpointer data, GObject *dead_object)
|
||||
{
|
||||
GtkInspectorCssEditor *ce = data;
|
||||
|
||||
@ -447,7 +484,7 @@ gtk_inspector_css_editor_set_object (GtkInspectorCssEditor *ce,
|
||||
|
||||
if (ce->priv->context)
|
||||
{
|
||||
g_object_weak_unref (G_OBJECT (ce->priv->context), remove_dead_object, ce);
|
||||
g_object_weak_unref (G_OBJECT (ce->priv->context), gtk_inspector_css_editor_remove_dead_object, ce);
|
||||
text = get_current_text (GTK_TEXT_BUFFER (ce->priv->text));
|
||||
g_object_set_data_full (G_OBJECT (ce->priv->context),
|
||||
GTK_INSPECTOR_CSS_EDITOR_TEXT,
|
||||
@ -472,7 +509,7 @@ gtk_inspector_css_editor_set_object (GtkInspectorCssEditor *ce,
|
||||
set_initial_text (ce);
|
||||
disable_toggled (ce->priv->disable_button, ce);
|
||||
|
||||
g_object_weak_ref (G_OBJECT (ce->priv->context), remove_dead_object, ce);
|
||||
g_object_weak_ref (G_OBJECT (ce->priv->context), gtk_inspector_css_editor_remove_dead_object, ce);
|
||||
}
|
||||
|
||||
// vim: set et sw=2 ts=2:
|
||||
|
@ -391,14 +391,14 @@ gtk_inspector_prop_list_set_object (GtkInspectorPropList *pl,
|
||||
g_free (props);
|
||||
|
||||
if (GTK_IS_WIDGET (object))
|
||||
g_signal_connect_swapped (object, "destroy", G_CALLBACK (cleanup_object), pl);
|
||||
g_signal_connect_object (object, "destroy", G_CALLBACK (cleanup_object), pl, G_CONNECT_SWAPPED);
|
||||
|
||||
/* Listen for updates */
|
||||
pl->priv->notify_handler_id =
|
||||
g_signal_connect (object,
|
||||
pl->priv->child_properties ? "child-notify" : "notify",
|
||||
G_CALLBACK (gtk_inspector_prop_list_prop_changed_cb),
|
||||
pl);
|
||||
g_signal_connect_object (object,
|
||||
pl->priv->child_properties ? "child-notify" : "notify",
|
||||
G_CALLBACK (gtk_inspector_prop_list_prop_changed_cb),
|
||||
pl, 0);
|
||||
|
||||
gtk_widget_show (GTK_WIDGET (pl));
|
||||
|
||||
|
@ -88,7 +88,7 @@ typedef struct
|
||||
} ObjectData;
|
||||
|
||||
static void
|
||||
remove_dead_object (gpointer data, GObject *dead_object)
|
||||
gtk_widget_tree_remove_dead_object (gpointer data, GObject *dead_object)
|
||||
{
|
||||
ObjectData *od = data;
|
||||
|
||||
@ -113,7 +113,7 @@ object_data_free (gpointer data)
|
||||
gtk_tree_row_reference_free (od->row);
|
||||
|
||||
if (od->object)
|
||||
g_object_weak_unref (od->object, remove_dead_object, od);
|
||||
g_object_weak_unref (od->object, gtk_widget_tree_remove_dead_object, od);
|
||||
|
||||
g_free (od);
|
||||
}
|
||||
@ -333,7 +333,7 @@ gtk_inspector_widget_tree_append_object (GtkInspectorWidgetTree *wt,
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
g_hash_table_insert (wt->priv->iters, object, od);
|
||||
g_object_weak_ref (object, remove_dead_object, od);
|
||||
g_object_weak_ref (object, gtk_widget_tree_remove_dead_object, od);
|
||||
|
||||
g_free (address);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user