summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-10-17 18:52:51 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-10-17 18:52:51 (GMT)
commit30411ff58e8c495953d09b5b796ce129056c20fb (patch)
tree9f2a723d903b2d881dbe18730f74dbb24500a93e /src
parentab45be33f699d458fe8cabf85b4c6c4f41f24fdd (diff)
Written a better version of CSS definitions loading.
Diffstat (limited to 'src')
-rw-r--r--src/gui/core/theme.c205
1 files changed, 141 insertions, 64 deletions
diff --git a/src/gui/core/theme.c b/src/gui/core/theme.c
index 4b097d0..be060be 100644
--- a/src/gui/core/theme.c
+++ b/src/gui/core/theme.c
@@ -25,13 +25,14 @@
#include "theme.h"
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <assert.h>
#include <dirent.h>
#include <fcntl.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
#include <config.h>
@@ -46,10 +47,16 @@
/* Parcourt tous les répertoires connus pour trouver un thème. */
-static bool browse_themes_directories(GdkScreen *, const char *, gboolean);
+static char *browse_themes_directories(const char *, gboolean);
/* Parcourt un répertoire donné à la recherche d'un thème. */
-static bool look_for_named_theme(GdkScreen *, const char *, const char *, gboolean);
+static char *look_for_named_theme(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);
+
+/* Etend le thème courant de GTK. */
+static void activate_css_content(GdkScreen *, const char *);
/* Répertoires de recherche */
@@ -82,6 +89,7 @@ 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;
@@ -94,11 +102,16 @@ bool load_extra_gtk_theme(void)
g_object_get(settings, "gtk-application-prefer-dark-theme", &dark, NULL);
- if (dark)
- result = browse_themes_directories(screen, name, true);
+ content = browse_themes_directories(name, dark);
- if (!result)
- result = browse_themes_directories(screen, name, false);
+ if (content != NULL)
+ {
+ activate_css_content(screen, content);
+ free(content);
+
+ result = true;
+
+ }
legt_done:
@@ -109,26 +122,25 @@ bool load_extra_gtk_theme(void)
/******************************************************************************
* *
-* Paramètres : screen = écran concerné par les éventuels chargements. *
-* name = nom du thème recherché, et donc de son répertoire. *
+* 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. *
* *
* Description : Parcourt tous les répertoires connus pour trouver un thème. *
* *
-* Retour : true si un élément de thème a pu être chargé, false sinon. *
+* Retour : Contenu CSS chargé ou NULL si aucun. *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool browse_themes_directories(GdkScreen *screen, const char *name, gboolean dark)
+static char *browse_themes_directories(const char *name, gboolean dark)
{
- bool result; /* Bilan à faire remonter */
+ char *result; /* Défintions CSS à renvoyer */
char *suffix; /* Fin du répertoire personnel */
char *owndir; /* Thèmes personnels ? */
const char **iter; /* Boucle de parcours */
- result = false;
+ result = NULL;
/* Répertoire de l'utilisateur en premier ! */
@@ -142,7 +154,7 @@ static bool browse_themes_directories(GdkScreen *screen, const char *name, gbool
if (owndir != NULL)
{
- result = look_for_named_theme(screen, owndir, name, dark);
+ result = look_for_named_theme(owndir, name, dark);
free(owndir);
@@ -150,8 +162,8 @@ static bool browse_themes_directories(GdkScreen *screen, const char *name, gbool
/* Parcours des autres répertoires classiques au besoin */
- for (iter = _themes_directories; *iter != NULL && !result; iter++)
- result = look_for_named_theme(screen, *iter, name, dark);
+ for (iter = _themes_directories; *iter != NULL && result == NULL; iter++)
+ result = look_for_named_theme(*iter, name, dark);
return result;
@@ -160,35 +172,30 @@ static bool browse_themes_directories(GdkScreen *screen, const char *name, gbool
/******************************************************************************
* *
-* Paramètres : screen = écran concerné par les éventuels chargements. *
-* dirname = chemin du répertoire où effectuer des recherches. *
+* Paramètres : 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 : true si un élément de thème a pu être chargé, false sinon. *
+* Retour : Contenu CSS chargé ou NULL si aucun. *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool look_for_named_theme(GdkScreen *screen, const char *dirname, const char *name, gboolean dark)
+static char *look_for_named_theme(const char *dirname, const char *name, gboolean dark)
{
- bool result; /* Bilan à faire remonter */
+ char *result; /* Défintions CSS à renvoyer */
char *path; /* Chemin d'accès à essayer */
int ret; /* Bilan d'un appel */
int dirfd; /* Canal de lecture */
struct dirent **namelist; /* Liste des trouvailles */
- char *css_content; /* Contenu de style cumulé */
int count; /* Nombre de fichiers trouvés */
int i; /* Boucle de parcours */
char *filename; /* Chemin d'accès constitué */
- GtkCssProvider *provider; /* Nouveau fournisseur CSS */
- GError *error; /* Relevé d'éventuelles erreurs*/
- char *content; /* Contenu d'une feuille */
- result = false;
+ result = NULL;
ret = asprintf(&path, "%s" G_DIR_SEPARATOR_S "%s", dirname, name);
if (ret == -1) goto lfnt_done;
@@ -196,13 +203,6 @@ static bool look_for_named_theme(GdkScreen *screen, const char *dirname, const c
dirfd = open(path, O_RDONLY | O_DIRECTORY);
if (dirfd == -1) goto lfnt_not_found;
- int keep_dark_css_only(const struct dirent *entry)
- {
- return (entry->d_type == DT_REG
- && endswith(entry->d_name, "-dark.css") ? 1 : 0);
-
- }
-
int keep_css_only(const struct dirent *entry)
{
return (entry->d_type == DT_REG
@@ -211,83 +211,160 @@ static bool look_for_named_theme(GdkScreen *screen, const char *dirname, const c
}
- css_content = NULL;
-
- count = scandirat(dirfd, ".", &namelist, dark ? keep_dark_css_only : keep_css_only, alphasort);
+ count = scandirat(dirfd, ".", &namelist, keep_css_only, alphasort);
for (i = 0; i < count; 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);
+
+ free(filename);
+
+ }
+
+ if (count > 0)
+ free(namelist);
+
+ close(dirfd);
+
+ lfnt_not_found:
+
+ free(path);
+
+ lfnt_done:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* 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. *
+* *
+* Description : Ajoute les définitions CSS à partir d'un chemin donné. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void load_css_partial_content(char **content, const char *path, gboolean dark)
+{
+ bool got_it; /* Version sombre présente ? */
+ char *dark_path; /* Version sombre du chemin */
+ GtkCssProvider *provider; /* Nouveau fournisseur CSS */
+ GError *error; /* Relevé d'éventuelles erreurs*/
+ char *extra; /* Contenu d'une feuille */
+
+ got_it = false;
+
+ if (dark)
+ {
+ dark_path = strdup(path);
+ dark_path = strrpl(dark_path, ".css", "-dark.css");
+
provider = gtk_css_provider_new();
error = NULL;
- gtk_css_provider_load_from_path(provider, filename, &error);
+ gtk_css_provider_load_from_path(provider, dark_path, &error);
if (error == NULL)
{
- log_variadic_message(LMT_INFO, _("Loaded CSS definitions from '%s'"), filename);
+ log_variadic_message(LMT_INFO, _("Loaded CSS definitions from '%s'"), dark_path);
+
+ extra = gtk_css_provider_to_string(provider);
- content = gtk_css_provider_to_string(provider);
+ *content = stradd(*content, extra);
- css_content = stradd(css_content, content);
+ free(extra);
- free(content);
+ got_it = true;
}
else
- {
- log_variadic_message(LMT_ERROR, _("Failed to load CSS definitions from '%s'"), filename);
g_error_free(error);
- }
g_object_unref(G_OBJECT(provider));
- free(filename);
-
}
- if (count > 0)
- free(namelist);
-
- close(dirfd);
-
- if (css_content != NULL)
+ if (!got_it)
{
provider = gtk_css_provider_new();
error = NULL;
- gtk_css_provider_load_from_data(provider, css_content, -1, &error);
+ gtk_css_provider_load_from_path(provider, path, &error);
if (error == NULL)
{
- gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(provider),
- GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+ log_variadic_message(LMT_INFO, _("Loaded CSS definitions from '%s'"), path);
+
+ extra = gtk_css_provider_to_string(provider);
+
+ *content = stradd(*content, extra);
- result = true;
+ free(extra);
}
else
{
- log_variadic_message(LMT_ERROR, _("Failed to load CSS definitions"));
+ log_variadic_message(LMT_ERROR, _("Failed to load CSS definitions from '%s'"), path);
g_error_free(error);
}
- free(css_content);
-
g_object_unref(G_OBJECT(provider));
}
- lfnt_not_found:
+}
- free(path);
- lfnt_done:
+/******************************************************************************
+* *
+* Paramètres : screen = écran concerné par les éventuels chargements. *
+* content = contenu CSS reconstitué à charger. *
+* *
+* Description : Etend le thème courant de GTK. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- return result;
+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));
}