diff --git a/ChangeLog b/ChangeLog index dff5709fdb..8f01dd964a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2005-04-05 Matthias Clasen + + * gtk/gtkicontheme.c: Store icon caches along with the + mtimes of the toplevel directories. The previous + mechanism of a hashtable-per-theme caused duplicate icon + caches for the same toplevel directory to be created. + (#170030) + 2005-04-05 Matthias Clasen * gtk/gtktreemodelsort.c (gtk_tree_model_sort_build_level): diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index dff5709fdb..8f01dd964a 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,11 @@ +2005-04-05 Matthias Clasen + + * gtk/gtkicontheme.c: Store icon caches along with the + mtimes of the toplevel directories. The previous + mechanism of a hashtable-per-theme caused duplicate icon + caches for the same toplevel directory to be created. + (#170030) + 2005-04-05 Matthias Clasen * gtk/gtktreemodelsort.c (gtk_tree_model_sort_build_level): diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index dff5709fdb..8f01dd964a 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,11 @@ +2005-04-05 Matthias Clasen + + * gtk/gtkicontheme.c: Store icon caches along with the + mtimes of the toplevel directories. The previous + mechanism of a hashtable-per-theme caused duplicate icon + caches for the same toplevel directory to be created. + (#170030) + 2005-04-05 Matthias Clasen * gtk/gtktreemodelsort.c (gtk_tree_model_sort_build_level): diff --git a/gtk/gtkicontheme.c b/gtk/gtkicontheme.c index b8d88313f5..01d3b57da8 100644 --- a/gtk/gtkicontheme.c +++ b/gtk/gtkicontheme.c @@ -142,11 +142,6 @@ typedef struct char *comment; char *example; - /* Icon caches, per theme directory, key is NULL if - * no cache exists for that directory - */ - GHashTable *icon_caches; - /* In search order */ GList *dirs; } IconTheme; @@ -186,6 +181,8 @@ typedef struct { char *dir; time_t mtime; /* 0 == not existing or not a dir */ + + GtkIconCache *cache; } IconThemeDirMtime; static void gtk_icon_theme_class_init (GtkIconThemeClass *klass); @@ -582,8 +579,12 @@ gtk_icon_theme_init (GtkIconTheme *icon_theme) static void free_dir_mtime (IconThemeDirMtime *dir_mtime) { + if (dir_mtime->cache) + _gtk_icon_cache_unref (dir_mtime->cache); + g_free (dir_mtime->dir); g_free (dir_mtime); + } static void @@ -883,6 +884,7 @@ insert_theme (GtkIconTheme *icon_theme, const char *theme_name) theme_name, NULL); dir_mtime = g_new (IconThemeDirMtime, 1); + dir_mtime->cache = NULL; dir_mtime->dir = path; if (g_stat (path, &stat_buf) == 0 && S_ISDIR (stat_buf.st_mode)) dir_mtime->mtime = stat_buf.st_mtime; @@ -950,7 +952,6 @@ insert_theme (GtkIconTheme *icon_theme, const char *theme_name) "Icon Theme", "Example", NULL); - theme->icon_caches = NULL; theme->dirs = NULL; for (i = 0; dirs[i] != NULL; i++) theme_subdir_load (icon_theme, theme, theme_file, dirs[i]); @@ -1321,27 +1322,6 @@ gtk_icon_theme_load_icon (GtkIconTheme *icon_theme, return pixbuf; } -typedef struct -{ - const gchar *icon_name; - gboolean found; -} CacheSearch; - -static void -cache_has_icon (gpointer key, - gpointer value, - gpointer user_data) -{ - GtkIconCache *cache = (GtkIconCache *)value; - CacheSearch *search = (CacheSearch *)user_data; - - if (!cache || search->found) - return; - - if (_gtk_icon_cache_has_icon (cache, search->icon_name)) - search->found = TRUE; -} - /** * gtk_icon_theme_has_icon: * @icon_theme: a #GtkIconTheme @@ -1361,7 +1341,6 @@ gtk_icon_theme_has_icon (GtkIconTheme *icon_theme, { GtkIconThemePrivate *priv; GList *l; - CacheSearch search; g_return_val_if_fail (GTK_IS_ICON_THEME (icon_theme), FALSE); @@ -1369,16 +1348,12 @@ gtk_icon_theme_has_icon (GtkIconTheme *icon_theme, ensure_valid_themes (icon_theme); - search.icon_name = icon_name; - search.found = FALSE; - - for (l = priv->themes; l; l = l->next) + for (l = priv->dir_mtimes; l; l = l->next) { - IconTheme *theme = (IconTheme *)l->data; - - g_hash_table_foreach (theme->icon_caches, cache_has_icon, &search); - - if (search.found) + IconThemeDirMtime *dir_mtime = l->data; + GtkIconCache *cache = dir_mtime->cache; + + if (cache && _gtk_icon_cache_has_icon (cache, icon_name)) return TRUE; } @@ -1665,9 +1640,6 @@ theme_destroy (IconTheme *theme) g_list_foreach (theme->dirs, (GFunc)theme_dir_destroy, NULL); g_list_free (theme->dirs); - if (theme->icon_caches) - g_hash_table_destroy (theme->icon_caches); - g_free (theme); } @@ -2116,7 +2088,6 @@ theme_subdir_load (GtkIconTheme *icon_theme, int threshold; char *full_dir; GError *error = NULL; - GtkIconCache *cache; IconThemeDirMtime *dir_mtime; size = g_key_file_get_integer (theme_file, subdir, "Size", &error); @@ -2187,21 +2158,14 @@ theme_subdir_load (GtkIconTheme *icon_theme, full_dir = g_build_filename (dir_mtime->dir, subdir, NULL); /* First, see if we have a cache for the directory */ - if (!theme->icon_caches) - theme->icon_caches = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, (GDestroyNotify)free_cache); - - if (!g_hash_table_lookup_extended (theme->icon_caches, dir_mtime->dir, - NULL, (gpointer)&cache)) - { - /* This will return NULL if the cache doesn't exist or is outdated */ - cache = _gtk_icon_cache_new_for_path (dir_mtime->dir); - - g_hash_table_insert (theme->icon_caches, g_strdup (dir_mtime->dir), cache); - } - - if (cache != NULL || g_file_test (full_dir, G_FILE_TEST_IS_DIR)) + if (dir_mtime->cache != NULL || g_file_test (full_dir, G_FILE_TEST_IS_DIR)) { + if (dir_mtime->cache == NULL) + { + /* This will return NULL if the cache doesn't exist or is outdated */ + dir_mtime->cache = _gtk_icon_cache_new_for_path (dir_mtime->dir); + } + dir = g_new (IconThemeDir, 1); dir->type = type; dir->context = context; @@ -2212,8 +2176,8 @@ theme_subdir_load (GtkIconTheme *icon_theme, dir->dir = full_dir; dir->icon_data = NULL; dir->subdir = g_strdup (subdir); - if (cache != NULL) - dir->cache = _gtk_icon_cache_ref (cache); + if (dir_mtime->cache != NULL) + dir->cache = _gtk_icon_cache_ref (dir_mtime->cache); else { dir->cache = NULL;