Commit 69f87bcc authored by Michael Natterer's avatar Michael Natterer 😴

libgimpwidgets: be smarter when changing icon themes, and have fallbacks

Add gimp_stock_set_icon_theme() which can be called at any time, also
before gimp_stock_init(), in which case we avoid setting the configured
icon theme twice on startup. Call it from libgimp/gimpui.c and
from app/gui/icon-themes.c so the app and plug-ins use the same
icon theme.
parent 0af43e92
......@@ -221,6 +221,11 @@ gui_init (Gimp *gimp,
gui_unique_init (gimp);
gimp_language_store_parser_init ();
/* initialize icon themes before gimp_widgets_init() so we avoid
* setting the configured theme twice
*/
icon_themes_init (gimp);
gimp_widgets_init (gui_help_func,
gui_get_foreground_func,
gui_get_background_func,
......@@ -235,8 +240,6 @@ gui_init (Gimp *gimp,
themes_init (gimp);
icon_themes_init (gimp);
initial_monitor = gimp_get_monitor_at_pointer (&initial_screen);
gtk_widget_set_default_colormap (gdk_screen_get_rgb_colormap (initial_screen));
......
......@@ -208,10 +208,6 @@ static void
icons_apply_theme (Gimp *gimp,
const gchar *icon_theme_name)
{
GtkIconTheme *icon_theme;
gchar **paths;
gint n_paths;
g_return_if_fail (GIMP_IS_GIMP (gimp));
if (! icon_theme_name)
......@@ -220,22 +216,7 @@ icons_apply_theme (Gimp *gimp,
if (gimp->be_verbose)
g_print ("Loading icon theme '%s'\n", icon_theme_name);
icon_theme = gtk_icon_theme_get_default ();
gtk_icon_theme_get_search_path (icon_theme, &paths, &n_paths);
if (paths)
{
GFile *icon_theme_dir = icon_themes_get_theme_dir (gimp, icon_theme_name);
g_free (paths[0]);
paths[0] = g_file_get_path (icon_theme_dir);
gtk_icon_theme_set_search_path (icon_theme,
(const gchar **) paths, n_paths);
g_strfreev (paths);
}
gimp_stock_set_icon_theme (icon_themes_get_theme_dir (gimp, icon_theme_name));
}
static void
......
......@@ -96,6 +96,7 @@ gimp_ui_init (const gchar *prog_name,
GdkScreen *screen;
const gchar *display_name;
gchar *themerc;
GFile *icon_theme;
g_return_if_fail (prog_name != NULL);
......@@ -137,6 +138,10 @@ gimp_ui_init (const gchar *prog_name,
screen = gdk_screen_get_default ();
gtk_widget_set_default_colormap (gdk_screen_get_rgb_colormap (screen));
icon_theme = g_file_new_for_path (gimp_get_icon_theme_dir ());
gimp_stock_set_icon_theme (icon_theme);
g_object_unref (icon_theme);
gimp_widgets_init (gimp_ui_help_func,
gimp_context_get_foreground,
gimp_context_get_background,
......
......@@ -346,6 +346,131 @@ register_bidi_stock_icon (GtkIconFactory *factory,
}
static GFile *icon_theme_path = NULL;
static GFile *default_icon_theme_path = NULL;
static void
gimp_stock_change_icon_theme (GFile *path)
{
if (! default_icon_theme_path)
default_icon_theme_path = gimp_data_directory_file ("icons", "Default",
NULL);
if (! g_file_equal (path, icon_theme_path))
{
GtkIconTheme *icon_theme = gtk_icon_theme_get_default ();
if (g_file_equal (icon_theme_path, default_icon_theme_path))
{
/* if the current icon theme is the default theme, simply
* prepend the new theme's path
*/
gchar *path_str = g_file_get_path (path);
gtk_icon_theme_prepend_search_path (icon_theme, path_str);
g_free (path_str);
}
else
{
/* if the current theme is not the default theme, we need
* to deal with the search path's first element
*/
gchar **paths;
gint n_paths;
gtk_icon_theme_get_search_path (icon_theme, &paths, &n_paths);
if (g_file_equal (path, default_icon_theme_path))
{
/* when switching to the default theme, remove the
* first search path element, the default theme will
* still be in the search path as fallback
*/
gtk_icon_theme_set_search_path (icon_theme,
(const gchar **) paths + 1,
n_paths - 1);
}
else
{
/* when switching between two non-default themes, replace
* the first element of the search path with the new
* theme's path
*/
g_free (paths[0]);
paths[0] = g_file_get_path (path);
gtk_icon_theme_set_search_path (icon_theme,
(const gchar **) paths, n_paths);
}
g_strfreev (paths);
}
g_object_unref (icon_theme_path);
icon_theme_path = g_object_ref (path);
}
}
void
gimp_stock_set_icon_theme (GFile *path)
{
g_return_if_fail (path == NULL || G_IS_FILE (path));
if (path)
path = g_object_ref (path);
else
path = gimp_data_directory_file (gimp_data_directory (), "icons", "Default",
NULL);
if (! g_file_query_exists (path, NULL))
{
g_warning ("Icon theme path does not exist: %s",
gimp_file_get_utf8_name (path));
}
else
{
GFile *hicolor = g_file_get_child (path, "hicolor");
if (! g_file_query_exists (hicolor, NULL))
{
g_warning ("Icon theme path has no 'hicolor' subdirectory: %s",
gimp_file_get_utf8_name (path));
}
else
{
GFile *index = g_file_get_child (hicolor, "index.theme");
if (! g_file_query_exists (index, NULL))
{
g_warning ("Icon theme path has no 'hicolor/index.theme': %s",
gimp_file_get_utf8_name (path));
}
else
{
/* the path points to what looks like a valid icon theme */
if (icon_theme_path)
{
/* this is an icon theme change */
gimp_stock_change_icon_theme (path);
}
else
{
/* this is the first call upon initialization */
icon_theme_path = g_object_ref (path);
}
}
g_object_unref (index);
}
g_object_unref (hicolor);
}
g_object_unref (path);
}
/**
* gimp_stock_init:
*
......@@ -361,7 +486,6 @@ gimp_stock_init (void)
GdkPixbuf *pixbuf;
GError *error = NULL;
gchar *icon_theme;
gchar *icons_dir;
gint i;
......@@ -398,15 +522,29 @@ gimp_stock_init (void)
gtk_stock_add_static (gimp_compat_stock_items,
G_N_ELEMENTS (gimp_compat_stock_items));
icon_theme = g_strdup ("Default"); /* FIXME */
icons_dir = g_build_filename (gimp_data_directory (), "icons", icon_theme,
NULL);
g_free (icon_theme);
/* always prepend the default icon theme, it's never removed from
* the path again and acts as fallback for missing icons in other
* themes.
*/
if (! default_icon_theme_path)
default_icon_theme_path = gimp_data_directory_file ("icons", "Default",
NULL);
icons_dir = g_file_get_path (default_icon_theme_path);
gtk_icon_theme_prepend_search_path (gtk_icon_theme_get_default (),
icons_dir);
g_free (icons_dir);
/* if an icon theme was chosen before init(), change to it */
if (icon_theme_path &&
! g_file_equal (icon_theme_path, default_icon_theme_path))
{
icons_dir = g_file_get_path (icon_theme_path);
gtk_icon_theme_prepend_search_path (gtk_icon_theme_get_default (),
icons_dir);
g_free (icons_dir);
}
pixbuf = gdk_pixbuf_new_from_resource ("/org/gimp/icons/64/gimp-wilber-eek.png",
&error);
......
......@@ -296,7 +296,9 @@ G_BEGIN_DECLS
#define GIMP_STOCK_CONVERT_PRECISION GIMP_STOCK_CONVERT_RGB
void gimp_stock_init (void);
void gimp_stock_init (void);
void gimp_stock_set_icon_theme (GFile *path);
G_END_DECLS
......
......@@ -373,6 +373,7 @@ EXPORTS
gimp_spin_button_new
gimp_standard_help_func
gimp_stock_init
gimp_stock_set_icon_theme
gimp_string_combo_box_get_active
gimp_string_combo_box_get_type
gimp_string_combo_box_new
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment