[gtk+] inspector: life-cycle fixes



commit 1041f93f7ff95f603260d4edf41bc372697d4206
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Sep 25 23:05:15 2014 -0400

    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.

 gtk/inspector/classes-list.c |   28 +++++++++++++++++++++-----
 gtk/inspector/css-editor.c   |   43 +++++++++++++++++++++++++++++++++++++++--
 gtk/inspector/prop-list.c    |   10 ++++----
 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 2d21265..1fc3130 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 d8f5181..7bfaa26 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 707e4a2..1399777 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 6f3ec6a..8fd6130 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);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]