[gnome-software] gs-common: Require a CSS class name for custom CSS



commit fed85f0595f28b12b298814fd8d38ffc50deac1e
Author: Philip Withnall <withnall endlessm com>
Date:   Wed Nov 13 11:25:20 2019 +0000

    gs-common: Require a CSS class name for custom CSS
    
    Rather than building one out of the pointer to the widget name, require
    a hard-coded one. CSS class names are interned into the global `GQuark`
    table by GTK, so constructing a different one for each widget means that
    table grows without bound. That is bad — all those strings are
    (deliberately) leaked, and every addition slows the quark table down a
    bit.
    
    In order to allow the same class name to be reused across multiple
    widgets without interfering, install the custom `GtkCssProvider` only on
    the given widget instance, rather than for the entire screen.
    
    Signed-off-by: Philip Withnall <withnall endlessm com>

 src/gs-common.c         | 23 ++++++++++++++++-------
 src/gs-common.h         |  1 +
 src/gs-details-page.c   |  2 +-
 src/gs-feature-tile.c   |  6 +++---
 src/gs-popular-tile.c   |  2 +-
 src/gs-summary-tile.c   |  2 +-
 src/gs-upgrade-banner.c |  2 +-
 7 files changed, 24 insertions(+), 14 deletions(-)
---
diff --git a/src/gs-common.c b/src/gs-common.c
index 703e8136..f2bd0e96 100644
--- a/src/gs-common.c
+++ b/src/gs-common.c
@@ -360,24 +360,33 @@ gs_utils_widget_set_css_internal (GtkWidget *widget,
        provider = gtk_css_provider_new ();
        g_signal_connect (provider, "parsing-error",
                          G_CALLBACK (gs_utils_widget_css_parsing_error_cb), NULL);
-       gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
-                                                  GTK_STYLE_PROVIDER (provider),
-                                                  GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
        gtk_css_provider_load_from_data (provider, css, -1, NULL);
        g_object_set_data_full (G_OBJECT (widget),
                                "GnomeSoftware::provider",
                                g_object_ref (provider),
                                g_object_unref);
+       gtk_style_context_add_provider (context, GTK_STYLE_PROVIDER (provider),
+                                       GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
 }
 
+/**
+ * gs_utils_widget_set_css:
+ * @widget: a widget
+ * @class_name: class name to use, without the leading `.`
+ * @css: (nullable): CSS to set on the widget, or %NULL to clear custom CSS
+ *
+ * Set custom CSS on the given @widget instance. This doesn’t affect any other
+ * instances of the same widget. The @class_name must be a static string to be
+ * used as a name for the @css. It doesn’t need to vary with @widget, but
+ * multiple values of @class_name can be used with the same @widget to control
+ * several independent snippets of custom CSS.
+ */
 void
-gs_utils_widget_set_css (GtkWidget *widget, const gchar *css)
+gs_utils_widget_set_css (GtkWidget *widget, const gchar *class_name, const gchar *css)
 {
-       g_autofree gchar *class_name = NULL;
        g_autoptr(GString) str = NULL;
 
-       /* remove custom class if NULL */
-       class_name = g_strdup_printf ("themed-widget_%p", widget);
+       /* remove custom class if NULL; we don’t currently bother to remove the custom #GtkCssProvider */
        if (css == NULL) {
                GtkStyleContext *context = gtk_widget_get_style_context (widget);
                gtk_style_context_remove_class (context, class_name);
diff --git a/src/gs-common.h b/src/gs-common.h
index 89e6db59..74b81a35 100644
--- a/src/gs-common.h
+++ b/src/gs-common.h
@@ -33,6 +33,7 @@ void  gs_image_set_from_pixbuf                (GtkImage               *image,
 
 gboolean        gs_utils_is_current_desktop    (const gchar    *name);
 void            gs_utils_widget_set_css        (GtkWidget      *widget,
+                                                const gchar    *class_name,
                                                 const gchar    *css);
 const gchar    *gs_utils_get_error_value       (const GError   *error);
 void            gs_utils_show_error_dialog     (GtkWindow      *parent,
diff --git a/src/gs-details-page.c b/src/gs-details-page.c
index 4bb02999..217e4fed 100644
--- a/src/gs-details-page.c
+++ b/src/gs-details-page.c
@@ -1680,7 +1680,7 @@ gs_details_page_content_rating_set_css (GtkWidget *widget, guint age)
        }
        g_string_append_printf (css, "color: %s;\n", color_fg);
        g_string_append_printf (css, "background-color: %s;\n", color_bg);
-       gs_utils_widget_set_css (widget, css->str);
+       gs_utils_widget_set_css (widget, "content-rating-custom", css->str);
 }
 
 static void
diff --git a/src/gs-feature-tile.c b/src/gs-feature-tile.c
index 27b6f19a..b932b1eb 100644
--- a/src/gs-feature-tile.c
+++ b/src/gs-feature-tile.c
@@ -49,11 +49,11 @@ gs_feature_tile_refresh (GsAppTile *self)
        css = gs_css_new ();
        if (markup != NULL)
                gs_css_parse (css, markup, NULL);
-       gs_utils_widget_set_css (GTK_WIDGET (tile),
+       gs_utils_widget_set_css (GTK_WIDGET (tile), "feature-tile",
                                 gs_css_get_markup_for_id (css, "tile"));
-       gs_utils_widget_set_css (tile->title,
+       gs_utils_widget_set_css (tile->title, "feature-tile-name",
                                 gs_css_get_markup_for_id (css, "name"));
-       gs_utils_widget_set_css (tile->subtitle,
+       gs_utils_widget_set_css (tile->subtitle, "feature-tile-subtitle",
                                 gs_css_get_markup_for_id (css, "summary"));
 
        accessible = gtk_widget_get_accessible (GTK_WIDGET (tile));
diff --git a/src/gs-popular-tile.c b/src/gs-popular-tile.c
index 0ad7c65e..46212662 100644
--- a/src/gs-popular-tile.c
+++ b/src/gs-popular-tile.c
@@ -78,7 +78,7 @@ gs_popular_tile_refresh (GsAppTile *self)
 
        /* perhaps set custom css */
        css = gs_app_get_metadata_item (app, "GnomeSoftware::PopularTile-css");
-       gs_utils_widget_set_css (GTK_WIDGET (tile), css);
+       gs_utils_widget_set_css (GTK_WIDGET (tile), "popular-tile", css);
 
        if (gs_app_get_pixbuf (app) != NULL) {
                gs_image_set_from_pixbuf (GTK_IMAGE (tile->image), gs_app_get_pixbuf (app));
diff --git a/src/gs-summary-tile.c b/src/gs-summary-tile.c
index 3fe57277..90e810c9 100644
--- a/src/gs-summary-tile.c
+++ b/src/gs-summary-tile.c
@@ -84,7 +84,7 @@ gs_summary_tile_refresh (GsAppTile *self)
 
        /* perhaps set custom css */
        css = gs_app_get_metadata_item (app, "GnomeSoftware::AppTile-css");
-       gs_utils_widget_set_css (GTK_WIDGET (tile), css);
+       gs_utils_widget_set_css (GTK_WIDGET (tile), "summary-tile", css);
 
        accessible = gtk_widget_get_accessible (GTK_WIDGET (tile));
 
diff --git a/src/gs-upgrade-banner.c b/src/gs-upgrade-banner.c
index e76ca33c..51b369f5 100644
--- a/src/gs-upgrade-banner.c
+++ b/src/gs-upgrade-banner.c
@@ -248,7 +248,7 @@ gs_upgrade_banner_set_app (GsUpgradeBanner *self, GsApp *app)
 
        /* perhaps set custom css */
        css = gs_app_get_metadata_item (app, "GnomeSoftware::UpgradeBanner-css");
-       gs_utils_widget_set_css (priv->box_upgrades, css);
+       gs_utils_widget_set_css (priv->box_upgrades, "upgrade-banner-custom", css);
 
        gs_upgrade_banner_refresh (self);
 }


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