From ec57c6c10b3a0774a27e11a9279a25b90ce76ed4 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 18 Mar 2015 18:22:17 +0100 Subject: [PATCH] csspathnode: Handle context going away Sometimes path nodes can survive longer than the style context that created them. Don't crash in those cases. Fixes startup of mutter. Testcase included. https://bugzilla.gnome.org/show_bug.cgi?id=746407 --- gtk/gtkcsspathnode.c | 11 +++++++++++ gtk/gtkcsspathnodeprivate.h | 2 ++ gtk/gtkstylecontext.c | 7 +++++-- testsuite/gtk/stylecontext.c | 15 +++++++++++++++ 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/gtk/gtkcsspathnode.c b/gtk/gtkcsspathnode.c index e9b5298733..fecb4552a9 100644 --- a/gtk/gtkcsspathnode.c +++ b/gtk/gtkcsspathnode.c @@ -156,6 +156,17 @@ gtk_css_path_node_new (GtkStyleContext *context) return GTK_CSS_NODE (node); } +void +gtk_css_path_node_unset_context (GtkCssPathNode *node) +{ + gtk_internal_return_if_fail (GTK_IS_CSS_PATH_NODE (node)); + gtk_internal_return_if_fail (node->context != NULL); + + node->context = NULL; + + gtk_css_node_invalidate_style_provider (GTK_CSS_NODE (node)); +} + void gtk_css_path_node_set_widget_path (GtkCssPathNode *node, GtkWidgetPath *path) diff --git a/gtk/gtkcsspathnodeprivate.h b/gtk/gtkcsspathnodeprivate.h index dd3831cc5b..4c7d60e5bd 100644 --- a/gtk/gtkcsspathnodeprivate.h +++ b/gtk/gtkcsspathnodeprivate.h @@ -50,6 +50,8 @@ GType gtk_css_path_node_get_type (void) G_GNUC_CONST; GtkCssNode * gtk_css_path_node_new (GtkStyleContext *context); +void gtk_css_path_node_unset_context (GtkCssPathNode *node); + void gtk_css_path_node_set_widget_path (GtkCssPathNode *node, GtkWidgetPath *path); GtkWidgetPath * gtk_css_path_node_get_widget_path (GtkCssPathNode *node); diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c index bbf629a39c..3786e356d5 100644 --- a/gtk/gtkstylecontext.c +++ b/gtk/gtkstylecontext.c @@ -365,12 +365,15 @@ gtk_style_context_finalize (GObject *object) style_context = GTK_STYLE_CONTEXT (object); priv = style_context->priv; + while (priv->saved_nodes) + gtk_style_context_pop_style_node (style_context); + if (GTK_IS_CSS_PATH_NODE (priv->cssnode)) + gtk_css_path_node_unset_context (GTK_CSS_PATH_NODE (priv->cssnode)); + gtk_style_context_clear_parent (style_context); gtk_style_context_set_cascade (style_context, NULL); - while (priv->saved_nodes) - gtk_style_context_pop_style_node (style_context); g_object_unref (priv->cssnode); gtk_style_context_clear_property_cache (style_context); diff --git a/testsuite/gtk/stylecontext.c b/testsuite/gtk/stylecontext.c index fcbc0a1612..4d6438cb33 100644 --- a/testsuite/gtk/stylecontext.c +++ b/testsuite/gtk/stylecontext.c @@ -352,6 +352,20 @@ test_set_widget_path_saved (void) g_object_unref (context); } +void +test_widget_path_parent (void) +{ + GtkStyleContext *parent, *context; + + parent = gtk_style_context_new (); + context = gtk_style_context_new (); + + gtk_style_context_set_parent (context, parent); + + g_object_unref (parent); + g_object_unref (context); +} + int main (int argc, char *argv[]) { @@ -364,6 +378,7 @@ main (int argc, char *argv[]) g_test_add_func ("/style/basic", test_basic_properties); g_test_add_func ("/style/invalidate-saved", test_invalidate_saved); g_test_add_func ("/style/set-widget-path-saved", test_set_widget_path_saved); + g_test_add_func ("/style/widget-path-parent", test_widget_path_parent); return g_test_run (); }