[gnome-shell/wip/carlosg/stylesheet-updates] st: Track stylesheet changes on the StThemeContext



commit f83957da017e595dac76e13d032d34e433f1f1f8
Author: Carlos Garnacho <carlosg gnome org>
Date:   Thu Oct 24 14:03:12 2019 +0200

    st: Track stylesheet changes on the StThemeContext
    
    Instead of every individual StThemeNode. There are essentially two kinds
    of theme nodes: Those we create for lookups, and those interned by the
    theme context and used by StWidgets. Listening to the signal on the former
    is pointless as they are short lived and not meant to be really used for
    drawing. So it is only essential to track stylesheet changes in those we
    intern for later use.
    
    This change does precisely that, it lets the StThemeContext track the
    stylesheet changes and let all known theme nodes reset their state for
    it.
    
    The internal array holding all connected handlers for this signal in glib
    was about the biggest single allocation made in gnome-shell, as interned
    theme nodes nodes are around the 4 to 5 digit numbers. This essentially
    makes it disappear.
    
    This however means that widgets that are explicitly set a theme through
    st_widget_set_theme() don't get their theme node implicitly updated.
    There's little reasons to use that API, so perhaps this is an acceptable
    tradeoff.

 src/st/st-theme-context.c      | 40 ++++++++++++++++++++++++++++++++++++----
 src/st/st-theme-node-private.h |  1 +
 src/st/st-theme-node.c         | 22 +++-------------------
 3 files changed, 40 insertions(+), 23 deletions(-)
---
diff --git a/src/st/st-theme-context.c b/src/st/st-theme-context.c
index 1087dfe7d7..2b12d20abb 100644
--- a/src/st/st-theme-context.c
+++ b/src/st/st-theme-context.c
@@ -25,6 +25,7 @@
 #include "st-texture-cache.h"
 #include "st-theme.h"
 #include "st-theme-context.h"
+#include "st-theme-node-private.h"
 
 struct _StThemeContext {
   GObject parent;
@@ -36,6 +37,8 @@ struct _StThemeContext {
   /* set of StThemeNode */
   GHashTable *nodes;
 
+  guint stylesheets_changed_id;
+
   int scale_factor;
 };
 
@@ -83,6 +86,13 @@ st_theme_context_finalize (GObject *object)
                                         (gpointer) st_theme_context_changed,
                                         context);
 
+  if (context->stylesheets_changed_id)
+    {
+      g_signal_handler_disconnect (context->theme,
+                                   context->stylesheets_changed_id);
+      context->stylesheets_changed_id = 0;
+    }
+
   if (context->nodes)
     g_hash_table_unref (context->nodes);
   if (context->root_node)
@@ -254,6 +264,19 @@ on_icon_theme_changed (StTextureCache *cache,
   g_source_set_name_by_id (id, "[gnome-shell] changed_idle");
 }
 
+static void
+on_custom_stylesheets_changed (StTheme        *theme,
+                               StThemeContext *context)
+{
+  GHashTableIter iter;
+  StThemeNode *node;
+
+  g_hash_table_iter_init (&iter, context->nodes);
+
+  while (g_hash_table_iter_next (&iter, (gpointer *) &node, NULL))
+    _st_theme_node_reset_for_stylesheet_change (node);
+}
+
 /**
  * st_theme_context_get_for_stage:
  * @stage: a #ClutterStage
@@ -298,13 +321,22 @@ st_theme_context_set_theme (StThemeContext          *context,
 
   if (context->theme != theme)
     {
-      if (context->theme)
-        g_object_unref (context->theme);
+      if (context->stylesheets_changed_id)
+        {
+          g_signal_handler_disconnect (context->theme,
+                                       context->stylesheets_changed_id);
+          context->stylesheets_changed_id = 0;
+        }
 
-      context->theme = theme;
+      g_set_object (&context->theme, theme);
 
       if (context->theme)
-        g_object_ref (context->theme);
+        {
+          context->stylesheets_changed_id =
+            g_signal_connect (context->theme, "custom-stylesheets-changed",
+                              G_CALLBACK (on_custom_stylesheets_changed),
+                              context);
+        }
 
       st_theme_context_changed (context);
     }
diff --git a/src/st/st-theme-node-private.h b/src/st/st-theme-node-private.h
index 47be65dba8..578a06e72b 100644
--- a/src/st/st-theme-node-private.h
+++ b/src/st/st-theme-node-private.h
@@ -123,6 +123,7 @@ void _st_theme_node_ensure_background (StThemeNode *node);
 void _st_theme_node_ensure_geometry (StThemeNode *node);
 void _st_theme_node_apply_margins (StThemeNode *node,
                                    ClutterActor *actor);
+void _st_theme_node_reset_for_stylesheet_change (StThemeNode *node);
 
 G_END_DECLS
 
diff --git a/src/st/st-theme-node.c b/src/st/st-theme-node.c
index 1261e92573..2454fd0aa4 100644
--- a/src/st/st-theme-node.c
+++ b/src/st/st-theme-node.c
@@ -77,16 +77,13 @@ maybe_free_properties (StThemeNode *node)
     }
 }
 
-static void
-on_custom_stylesheets_changed (StTheme *theme,
-                               gpointer data)
+void
+_st_theme_node_reset_for_stylesheet_change (StThemeNode *node)
 {
-  StThemeNode *node = data;
   maybe_free_properties (node);
   node->properties_computed = FALSE;
 }
 
-
 static void
 st_theme_node_dispose (GObject *gobject)
 {
@@ -110,12 +107,6 @@ st_theme_node_dispose (GObject *gobject)
       node->icon_colors = NULL;
     }
 
-  if (node->theme && node->stylesheets_changed_id)
-    {
-      g_signal_handler_disconnect (node->theme, node->stylesheets_changed_id);
-      node->stylesheets_changed_id = 0;
-    }
-
   st_theme_node_paint_state_free (&node->cached_state);
 
   g_clear_object (&node->theme);
@@ -228,14 +219,7 @@ st_theme_node_new (StThemeContext    *context,
   if (theme == NULL && parent_node != NULL)
     theme = parent_node->theme;
 
-  if (theme != NULL)
-    {
-      node->theme = g_object_ref (theme);
-      node->stylesheets_changed_id =
-        g_signal_connect (node->theme, "custom-stylesheets-changed",
-                          G_CALLBACK (on_custom_stylesheets_changed), node);
-    }
-
+  g_set_object (&node->theme, theme);
   node->element_type = element_type;
   node->element_id = g_strdup (element_id);
   node->element_classes = split_on_whitespace (element_class);


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