From 3a8bc79d69acae3735cc0203b54d93b4137caa09 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Mon, 21 Jan 2019 23:19:01 +0100 Subject: Improved code as GTK failed to load CSS content it has exported. --- src/gui/core/theme.c | 175 +++++++++++++++++++-------------------------------- 1 file changed, 65 insertions(+), 110 deletions(-) diff --git a/src/gui/core/theme.c b/src/gui/core/theme.c index 420fb79..8e68780 100644 --- a/src/gui/core/theme.c +++ b/src/gui/core/theme.c @@ -48,19 +48,16 @@ /* Parcourt tous les répertoires connus pour trouver un thème. */ -static char *browse_themes_directories(const char *, gboolean); +static bool browse_themes_directories(GdkScreen *, const char *, gboolean); /* Parcourt un répertoire donné à la recherche d'un thème. */ -static char *look_for_named_theme(const char *, const char *, gboolean); +static bool look_for_named_theme(GdkScreen *, const char *, const char *, gboolean); /* Ajoute les définitions CSS à partir d'un chemin donné. */ -static void load_css_partial_content(char **, const char *, gboolean); +static bool load_css_content(GdkScreen *, const char *, gboolean); /* Parcourt tous les greffons à la recherche de définitions CSS. */ -static void prepend_plugins_themes(char **, gboolean); - -/* Etend le thème courant de GTK. */ -static void activate_css_content(GdkScreen *, const char *); +static bool extend_with_plugins_themes(GdkScreen *, gboolean); /* Répertoires de recherche */ @@ -93,7 +90,6 @@ bool load_extra_gtk_theme(void) GdkScreen *screen; /* Ecran(s) concerné(s) */ GtkSettings *settings; /* Propriétés du système */ gboolean dark; /* Envie d'un thème sombre ? */ - char *content; /* Définitions CSS à charger */ result = false; @@ -106,18 +102,10 @@ bool load_extra_gtk_theme(void) g_object_get(settings, "gtk-application-prefer-dark-theme", &dark, NULL); - content = browse_themes_directories(name, dark); - - if (content != NULL) - { - prepend_plugins_themes(&content, dark); - - activate_css_content(screen, content); - free(content); + result = browse_themes_directories(screen, name, dark); - result = true; - - } + if (result) + result = extend_with_plugins_themes(screen, dark); legt_done: @@ -128,25 +116,26 @@ bool load_extra_gtk_theme(void) /****************************************************************************** * * -* Paramètres : name = nom du thème recherché, et donc de son répertoire. * -* dark = indique une préférence pour la variante foncée. * +* Paramètres : screen = écran visé par le chargement d'un thème. * +* name = nom du thème recherché, et donc de son répertoire. * +* dark = indique une préférence pour la variante foncée. * * * * Description : Parcourt tous les répertoires connus pour trouver un thème. * * * -* Retour : Contenu CSS chargé ou NULL si aucun. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -static char *browse_themes_directories(const char *name, gboolean dark) +static bool browse_themes_directories(GdkScreen *screen, const char *name, gboolean dark) { - char *result; /* Défintions CSS à renvoyer */ + bool result; /* Bilan à renvoyer */ char *suffix; /* Fin du répertoire personnel */ char *owndir; /* Thèmes personnels ? */ const char **iter; /* Boucle de parcours */ - result = NULL; + result = false; /* Répertoire de l'utilisateur en premier ! */ @@ -160,7 +149,7 @@ static char *browse_themes_directories(const char *name, gboolean dark) if (owndir != NULL) { - result = look_for_named_theme(owndir, name, dark); + result = look_for_named_theme(screen, owndir, name, dark); free(owndir); @@ -168,8 +157,8 @@ static char *browse_themes_directories(const char *name, gboolean dark) /* Parcours des autres répertoires classiques au besoin */ - for (iter = _themes_directories; *iter != NULL && result == NULL; iter++) - result = look_for_named_theme(*iter, name, dark); + for (iter = _themes_directories; *iter != NULL && !result; iter++) + result = look_for_named_theme(screen, *iter, name, dark); return result; @@ -178,21 +167,22 @@ static char *browse_themes_directories(const char *name, gboolean dark) /****************************************************************************** * * -* Paramètres : dirname = chemin du répertoire où effectuer des recherches. * +* Paramètres : screen = écran visé par le chargement d'un thème. * +* dirname = chemin du répertoire où effectuer des recherches. * * name = nom du thème recherché, et donc de son répertoire. * * dark = indique une préférence pour la variante foncée. * * * * Description : Parcourt un répertoire donné à la recherche d'un thème. * * * -* Retour : Contenu CSS chargé ou NULL si aucun. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -static char *look_for_named_theme(const char *dirname, const char *name, gboolean dark) +static bool look_for_named_theme(GdkScreen *screen, const char *dirname, const char *name, gboolean dark) { - char *result; /* Défintions CSS à renvoyer */ + bool result; /* Bilan à renvoyer */ char *path; /* Chemin d'accès à essayer */ int ret; /* Bilan d'un appel */ int dirfd; /* Canal de lecture */ @@ -201,7 +191,7 @@ static char *look_for_named_theme(const char *dirname, const char *name, gboolea int i; /* Boucle de parcours */ char *filename; /* Chemin d'accès constitué */ - result = NULL; + result = false; ret = asprintf(&path, "%s" G_DIR_SEPARATOR_S "%s", dirname, name); if (ret == -1) goto lfnt_done; @@ -219,12 +209,14 @@ static char *look_for_named_theme(const char *dirname, const char *name, gboolea count = scandirat(dirfd, ".", &namelist, keep_css_only, alphasort); - for (i = 0; i < count; i++) + result = (count > 0); + + for (i = 0; i < count && result; i++) { ret = asprintf(&filename, "%s%s%s", path, G_DIR_SEPARATOR_S, namelist[i]->d_name); if (ret == -1) continue; - load_css_partial_content(&result, filename, dark); + result = load_css_content(screen, filename, dark); free(filename); @@ -248,28 +240,40 @@ static char *look_for_named_theme(const char *dirname, const char *name, gboolea /****************************************************************************** * * -* Paramètres : content = définitions CSS à compléter. [OUT] * -* path = chemin vers la nouvelle définition à ajouter. * -* dark = indique une préférence pour la variante foncée. * +* Paramètres : screen = écran visé par le chargement d'un thème. * +* path = chemin vers la nouvelle définition à ajouter. * +* dark = indique une préférence pour la variante foncée. * * * * Description : Ajoute les définitions CSS à partir d'un chemin donné. * * * -* Retour : - * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -static void load_css_partial_content(char **content, const char *path, gboolean dark) +static bool load_css_content(GdkScreen *screen, const char *path, gboolean dark) { - bool got_it; /* Version sombre présente ? */ + bool result; /* Bilan à renvoyer */ GtkCssProvider *provider; /* Nouveau fournisseur CSS */ char *dark_path; /* Version sombre du chemin */ GFile *file; /* Fichier à charger */ GError *error; /* Relevé d'éventuelles erreurs*/ - char *css; /* Contenu d'une feuille */ - got_it = false; + result = false; + + /** + * Comme GTK exporte les images sous forme de données encodées en base 64 + * (cf. gtk_css_image_surface_print()) et ne sait pas recharger ensuite + * ces mêmes données (cf. gtk_css_image_url_load_image()), on ne peut pas + * collecter les images des ressources via gtk_css_provider_to_string() + * pour constituer un contenu CSS global... + * + * On intègre ainsi les contenus CSS un par un, sans pouvoir déterminer + * si l'ensemble est complètement intégré sans erreur. + * + * Ce constat est valable pour la version 3.22.11-1 de Debian, au moins. + */ if (dark) { @@ -293,13 +297,10 @@ static void load_css_partial_content(char **content, const char *path, gboolean { log_variadic_message(LMT_INFO, _("Loaded CSS definitions from '%s'"), dark_path); - css = gtk_css_provider_to_string(provider); + gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(provider), + GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); - *content = stradd(*content, css); - - free(css); - - got_it = true; + result = true; } else @@ -311,7 +312,7 @@ static void load_css_partial_content(char **content, const char *path, gboolean } - if (!got_it) + if (!result) { provider = gtk_css_provider_new(); @@ -330,11 +331,10 @@ static void load_css_partial_content(char **content, const char *path, gboolean { log_variadic_message(LMT_INFO, _("Loaded CSS definitions from '%s'"), path); - css = gtk_css_provider_to_string(provider); - - *content = stradd(*content, css); + gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(provider), + GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); - free(css); + result = true; } else @@ -347,92 +347,47 @@ static void load_css_partial_content(char **content, const char *path, gboolean } + return result; + } /****************************************************************************** * * -* Paramètres : content = définitions CSS à compléter. [OUT] * -* dark = indique une préférence pour la variante foncée. * +* Paramètres : screen = écran visé par le chargement d'un thème. * +* dark = indique une préférence pour la variante foncée. * * * * Description : Parcourt tous les greffons à la recherche de définitions CSS.* * * -* Retour : - * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -static void prepend_plugins_themes(char **content, gboolean dark) +static bool extend_with_plugins_themes(GdkScreen *screen, gboolean dark) { - char *extra; /* Nouvelles définitions CSS */ + bool result; /* Bilan à renvoyer */ char **resources; /* Fichiers supplémentaires */ size_t count; /* Nombre de ces fichiers */ size_t i; /* Boucle de parcours */ - extra = NULL; + result = true; resources = NULL; count = 0; include_plugin_theme(&resources, &count); - for (i = 0; i < count; i++) + for (i = 0; i < count && result; i++) { - load_css_partial_content(&extra, resources[i], dark); + result = load_css_content(screen, resources[i], dark); free(resources[i]); } if (resources != NULL) free(resources); - if (extra != NULL) - { - *content = strprep(*content, extra); - free(extra); - } - -} - - -/****************************************************************************** -* * -* Paramètres : screen = écran concerné par les éventuels chargements. * -* content = contenu CSS reconstitué à charger. * -* * -* Description : Etend le thème courant de GTK. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void activate_css_content(GdkScreen *screen, const char *content) -{ - GtkCssProvider *provider; /* Nouveau fournisseur CSS */ - GError *error; /* Relevé d'éventuelles erreurs*/ - - provider = gtk_css_provider_new(); - - error = NULL; - - gtk_css_provider_load_from_data(provider, content, -1, &error); - - if (error == NULL) - { - gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(provider), - GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); - } - else - { - assert(false); - - log_variadic_message(LMT_ERROR, _("Failed to load the global CSS extra definition")); - g_error_free(error); - - } - - g_object_unref(G_OBJECT(provider)); + return result; } -- cgit v0.11.2-87-g4458