From 232290aad4be81cd67a309e5f28f867ad69a3fd4 Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Fri, 15 Mar 2013 15:54:00 +0100 Subject: [PATCH] Fix our custom styles under KDE and for people using gtk-chtheme We have a custom RC file defining various styles we need, and we want the user to be able to override them (e.g. if they want -- or need -- other colors). Fair enough, one would simply call gtk_rc_parse() with the appropriate filename. However, the styling rules applies in the order they are loaded, then if we load our styles after GTK has loaded the user's ones we'd override them. There are 2 solutions to fix this: 1) set our styles' priority to something with lower than "user" (actually "theme" priority because rules precedence are first calculated depending on the priority no matter of how precise the rules is, so we need to override the theme). 2) prepend our custom style to GTK's list while keeping priority to user (which is the default), so it gets loaded before real user's ones and so gets overridden by them. One would normally go for 1 because it's ways simpler and requires less code: you just have to add the priorities to your styles, which is a matter of adding a few ":theme" in the RC file. However, KDE being a bitch it doesn't set the gtk-theme-name but rather directly includes the style to use in a user gtkrc file, which makes the theme have "user" priority, hence overriding our styles. So, we cannot set priorities in the RC file if we want to support running under KDE, which pretty much leave us with no choice but to go with solution 2, which unfortunately requires writing ugly code since GTK don't have a gtk_rc_prepend_default_file() function. Thank you very much KDE. Though, as a side benefit it also makes the code work with people using gtk-chtheme, which also found it funny to include the theme in the user RC file. --- data/geany.gtkrc | 14 +++++++------- src/main.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ src/ui_utils.c | 5 +---- 3 files changed, 57 insertions(+), 11 deletions(-) diff --git a/data/geany.gtkrc b/data/geany.gtkrc index 90339d6d4..159d7b491 100644 --- a/data/geany.gtkrc +++ b/data/geany.gtkrc @@ -7,21 +7,21 @@ style "geany-close-tab-button-style" { xthickness = 0 ythickness = 0 } -widget "*.geany-close-tab-button" style:theme "geany-close-tab-button-style" +widget "*.geany-close-tab-button" style "geany-close-tab-button-style" # use monospaced font in search entries for easier reading of regexp (#1907117) style "geany-monospace" { font_name = "Monospace" } -widget "GeanyDialogSearch.*.GtkEntry" style:theme "geany-monospace" -widget "GeanyDialogSearch.*.geany-search-entry-no-match" style:theme "geany-monospace" +widget "GeanyDialogSearch.*.GtkEntry" style "geany-monospace" +widget "GeanyDialogSearch.*.geany-search-entry-no-match" style "geany-monospace" # set red background for GtkEntries showing unmatched searches style "geany-search-entry-no-match-style" { base[NORMAL] = "#ffff66666666" text[NORMAL] = "#ffffffffffff" } -widget "*.geany-search-entry-no-match" style:theme "geany-search-entry-no-match-style" +widget "*.geany-search-entry-no-match" style "geany-search-entry-no-match-style" # document status colors style "geany-document-status-changed-style" { @@ -36,6 +36,6 @@ style "geany-document-status-readonly-style" { fg[NORMAL] = "#00007fff0000" fg[ACTIVE] = "#00007fff0000" } -widget "*.geany-document-status-changed" style:theme "geany-document-status-changed-style" -widget "*.geany-document-status-disk-changed" style:theme "geany-document-status-disk-changed-style" -widget "*.geany-document-status-readonly" style:theme "geany-document-status-readonly-style" +widget "*.geany-document-status-changed" style "geany-document-status-changed-style" +widget "*.geany-document-status-disk-changed" style "geany-document-status-disk-changed-style" +widget "*.geany-document-status-readonly" style "geany-document-status-readonly-style" diff --git a/src/main.c b/src/main.c index 88dad1e99..e7867c6a8 100644 --- a/src/main.c +++ b/src/main.c @@ -969,6 +969,52 @@ static const gchar *get_locale(void) } +#if ! GTK_CHECK_VERSION(3, 0, 0) +/* This prepends our own gtkrc file to the list of RC files to be loaded by GTK at startup. + * This function *has* to be called before gtk_init(). + * + * We have a custom RC file defining various styles we need, and we want the user to be + * able to override them (e.g. if they want -- or need -- other colors). Fair enough, one + * would simply call gtk_rc_parse() with the appropriate filename. However, the styling + * rules applies in the order they are loaded, then if we load our styles after GTK has + * loaded the user's ones we'd override them. + * + * There are 2 solutions to fix this: + * 1) set our styles' priority to something with lower than "user" (actually "theme" + * priority because rules precedence are first calculated depending on the priority + * no matter of how precise the rules is, so we need to override the theme). + * 2) prepend our custom style to GTK's list while keeping priority to user (which is the + * default), so it gets loaded before real user's ones and so gets overridden by them. + * + * One would normally go for 1 because it's ways simpler and requires less code: you just + * have to add the priorities to your styles, which is a matter of adding a few ":theme" in + * the RC file. However, KDE being a bitch it doesn't set the gtk-theme-name but rather + * directly includes the style to use in a user gtkrc file, which makes the theme have + * "user" priority, hence overriding our styles. So, we cannot set priorities in the RC + * file if we want to support running under KDE, which pretty much leave us with no choice + * but to go with solution 2, which unfortunately requires writing ugly code since GTK + * don't have a gtk_rc_prepend_default_file() function. Thank you very much KDE. + * + * Though, as a side benefit it also makes the code work with people using gtk-chtheme, + * which also found it funny to include the theme in the user RC file. */ +static void setup_gtk2_styles(void) +{ + gchar **gtk_files = gtk_rc_get_default_files(); + gchar **new_files = g_malloc(sizeof *new_files * (g_strv_length(gtk_files) + 2)); + guint i = 0; + + new_files[i++] = g_build_filename(app->datadir, "geany.gtkrc", NULL); + for (; *gtk_files; gtk_files++) + new_files[i++] = g_strdup(*gtk_files); + new_files[i] = NULL; + + gtk_rc_set_default_files(new_files); + + g_strfreev(new_files); +} +#endif + + gint main(gint argc, gchar **argv) { GeanyDocument *doc; @@ -990,6 +1036,9 @@ gint main(gint argc, gchar **argv) memset(&ui_widgets, 0, sizeof(UIWidgets)); setup_paths(); +#if ! GTK_CHECK_VERSION(3, 0, 0) + setup_gtk2_styles(); +#endif #ifdef ENABLE_NLS main_locale_init(GEANY_LOCALEDIR, GETTEXT_PACKAGE); #endif diff --git a/src/ui_utils.c b/src/ui_utils.c index f49aeab49..b5e19973c 100644 --- a/src/ui_utils.c +++ b/src/ui_utils.c @@ -2180,10 +2180,7 @@ static void init_custom_style(void) g_object_unref(css); g_free(css_file); #else - gchar *gtkrc_file = g_build_filename(app->datadir, "geany.gtkrc", NULL); - - gtk_rc_parse(gtkrc_file); - g_free(gtkrc_file); + /* see setup_gtk2_styles() in main.c */ #endif } -- 2.11.4.GIT