summaryrefslogtreecommitdiff
path: root/src/gui/core/theme.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2019-01-21 22:19:01 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2019-01-21 22:19:01 (GMT)
commit3a8bc79d69acae3735cc0203b54d93b4137caa09 (patch)
tree1ed050771f3146728f757b4dda350f612407f332 /src/gui/core/theme.c
parentcbf3d6a202489a0a8d2ce4fe8aef31e78bbc653f (diff)
Improved code as GTK failed to load CSS content it has exported.
Diffstat (limited to 'src/gui/core/theme.c')
-rw-r--r--src/gui/core/theme.c175
1 files 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;
}