From cc5a41d0ff116c28e6fda7bcd477e4e3a9c5d6b9 Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Thu, 28 Mar 2024 14:58:54 +0800 Subject: [PATCH] st/theme-node: Forget properties cache on stylesheet change To avoid `node->properties` pointing to freed memory after each `st_theme_unload_stylesheet`, flush the cache that is `node->properties`. They will be reloaded as soon as they are required by `ensure_properties`. And yes `node->stylesheets_changed_id` already existed, but was unused. Why not just fix Croco? Croco does not use proper reference counting everywhere it should, and retrofitting it would be difficult due to the recursive nature of `CRDeclaration`. Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/7339 ... but mostly reported in https://github.com/micheleg/dash-to-dock/issues/2179 and its duplicates. --- src/st/st-theme-node-private.h | 2 +- src/st/st-theme-node.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/st/st-theme-node-private.h b/src/st/st-theme-node-private.h index 02eb95e52..b8028925e 100644 --- a/src/st/st-theme-node-private.h +++ b/src/st/st-theme-node-private.h @@ -105,7 +105,7 @@ struct _StThemeNode { int box_shadow_min_width; int box_shadow_min_height; - guint stylesheets_changed_id; + gulong stylesheets_changed_id; CoglTexture *border_slices_texture; CoglPipeline *border_slices_pipeline; diff --git a/src/st/st-theme-node.c b/src/st/st-theme-node.c index b471ad72b..31b27583c 100644 --- a/src/st/st-theme-node.c +++ b/src/st/st-theme-node.c @@ -75,6 +75,10 @@ maybe_free_properties (StThemeNode *node) cr_declaration_destroy (node->inline_properties); node->inline_properties = NULL; } + + g_clear_signal_handler (&node->stylesheets_changed_id, node->theme); + + node->properties_computed = FALSE; } static void @@ -472,6 +476,16 @@ ensure_properties (StThemeNode *node) node->n_properties = properties->len; node->properties = (CRDeclaration **)g_ptr_array_free (properties, FALSE); } + + if (!node->stylesheets_changed_id) + { + node->stylesheets_changed_id = + g_signal_connect_object (node->theme, + "custom-stylesheets-changed", + G_CALLBACK (maybe_free_properties), + G_OBJECT (node), + G_CONNECT_SWAPPED); + } } }