summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2014-09-25 23:05:15 -0400
committerMatthias Clasen <mclasen@redhat.com>2014-09-25 23:05:15 -0400
commit1041f93f7ff95f603260d4edf41bc372697d4206 (patch)
tree58bee44a040b13b8aed9d82ab0e06ade4f1e8ad1
parented5f6d4333bf152072c1e6c7826185f973dba2cd (diff)
downloadgtk+-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.c28
-rw-r--r--gtk/inspector/css-editor.c43
-rw-r--r--gtk/inspector/prop-list.c10
-rw-r--r--gtk/inspector/widget-tree.c6
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);