Add some theme apis

Add apis to get the list of available themes,
as well as the dark or light variant of a theme.
This commit is contained in:
Matthias Clasen
2020-04-12 00:20:27 -04:00
parent eb7ad4bbad
commit 37c151ce0f
8 changed files with 235 additions and 63 deletions

View File

@@ -2304,6 +2304,12 @@ GtkSettingsValue
gtk_settings_get_default
gtk_settings_get_for_display
gtk_settings_reset_property
<SUBSECTION>
gtk_theme_get_dark_variant
gtk_theme_get_light_variant
gtk_theme_get_available_themes
<SUBSECTION Standard>
GtkSettingsClass
GTK_IS_SETTINGS

View File

@@ -230,6 +230,7 @@
#include <gtk/gtktexttag.h>
#include <gtk/gtktexttagtable.h>
#include <gtk/gtktextview.h>
#include <gtk/gtktheme.h>
#include <gtk/gtktogglebutton.h>
#include <gtk/gtktooltip.h>
#include <gtk/gtktestutils.h>

View File

@@ -1266,8 +1266,8 @@ _gtk_css_find_theme_dir (const gchar *dir,
#undef MINOR
static gchar *
_gtk_css_find_theme (const gchar *name)
char *
_gtk_css_find_theme (const char *name)
{
gchar *path;
const char *const *dirs;

View File

@@ -26,6 +26,8 @@ gchar *_gtk_get_theme_dir (void);
const gchar *_gtk_css_provider_get_theme_dir (GtkCssProvider *provider);
char *_gtk_css_find_theme (const char *theme);
void gtk_css_provider_set_keep_css_sections (void);
G_END_DECLS

View File

@@ -29,6 +29,7 @@
#include "gtkstyleproviderprivate.h"
#include "gtktypebuiltins.h"
#include "gtkversion.h"
#include "gtktheme.h"
#include "gtkwidget.h"
#include "gdk/gdk-private.h"
@@ -1635,65 +1636,6 @@ settings_update_provider (GdkDisplay *display,
* NAME/NAME-dark
*/
extern char *_gtk_css_find_theme (const char *theme);
static gboolean
theme_exists (const char *theme)
{
char *path;
path = _gtk_css_find_theme (theme);
if (path)
{
g_free (path);
return TRUE;
}
return FALSE;
}
static char *
get_light_theme_variant (const char *theme)
{
if (g_str_equal (theme, "HighContrastInverse"))
return g_strdup ("HighContrast");
if (g_str_equal (theme, "Adwaita-dark"))
return g_strdup ("Adwaita");
if (g_str_has_suffix (theme, "-dark"))
{
char *light = g_strndup (theme, strlen (theme) - strlen ("-dark"));
if (theme_exists (light))
return light;
g_free (light);
}
return g_strdup (theme);
}
static char *
get_dark_theme_variant (const char *theme)
{
if (g_str_equal (theme, "HighContrast"))
return g_strdup ("HighContrastInverse");
if (g_str_equal (theme, "Adwaita"))
return g_strdup ("Adwaita-dark");
if (!g_str_has_suffix (theme, "-dark"))
{
char *dark = g_strconcat (theme, "-dark", NULL);
if (theme_exists (dark))
return dark;
g_free (dark);
}
return g_strdup (theme);
}
static char *
get_theme_name (GtkSettings *settings)
{
@@ -1715,11 +1657,11 @@ get_theme_name (GtkSettings *settings)
switch (user_pref)
{
case 0:
theme = get_light_theme_variant (theme_name);
theme = gtk_theme_get_light_variant (theme_name);
g_free (theme_name);
break;
case 1:
theme = get_dark_theme_variant (theme_name);
theme = gtk_theme_get_dark_variant (theme_name);
g_free (theme_name);
break;
default:

181
gtk/gtktheme.c Normal file
View File

@@ -0,0 +1,181 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2020 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gtktheme.h"
#include "gtkcssproviderprivate.h"
static gboolean
theme_exists (const char *theme)
{
char *path;
path = _gtk_css_find_theme (theme);
if (path)
{
g_free (path);
return TRUE;
}
return FALSE;
}
/**
* gtk_theme_get_dark_variant:
* @theme: a theme name
*
* Returns the name of the dark variant of the
* given theme, if such a variant is available.
* Otherwise, @theme is returned.
*
* Returns: (transfer full): name of the dark variant
* of @theme. Free with g_free()
*/
char *
gtk_theme_get_dark_variant (const char *theme)
{
if (g_str_equal (theme, "HighContrast"))
return g_strdup ("HighContrastInverse");
if (g_str_equal (theme, "Adwaita"))
return g_strdup ("Adwaita-dark");
if (!g_str_has_suffix (theme, "-dark"))
{
char *dark = g_strconcat (theme, "-dark", NULL);
if (theme_exists (dark))
return dark;
g_free (dark);
}
return g_strdup (theme);
}
/**
* gtk_theme_get_light_variant:
* @theme: a theme name
*
* Returns the name of the light variant of the
* given theme, if such a variant is available.
* Otherwise, @theme is returned.
*
* Returns: (transfer full): name of the light variant
* of @theme. Free with g_free()
*/
char *
gtk_theme_get_light_variant (const char *theme)
{
if (g_str_equal (theme, "HighContrastInverse"))
return g_strdup ("HighContrast");
if (g_str_equal (theme, "Adwaita-dark"))
return g_strdup ("Adwaita");
if (g_str_has_suffix (theme, "-dark"))
{
char *light = g_strndup (theme, strlen (theme) - strlen ("-dark"));
if (theme_exists (light))
return light;
g_free (light);
}
return g_strdup (theme);
}
static void
fill_gtk (const gchar *path,
GHashTable *t)
{
const gchar *dir_entry;
GDir *dir = g_dir_open (path, 0, NULL);
if (!dir)
return;
while ((dir_entry = g_dir_read_name (dir)))
{
gchar *filename = g_build_filename (path, dir_entry, "gtk-4.0", "gtk.css", NULL);
if (g_file_test (filename, G_FILE_TEST_IS_REGULAR) &&
!g_hash_table_contains (t, dir_entry))
g_hash_table_add (t, g_strdup (dir_entry));
g_free (filename);
}
g_dir_close (dir);
}
/**
* gtk_theme_get_available_themes:
*
* Returns the list of available themes.
*
* Returns: (transfer full): an array of theme names
*/
char **
gtk_theme_get_available_themes (void)
{
GHashTable *t;
gchar *path;
gchar **builtin_themes;
guint i;
const gchar * const *dirs;
char **keys;
char **result;
t = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
/* Builtin themes */
builtin_themes = g_resources_enumerate_children ("/org/gtk/libgtk/theme", 0, NULL);
for (i = 0; builtin_themes[i] != NULL; i++)
{
if (g_str_has_suffix (builtin_themes[i], "/"))
g_hash_table_add (t, g_strndup (builtin_themes[i], strlen (builtin_themes[i]) - 1));
}
g_strfreev (builtin_themes);
path = _gtk_get_theme_dir ();
fill_gtk (path, t);
g_free (path);
path = g_build_filename (g_get_user_data_dir (), "themes", NULL);
fill_gtk (path, t);
g_free (path);
path = g_build_filename (g_get_home_dir (), ".themes", NULL);
fill_gtk (path, t);
g_free (path);
dirs = g_get_system_data_dirs ();
for (i = 0; dirs[i]; i++)
{
path = g_build_filename (dirs[i], "themes", NULL);
fill_gtk (path, t);
g_free (path);
}
keys = (char **)g_hash_table_get_keys_as_array (t, NULL);
result = g_strdupv (keys);
g_free (keys);
g_hash_table_destroy (t);
return result;
}

38
gtk/gtktheme.h Normal file
View File

@@ -0,0 +1,38 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2020 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GTK_THEME_H__
#define __GTK_THEME_H__
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtktypes.h>
G_BEGIN_DECLS
GDK_AVAILABLE_IN_ALL
char * gtk_theme_get_dark_variant (const char *theme);
GDK_AVAILABLE_IN_ALL
char * gtk_theme_get_light_variant (const char *theme);
GDK_AVAILABLE_IN_ALL
char **gtk_theme_get_available_themes (void);
G_END_DECLS
#endif /* __GTK_THEME_H__ */

View File

@@ -370,6 +370,7 @@ gtk_public_sources = files([
'gtktexttypes.c',
'gtktextutil.c',
'gtktextview.c',
'gtktheme.c',
'gtktogglebutton.c',
'gtktooltip.c',
'gtktooltipwindow.c',
@@ -602,6 +603,7 @@ gtk_public_headers = files([
'gtktexttag.h',
'gtktexttagtable.h',
'gtktextview.h',
'gtktheme.h',
'gtktogglebutton.h',
'gtktooltip.h',
'gtktreednd.h',