diff options
author | Matthias Clasen <mclasen@redhat.com> | 2014-09-25 23:05:15 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2014-09-25 23:05:15 -0400 |
commit | 1041f93f7ff95f603260d4edf41bc372697d4206 (patch) | |
tree | 58bee44a040b13b8aed9d82ab0e06ade4f1e8ad1 | |
parent | ed5f6d4333bf152072c1e6c7826185f973dba2cd (diff) | |
download | gtk+-1041f93f7ff95f603260d4edf41bc372697d4206.tar.gz |
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.
-rw-r--r-- | gtk/inspector/classes-list.c | 28 | ||||
-rw-r--r-- | gtk/inspector/css-editor.c | 43 | ||||
-rw-r--r-- | gtk/inspector/prop-list.c | 10 | ||||
-rw-r--r-- | gtk/inspector/widget-tree.c | 6 |
4 files changed, 70 insertions, 17 deletions
diff --git a/gtk/inspector/classes-list.c b/gtk/inspector/classes-list.c index 2d21265aae..1fc313082c 100644 --- a/gtk/inspector/classes-list.c +++ b/gtk/inspector/classes-list.c @@ -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) @@ -291,9 +294,22 @@ gtk_inspector_classes_list_set_object (GtkInspectorClassesList *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); diff --git a/gtk/inspector/css-editor.c b/gtk/inspector/css-editor.c index d8f5181920..7bfaa26686 100644 --- a/gtk/inspector/css-editor.c +++ b/gtk/inspector/css-editor.c @@ -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 @@ -334,6 +337,30 @@ create_provider (GtkInspectorCssEditor *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) { ce->priv = gtk_inspector_css_editor_get_instance_private (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: diff --git a/gtk/inspector/prop-list.c b/gtk/inspector/prop-list.c index 707e4a234c..139977748e 100644 --- a/gtk/inspector/prop-list.c +++ b/gtk/inspector/prop-list.c @@ -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)); diff --git a/gtk/inspector/widget-tree.c b/gtk/inspector/widget-tree.c index 6f3ec6ac64..8fd6130866 100644 --- a/gtk/inspector/widget-tree.c +++ b/gtk/inspector/widget-tree.c @@ -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); |