GtkWidget *dialog;
+ if (g_str_equal (name, "DarkTheme"))
+ {
+ gboolean value = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+ GtkSettings *settings = gtk_settings_get_default ();
+
+ g_object_set (G_OBJECT (settings),
+ "gtk-application-prefer-dark-theme", value,
+ NULL);
+ return;
+ }
dialog = gtk_message_dialog_new (GTK_WINDOW (window),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO,
"Bold", /* tooltip */
G_CALLBACK (activate_action),
TRUE }, /* is_active */
+ { "DarkTheme", NULL, /* name, stock id */
+ "_Prefer Dark Theme", NULL, /* label, accelerator */
+ "Prefer Dark Theme", /* tooltip */
+ G_CALLBACK (activate_action),
+ FALSE }, /* is_active */
};
static guint n_toggle_entries = G_N_ELEMENTS (toggle_entries);
" <menuitem action='Quit'/>"
" </menu>"
" <menu action='PreferencesMenu'>"
+" <menuitem action='DarkTheme'/>"
" <menu action='ColorMenu'>"
" <menuitem action='Red'/>"
" <menuitem action='Green'/>"
/* The files we have parsed, to reread later if necessary */
GSList *rc_files;
- gchar *theme_name;
- gchar *key_theme_name;
- gchar *font_name;
+ gchar *theme_name;
+ gboolean prefer_dark_theme;
+ gchar *key_theme_name;
+ gchar *font_name;
gchar **pixmap_path;
static GtkStyle* gtk_rc_init_style (GtkRcContext *context,
GSList *rc_styles);
static void gtk_rc_parse_default_files (GtkRcContext *context);
-static void gtk_rc_parse_named (GtkRcContext *context,
+static gboolean gtk_rc_parse_named (GtkRcContext *context,
const gchar *name,
- const gchar *type);
+ const gchar *type,
+ const gchar *variant);
static void gtk_rc_context_parse_file (GtkRcContext *context,
const gchar *filename,
gint priority,
{
gchar *new_theme_name;
gchar *new_key_theme_name;
+ gboolean new_prefer_dark_theme;
if (context->reloading)
return;
g_object_get (settings,
"gtk-theme-name", &new_theme_name,
"gtk-key-theme-name", &new_key_theme_name,
+ "gtk-application-prefer-dark-theme", &new_prefer_dark_theme,
NULL);
if ((new_theme_name != context->theme_name &&
!(new_theme_name && context->theme_name && strcmp (new_theme_name, context->theme_name) == 0)) ||
(new_key_theme_name != context->key_theme_name &&
- !(new_key_theme_name && context->key_theme_name && strcmp (new_key_theme_name, context->key_theme_name) == 0)))
+ !(new_key_theme_name && context->key_theme_name && strcmp (new_key_theme_name, context->key_theme_name) == 0)) ||
+ new_prefer_dark_theme != context->prefer_dark_theme)
{
gtk_rc_reparse_all_for_settings (settings, TRUE);
}
"gtk-key-theme-name", &context->key_theme_name,
"gtk-font-name", &context->font_name,
"color-hash", &context->color_hash,
+ "gtk-application-prefer-dark-theme", &context->prefer_dark_theme,
NULL);
g_signal_connect (settings,
"notify::color-hash",
G_CALLBACK (gtk_rc_color_hash_changed),
context);
+ g_signal_connect (settings,
+ "notify::gtk-application-prefer-dark-theme",
+ G_CALLBACK (gtk_rc_settings_changed),
+ context);
context->pixmap_path = NULL;
settings->rc_context = NULL;
}
-static void
+static gboolean
gtk_rc_parse_named (GtkRcContext *context,
const gchar *name,
- const gchar *type)
+ const gchar *type,
+ const gchar *variant)
{
gchar *path = NULL;
const gchar *home_dir;
gchar *subpath;
+ gboolean retval;
+
+ retval = FALSE;
if (type)
subpath = g_strconcat ("gtk-3.0-", type,
G_DIR_SEPARATOR_S "gtkrc",
NULL);
else
- subpath = g_strdup ("gtk-3.0" G_DIR_SEPARATOR_S "gtkrc");
-
+ subpath = g_strconcat ("gtk-3.0" G_DIR_SEPARATOR_S "gtkrc",
+ variant, NULL);
+
/* First look in the users home directory
*/
home_dir = g_get_home_dir ();
{
gtk_rc_context_parse_file (context, path, GTK_PATH_PRIO_THEME, FALSE);
g_free (path);
+ retval = TRUE;
}
g_free (subpath);
+
+ return retval;
}
static void
g_object_get (context->settings,
"gtk-theme-name", &context->theme_name,
"gtk-key-theme-name", &context->key_theme_name,
+ "gtk-application-prefer-dark-theme", &context->prefer_dark_theme,
NULL);
if (context->theme_name && context->theme_name[0])
- gtk_rc_parse_named (context, context->theme_name, NULL);
+ {
+ if (context->prefer_dark_theme)
+ {
+ if (!gtk_rc_parse_named (context, context->theme_name, NULL, "-dark"))
+ gtk_rc_parse_named (context, context->theme_name, NULL, NULL);
+ }
+ else
+ {
+ gtk_rc_parse_named (context, context->theme_name, NULL, NULL);
+ }
+ }
if (context->key_theme_name && context->key_theme_name[0])
- gtk_rc_parse_named (context, context->key_theme_name, "key");
+ gtk_rc_parse_named (context, context->key_theme_name, "key", NULL);
context->reloading = FALSE;
PROP_ENABLE_TOOLTIPS,
PROP_TOOLBAR_STYLE,
PROP_TOOLBAR_ICON_SIZE,
- PROP_AUTO_MNEMONICS
+ PROP_AUTO_MNEMONICS,
+ PROP_APPLICATION_PREFER_DARK_THEME
};
GTK_PARAM_READWRITE),
NULL);
g_assert (result == PROP_AUTO_MNEMONICS);
+
+ /**
+ * GtkSettings:gtk-application-prefer-dark-theme:
+ *
+ * Whether the application prefers to use a dark theme. If a GTK+ theme
+ * includes a dark variant, it will be used instead of the configured
+ * theme.
+ *
+ * Some applications benefit from minimizing the amount of light pollution that
+ * interferes with the content. Good candidates for dark themes are photo and
+ * video editors that make the actual content get all the attention and minimize
+ * the distraction of the chrome.
+ *
+ * Dark themes should not be used for documents, where large spaces are white/light
+ * and the dark chrome creates too much contrast (web browser, text editor...).
+ *
+ * Since: 2.22
+ */
+ result = settings_install_property_parser (class,
+ g_param_spec_boolean ("gtk-application-prefer-dark-theme",
+ P_("Application prefers a dark theme"),
+ P_("Whether the application prefers to have a dark theme."),
+ FALSE,
+ GTK_PARAM_READWRITE),
+ NULL);
+ g_assert (result == PROP_APPLICATION_PREFER_DARK_THEME);
}
static void