#include "gtkicontheme.h"
#include "gtkiconfactory.h"
#include "gtkiconcache.h"
+#include "gtkbuiltincache.h"
#include "gtkintl.h"
+#include "gtkmain.h"
#include "gtksettings.h"
#include "gtkprivate.h"
#include "gtkalias.h"
-
#define DEFAULT_THEME_NAME "hicolor"
typedef enum
struct _GtkIconThemePrivate
{
- guint custom_theme : 1;
+ guint custom_theme : 1;
guint is_screen_singleton : 1;
guint pixbuf_supports_svg : 1;
+ guint themes_valid : 1;
+ guint check_reload : 1;
char *current_theme;
+ char *fallback_theme;
char **search_path;
int search_path_len;
- gboolean themes_valid;
/* A list of all the themes needed to look up icons.
* In search order, without duplicates
*/
*/
gchar *cp_filename;
#endif
- GdkPixbuf *builtin_pixbuf;
-
/* Cache pixbuf (if there is any) */
GdkPixbuf *cache_pixbuf;
GtkIconCache *cache;
} IconThemeDirMtime;
-static void gtk_icon_theme_class_init (GtkIconThemeClass *klass);
-static void gtk_icon_theme_init (GtkIconTheme *icon_theme);
static void gtk_icon_theme_finalize (GObject *object);
static void theme_dir_destroy (IconThemeDir *dir);
static void blow_themes (GtkIconTheme *icon_themes);
-static void icon_data_free (GtkIconData *icon_data);
-static void load_icon_data (IconThemeDir *dir,
- const char *path,
- const char *name);
+static void icon_data_free (GtkIconData *icon_data);
+static void load_icon_data (IconThemeDir *dir,
+ const char *path,
+ const char *name);
static IconSuffix theme_dir_get_icon_suffix (IconThemeDir *dir,
const gchar *icon_name,
static IconSuffix suffix_from_name (const char *name);
static BuiltinIcon *find_builtin_icon (const gchar *icon_name,
- gint size,
+ gint size,
gint *min_difference_p,
gboolean *has_larger_p);
-static GObjectClass *parent_class = NULL;
-
static guint signal_changed = 0;
static GHashTable *icon_theme_builtin_icons;
-GType
-gtk_icon_theme_get_type (void)
-{
- static GType type = 0;
-
- if (type == 0)
- {
- static const GTypeInfo info =
- {
- sizeof (GtkIconThemeClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) gtk_icon_theme_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (GtkIconTheme),
- 0, /* n_preallocs */
- (GInstanceInitFunc) gtk_icon_theme_init,
- };
-
- type = g_type_register_static (G_TYPE_OBJECT, "GtkIconTheme", &info, 0);
- }
+/* also used in gtkiconfactory.c */
+GtkIconCache *_builtin_cache = NULL;
+static GList *builtin_dirs = NULL;
- return type;
-}
+G_DEFINE_TYPE (GtkIconTheme, gtk_icon_theme, G_TYPE_OBJECT)
/**
* gtk_icon_theme_new:
priv = icon_theme->priv;
priv->is_screen_singleton = TRUE;
- g_object_set_data (G_OBJECT (screen), "gtk-icon-theme", icon_theme);
+ g_object_set_data (G_OBJECT (screen), I_("gtk-icon-theme"), icon_theme);
}
return icon_theme;
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- parent_class = g_type_class_peek_parent (klass);
-
gobject_class->finalize = gtk_icon_theme_finalize;
/**
* that a change has occurred in the contents of the current
* icon theme.
**/
- signal_changed = g_signal_new ("changed",
+ signal_changed = g_signal_new (I_("changed"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkIconThemeClass, changed),
if (was_screen_singleton)
{
- g_object_set_data (G_OBJECT (screen), "gtk-icon-theme", NULL);
+ g_object_set_data (G_OBJECT (screen), I_("gtk-icon-theme"), NULL);
priv->is_screen_singleton = FALSE;
}
if (!priv->custom_theme)
{
gchar *theme = NULL;
+ gchar *fallback_theme = NULL;
+ gboolean changed = FALSE;
if (priv->screen)
{
GtkSettings *settings = gtk_settings_get_for_screen (priv->screen);
- g_object_get (settings, "gtk-icon-theme-name", &theme, NULL);
+ g_object_get (settings,
+ "gtk-icon-theme-name", &theme,
+ "gtk-fallback-icon-theme", &fallback_theme, NULL);
}
if (!theme)
g_free (priv->current_theme);
priv->current_theme = theme;
- do_theme_change (icon_theme);
+ changed = TRUE;
}
else
g_free (theme);
+
+ if ((priv->fallback_theme && !fallback_theme) ||
+ (!priv->fallback_theme && fallback_theme) ||
+ (priv->fallback_theme && fallback_theme &&
+ strcmp (priv->fallback_theme, fallback_theme) != 0))
+ {
+ g_free (priv->fallback_theme);
+ priv->fallback_theme = fallback_theme;
+
+ changed = TRUE;
+ }
+ else
+ g_free (fallback_theme);
+
+ if (changed)
+ do_theme_change (icon_theme);
}
}
G_CALLBACK (display_closed), icon_theme);
g_signal_connect (settings, "notify::gtk-icon-theme-name",
G_CALLBACK (theme_changed), icon_theme);
+ g_signal_connect (settings, "notify::gtk-fallback-icon-theme-name",
+ G_CALLBACK (theme_changed), icon_theme);
}
update_current_theme (icon_theme);
{
GSList *formats = gdk_pixbuf_get_formats ();
GSList *tmp_list;
- static gboolean found_svg = FALSE;
- static gboolean value_known = FALSE;
+ static gint found_svg = -1;
- if (value_known)
+ if (found_svg != -1)
return found_svg;
-
+
+ found_svg = FALSE;
for (tmp_list = formats; tmp_list && !found_svg; tmp_list = tmp_list->next)
{
gchar **mime_types = gdk_pixbuf_format_get_mime_types (tmp_list->data);
}
g_slist_free (formats);
- value_known = TRUE;
return found_svg;
}
_gtk_icon_cache_unref (dir_mtime->cache);
g_free (dir_mtime->dir);
- g_free (dir_mtime);
+ g_slice_free (IconThemeDirMtime, dir_mtime);
}
if (!priv->reset_styles_idle)
priv->reset_styles_idle =
- g_idle_add (reset_styles_idle, icon_theme);
+ g_idle_add_full (GTK_PRIORITY_RESIZE - 2,
+ reset_styles_idle, icon_theme, NULL);
}
static void
g_free (priv->current_theme);
priv->current_theme = NULL;
- for (i=0; i < priv->search_path_len; i++)
+ for (i = 0; i < priv->search_path_len; i++)
g_free (priv->search_path[i]);
g_free (priv->search_path);
blow_themes (icon_theme);
- G_OBJECT_CLASS (parent_class)->finalize (object);
+ G_OBJECT_CLASS (gtk_icon_theme_parent_class)->finalize (object);
}
/**
priv->search_path = g_new (gchar *, n_elements);
priv->search_path_len = n_elements;
+
for (i = 0; i < priv->search_path_len; i++)
priv->search_path[i] = g_strdup (path[i]);
priv = icon_theme->priv;
priv->search_path_len++;
+
priv->search_path = g_renew (gchar *, priv->search_path, priv->search_path_len);
priv->search_path[priv->search_path_len-1] = g_strdup (path);
path = g_build_filename (priv->search_path[i],
theme_name,
NULL);
- dir_mtime = g_new (IconThemeDirMtime, 1);
+ dir_mtime = g_slice_new (IconThemeDirMtime);
dir_mtime->cache = NULL;
dir_mtime->dir = path;
if (g_stat (path, &stat_buf) == 0 && S_ISDIR (stat_buf.st_mode))
g_free (path);
}
+ if (theme_file || strcmp (theme_name, DEFAULT_THEME_NAME) == 0)
+ {
+ theme = g_new0 (IconTheme, 1);
+ theme->name = g_strdup (theme_name);
+ priv->themes = g_list_prepend (priv->themes, theme);
+ }
+
if (theme_file == NULL)
return;
-
- theme = g_new (IconTheme, 1);
+
theme->display_name =
g_key_file_get_locale_string (theme_file, "Icon Theme", "Name", NULL, NULL);
if (!theme->display_name)
- {
- g_warning ("Theme file for %s has no name\n", theme_name);
- g_free (theme);
- g_key_file_free (theme_file);
- return;
- }
+ g_warning ("Theme file for %s has no name\n", theme_name);
dirs = g_key_file_get_string_list (theme_file, "Icon Theme", "Directories", NULL, NULL);
if (!dirs)
return;
}
- theme->name = g_strdup (theme_name);
theme->comment =
g_key_file_get_locale_string (theme_file,
"Icon Theme", "Comment",
theme->dirs = NULL;
for (i = 0; dirs[i] != NULL; i++)
theme_subdir_load (icon_theme, theme, theme_file, dirs[i]);
-
+
g_strfreev (dirs);
-
- theme->dirs = g_list_reverse (theme->dirs);
- /* Prepend the finished theme */
- priv->themes = g_list_prepend (priv->themes, theme);
+ theme->dirs = g_list_reverse (theme->dirs);
themes = g_key_file_get_string_list (theme_file,
"Icon Theme",
g_free (unthemed_icon->svg_filename);
if (unthemed_icon->no_svg_filename)
g_free (unthemed_icon->no_svg_filename);
- g_free (unthemed_icon);
+ g_slice_free (UnthemedIcon, unthemed_icon);
+}
+
+static char *
+strip_suffix (const char *filename)
+{
+ const char *dot;
+
+ dot = strrchr (filename, '.');
+
+ if (dot == NULL)
+ return g_strdup (filename);
+
+ return g_strndup (filename, dot - filename);
}
static void
GtkIconThemePrivate *priv;
GDir *gdir;
int base;
- char *dir, *base_name, *dot;
+ char *dir;
const char *file;
- char *abs_file;
UnthemedIcon *unthemed_icon;
IconSuffix old_suffix, new_suffix;
GTimeVal tv;
priv->all_icons = g_hash_table_new (g_str_hash, g_str_equal);
insert_theme (icon_theme, priv->current_theme);
-
- /* Always look in the "default" icon theme */
+
+ /* Always look in the "default" icon theme, and in a fallback theme */
+ if (priv->fallback_theme)
+ insert_theme (icon_theme, priv->fallback_theme);
insert_theme (icon_theme, DEFAULT_THEME_NAME);
priv->themes = g_list_reverse (priv->themes);
{
dir = icon_theme->priv->search_path[base];
- dir_mtime = g_new (IconThemeDirMtime, 1);
+ dir_mtime = g_slice_new (IconThemeDirMtime);
dir_mtime->cache = _gtk_icon_cache_new_for_path (dir);
dir_mtime->dir = g_strdup (dir);
if (g_stat (dir, &stat_buf) == 0 && S_ISDIR (stat_buf.st_mode))
dir_mtime->mtime = stat_buf.st_mtime;
else
dir_mtime->mtime = 0;
-
+
priv->dir_mtimes = g_list_append (priv->dir_mtimes, dir_mtime);
-
+
if (dir_mtime->cache != NULL)
continue;
if (gdir == NULL)
continue;
-
+
while ((file = g_dir_read_name (gdir)))
{
new_suffix = suffix_from_name (file);
-
+
if (new_suffix != ICON_SUFFIX_NONE)
{
- abs_file = g_build_filename (dir, file, NULL);
+ char *abs_file;
+ char *base_name;
- base_name = g_strdup (file);
-
- dot = strrchr (base_name, '.');
- if (dot)
- *dot = 0;
+ abs_file = g_build_filename (dir, file, NULL);
+ base_name = strip_suffix (file);
if ((unthemed_icon = g_hash_table_lookup (priv->unthemed_icons,
base_name)))
}
else
{
- unthemed_icon = g_new0 (UnthemedIcon, 1);
+ unthemed_icon = g_slice_new0 (UnthemedIcon);
if (new_suffix == ICON_SUFFIX_SVG)
unthemed_icon->svg_filename = abs_file;
priv->last_stat_time = tv.tv_sec;
}
+void
+_gtk_icon_theme_ensure_builtin_cache (void)
+{
+ static gboolean initialized = FALSE;
+ IconThemeDir *dir;
+ static IconThemeDir dirs[5] =
+ {
+ { ICON_THEME_DIR_THRESHOLD, 0, 16, 16, 16, 2, NULL, "16", NULL, NULL, NULL },
+ { ICON_THEME_DIR_THRESHOLD, 0, 20, 20, 20, 2, NULL, "20", NULL, NULL, NULL },
+ { ICON_THEME_DIR_THRESHOLD, 0, 24, 24, 24, 2, NULL, "24", NULL, NULL, NULL },
+ { ICON_THEME_DIR_THRESHOLD, 0, 32, 32, 32, 2, NULL, "32", NULL, NULL, NULL },
+ { ICON_THEME_DIR_THRESHOLD, 0, 48, 48, 48, 2, NULL, "48", NULL, NULL, NULL }
+ };
+ gint i;
+
+ if (!initialized)
+ {
+ initialized = TRUE;
+
+ _builtin_cache = _gtk_icon_cache_new ((gchar *)builtin_icons);
+
+ for (i = 0; i < G_N_ELEMENTS (dirs); i++)
+ {
+ dir = &(dirs[i]);
+ dir->cache = _gtk_icon_cache_ref (_builtin_cache);
+
+ builtin_dirs = g_list_append (builtin_dirs, dir);
+ }
+ }
+}
+
static void
ensure_valid_themes (GtkIconTheme *icon_theme)
{
GtkIconThemePrivate *priv = icon_theme->priv;
GTimeVal tv;
-
+ gboolean was_valid = priv->themes_valid;
+
+ _gtk_icon_theme_ensure_builtin_cache ();
+
if (priv->themes_valid)
{
g_get_current_time (&tv);
}
if (!priv->themes_valid)
- load_themes (icon_theme);
+ {
+ load_themes (icon_theme);
+
+ if (!priv->check_reload && was_valid && priv->screen)
+ {
+ static GdkAtom atom_iconthemes = GDK_NONE;
+ GdkEvent *event = gdk_event_new (GDK_CLIENT_EVENT);
+ int i;
+
+ if (!atom_iconthemes)
+ atom_iconthemes = gdk_atom_intern_static_string ("_GTK_LOAD_ICONTHEMES");
+
+ for (i = 0; i < 5; i++)
+ event->client.data.l[i] = 0;
+ event->client.data_format = 32;
+ event->client.message_type = atom_iconthemes;
+
+ gdk_screen_broadcast_client_message (priv->screen, event);
+ }
+ }
}
/**
UnthemedIcon *unthemed_icon;
gboolean allow_svg;
gboolean use_builtin;
- gboolean found_default;
g_return_val_if_fail (GTK_IS_ICON_THEME (icon_theme), NULL);
g_return_val_if_fail (icon_name != NULL, NULL);
ensure_valid_themes (icon_theme);
- found_default = FALSE;
- l = priv->themes;
- while (l != NULL)
+ for (l = priv->themes; l; l = l->next)
{
IconTheme *theme = l->data;
- if (strcmp (theme->name, DEFAULT_THEME_NAME) == 0)
- found_default = TRUE;
-
icon_info = theme_lookup_icon (theme, icon_name, size, allow_svg, use_builtin);
if (icon_info)
goto out;
-
- l = l->next;
}
- if (!found_default)
- {
- BuiltinIcon *builtin = find_builtin_icon (icon_name, size, NULL, NULL);
- if (builtin)
- {
- icon_info = icon_info_new_builtin (builtin);
- goto out;
- }
- }
-
unthemed_icon = g_hash_table_lookup (priv->unthemed_icons, icon_name);
if (unthemed_icon)
{
GQuark
gtk_icon_theme_error_quark (void)
{
- static GQuark q = 0;
- if (q == 0)
- q = g_quark_from_static_string ("gtk-icon-theme-error-quark");
-
- return q;
+ return g_quark_from_static_string ("gtk-icon-theme-error-quark");
}
/**
* and renders it into a pixbuf. This is a convenience function;
* if more details about the icon are needed, use
* gtk_icon_theme_lookup_icon() followed by gtk_icon_info_load_icon().
+ *
+ * Note that you probably want to listen for icon theme changes and
+ * update the icon. This is usually done by connecting to the
+ * GtkWidget::style-set signal. If for some reason you do not want to
+ * update the icon when the icon theme changes, you should consider
+ * using gdk_pixbuf_copy() to make a private copy of the pixbuf
+ * returned by this function. Otherwise GTK+ may need to keep the old
+ * icon theme loaded, which would be a waste of memory.
*
* Return value: the rendered icon; this may be a newly created icon
* or a new reference to an internal icon, so you must not modify
icon_name, NULL, NULL))
return TRUE;
+ if (_builtin_cache &&
+ _gtk_icon_cache_has_icon (_builtin_cache, icon_name))
+ return TRUE;
+
if (icon_theme_builtin_icons &&
g_hash_table_lookup_extended (icon_theme_builtin_icons,
icon_name, NULL, NULL))
gtk_icon_theme_get_icon_sizes (GtkIconTheme *icon_theme,
const char *icon_name)
{
- GList *l, *d;
+ GList *l, *d, *icons;
GHashTable *sizes;
gint *result, *r;
- guint suffix;
-
+ guint suffix;
GtkIconThemePrivate *priv;
g_return_val_if_fail (GTK_IS_ICON_THEME (icon_theme), NULL);
}
}
+ for (d = builtin_dirs; d; d = d->next)
+ {
+ IconThemeDir *dir = d->data;
+
+ suffix = theme_dir_get_icon_suffix (dir, icon_name, NULL);
+ if (suffix != ICON_SUFFIX_NONE)
+ {
+ if (suffix == ICON_SUFFIX_SVG)
+ g_hash_table_insert (sizes, GINT_TO_POINTER (-1), NULL);
+ else
+ g_hash_table_insert (sizes, GINT_TO_POINTER (dir->size), NULL);
+ }
+ }
+
+ if (icon_theme_builtin_icons)
+ {
+ icons = g_hash_table_lookup (icon_theme_builtin_icons, icon_name);
+
+ while (icons)
+ {
+ BuiltinIcon *icon = icons->data;
+
+ g_hash_table_insert (sizes, GINT_TO_POINTER (icon->size), NULL);
+ icons = icons->next;
+ }
+ }
+
r = result = g_new0 (gint, g_hash_table_size (sizes) + 1);
g_hash_table_foreach (sizes, add_size, &r);
* Lists the icons in the current icon theme. Only a subset
* of the icons can be listed by providing a context string.
* The set of values for the context string is system dependent,
- * but will typically include such values as 'apps' and
- * 'mimetypes'.
+ * but will typically include such values as "Applications" and
+ * "MimeTypes".
*
* Return value: a #GList list holding the names of all the
* icons in the theme. You must first free each element
suffix = suffix & ~HAS_ICON_FILE;
}
else
- suffix = GPOINTER_TO_UINT (g_hash_table_lookup (dir->icons, icon_name));
+ suffix = GPOINTER_TO_UINT (g_hash_table_lookup (dir->icons, icon_name));
GTK_NOTE (ICONTHEME,
g_print ("get_icon_suffix%s %d\n", dir->cache ? " (cached)" : "", suffix));
gboolean allow_svg,
gboolean use_builtin)
{
- GList *l;
+ GList *dirs, *l;
IconThemeDir *dir, *min_dir;
char *file;
int min_difference, difference;
*/
if (strcmp (theme->name, DEFAULT_THEME_NAME) == 0 && use_builtin)
{
- closest_builtin = find_builtin_icon (icon_name, size,
+ closest_builtin = find_builtin_icon (icon_name,
+ size,
&min_difference,
&has_larger);
if (min_difference == 0)
return icon_info_new_builtin (closest_builtin);
+
+ dirs = builtin_dirs;
}
+ else
+ dirs = theme->dirs;
- l = theme->dirs;
+ l = dirs;
while (l != NULL)
{
dir = l->data;
}
l = l->next;
+
+ if (l == NULL && dirs == builtin_dirs)
+ {
+ dirs = theme->dirs;
+ l = dirs;
+ }
}
if (closest_builtin)
if (min_dir)
{
GtkIconInfo *icon_info = icon_info_new ();
- gboolean has_icon_file;
+ gboolean has_icon_file = FALSE;
suffix = theme_dir_get_icon_suffix (min_dir, icon_name, &has_icon_file);
suffix = best_suffix (suffix, allow_svg);
if (min_dir->icon_data != NULL)
icon_info->data = g_hash_table_lookup (min_dir->icon_data, icon_name);
- else if (min_dir->cache != NULL)
- icon_info->data = _gtk_icon_cache_get_icon_data (min_dir->cache, icon_name, min_dir->subdir);
- if (icon_info->data == NULL &&
- min_dir->cache && has_icon_file)
+ if (icon_info->data == NULL && min_dir->cache != NULL)
+ {
+ icon_info->data = _gtk_icon_cache_get_icon_data (min_dir->cache, icon_name, min_dir->subdir);
+ if (icon_info->data)
+ {
+ if (min_dir->icon_data == NULL)
+ min_dir->icon_data = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, (GDestroyNotify)icon_data_free);
+
+ g_hash_table_replace (min_dir->icon_data, g_strdup (icon_name), icon_info->data);
+ }
+ }
+
+ if (icon_info->data == NULL && has_icon_file)
{
gchar *icon_file_name, *icon_file_path;
if (g_file_test (icon_file_path, G_FILE_TEST_IS_REGULAR))
{
- if (min_dir->icon_data == NULL)
+ if (min_dir->icon_data == NULL)
min_dir->icon_data = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, (GDestroyNotify)icon_data_free);
load_icon_data (min_dir, icon_file_path, icon_file_name);
}
static void
-theme_list_icons (IconTheme *theme, GHashTable *icons,
- GQuark context)
+theme_list_icons (IconTheme *theme,
+ GHashTable *icons,
+ GQuark context)
{
GList *l = theme->dirs;
IconThemeDir *dir;
char *base_name;
char **split;
gsize length;
- char *dot;
char *str;
char *split_point;
int i;
if (error)
{
g_error_free (error);
+ g_key_file_free (icon_file);
return;
}
else
{
- base_name = g_strdup (name);
- dot = strrchr (base_name, '.');
- *dot = 0;
+ base_name = strip_suffix (name);
- data = g_new0 (GtkIconData, 1);
+ data = g_slice_new0 (GtkIconData);
g_hash_table_replace (dir->icon_data, base_name, data);
ivalues = g_key_file_get_integer_list (icon_file,
split = g_strsplit (str, "|", -1);
data->n_attach_points = g_strv_length (split);
- data->attach_points = g_malloc (sizeof (GdkPoint) * data->n_attach_points);
+ data->attach_points = g_new (GdkPoint, data->n_attach_points);
i = 0;
while (split[i] != NULL && i < data->n_attach_points)
{
GDir *gdir;
const char *name;
- char *base_name, *dot;
- char *path;
- IconSuffix suffix, hash_suffix;
GTK_NOTE (ICONTHEME,
g_print ("scanning directory %s\n", full_dir));
while ((name = g_dir_read_name (gdir)))
{
+ char *path;
+ char *base_name;
+ IconSuffix suffix, hash_suffix;
+
if (g_str_has_suffix (name, ".icon"))
{
if (dir->icon_data == NULL)
suffix = suffix_from_name (name);
if (suffix == ICON_SUFFIX_NONE)
continue;
-
- base_name = g_strdup (name);
- dot = strrchr (base_name, '.');
- *dot = 0;
-
+
+ base_name = strip_suffix (name);
+
hash_suffix = GPOINTER_TO_INT (g_hash_table_lookup (dir->icons, base_name));
g_hash_table_replace (dir->icons, base_name, GUINT_TO_POINTER (hash_suffix| suffix));
g_hash_table_insert (icon_theme->all_icons, base_name, NULL);
{
g_free (icon_data->attach_points);
g_free (icon_data->display_name);
- g_free (icon_data);
+ g_slice_free (GtkIconData, icon_data);
}
/*
static GType our_type = 0;
if (our_type == 0)
- our_type = g_boxed_type_register_static ("GtkIconInfo",
+ our_type = g_boxed_type_register_static (I_("GtkIconInfo"),
(GBoxedCopyFunc) gtk_icon_info_copy,
(GBoxedFreeFunc) gtk_icon_info_free);
+
return our_type;
}
static GtkIconInfo *
icon_info_new (void)
{
- GtkIconInfo *icon_info = g_new0 (GtkIconInfo, 1);
+ GtkIconInfo *icon_info = g_slice_new0 (GtkIconInfo);
icon_info->scale = -1.;
{
GtkIconInfo *icon_info = icon_info_new ();
- icon_info->builtin_pixbuf = g_object_ref (icon->pixbuf);
+ icon_info->cache_pixbuf = g_object_ref (icon->pixbuf);
icon_info->dir_type = ICON_THEME_DIR_THRESHOLD;
icon_info->dir_size = icon->size;
icon_info->threshold = 2;
g_return_val_if_fail (icon_info != NULL, NULL);
- copy = g_memdup (icon_info, sizeof (GtkIconInfo));
- if (copy->builtin_pixbuf)
- g_object_ref (copy->builtin_pixbuf);
+ copy = memcpy (g_slice_new (GtkIconInfo), icon_info, sizeof (GtkIconInfo));
+ if (copy->cache_pixbuf)
+ g_object_ref (copy->cache_pixbuf);
if (copy->pixbuf)
g_object_ref (copy->pixbuf);
if (copy->load_error)
if (icon_info->cp_filename)
g_free (icon_info->cp_filename);
#endif
- if (icon_info->builtin_pixbuf)
- g_object_unref (icon_info->builtin_pixbuf);
if (icon_info->pixbuf)
g_object_unref (icon_info->pixbuf);
if (icon_info->cache_pixbuf)
g_object_unref (icon_info->cache_pixbuf);
-
- g_free (icon_info);
+
+ g_slice_free (GtkIconInfo, icon_info);
}
/**
{
g_return_val_if_fail (icon_info != NULL, NULL);
- return icon_info->builtin_pixbuf;
+ if (icon_info->filename)
+ return NULL;
+
+ return icon_info->cache_pixbuf;
}
static GdkPixbuf *
/* At this point, we need to actually get the icon; either from the
* builting image or by loading the file
*/
- if (icon_info->builtin_pixbuf)
- source_pixbuf = g_object_ref (icon_info->builtin_pixbuf);
- else if (icon_info->cache_pixbuf)
+ if (icon_info->cache_pixbuf)
source_pixbuf = g_object_ref (icon_info->cache_pixbuf);
else
{
* Since: 2.4
**/
G_CONST_RETURN gchar *
-gtk_icon_info_get_display_name (GtkIconInfo *icon_info)
+gtk_icon_info_get_display_name (GtkIconInfo *icon_info)
{
g_return_val_if_fail (icon_info != NULL, NULL);
gboolean has_larger = FALSE;
BuiltinIcon *min_icon = NULL;
- _gtk_icon_factory_ensure_default_icons ();
-
if (!icon_theme_builtin_icons)
return NULL;
return min_icon;
}
+void
+_gtk_icon_theme_check_reload (GdkDisplay *display)
+{
+ gint n_screens, i;
+ GdkScreen *screen;
+ GtkIconTheme *icon_theme;
+
+ n_screens = gdk_display_get_n_screens (display);
+
+ for (i = 0; i < n_screens; i++)
+ {
+ screen = gdk_display_get_screen (display, i);
+
+ icon_theme = g_object_get_data (G_OBJECT (screen), "gtk-icon-theme");
+ if (icon_theme)
+ {
+ icon_theme->priv->check_reload = TRUE;
+ ensure_valid_themes (icon_theme);
+ icon_theme->priv->check_reload = FALSE;
+ }
+ }
+}
+
#ifdef G_OS_WIN32
/* DLL ABI stability backward compatibility versions */