diff --git a/gtk/gtkicontheme.c b/gtk/gtkicontheme.c index 6340186fca..517a0f7819 100644 --- a/gtk/gtkicontheme.c +++ b/gtk/gtkicontheme.c @@ -130,10 +130,35 @@ struct _GtkStringSet { int used_in_chunk; }; +#ifdef G_ENABLE_DEBUG +static void +dump_string_set (GtkStringSet *set) +{ + GtkStringSetChunk *chunk = set->chunks; + unsigned int n_chunks = 0; + GHashTableIter iter; + gpointer key; + + while (chunk) + { + n_chunks++; + chunk = chunk->next; + } + g_print ("%u strings, %u chunks\n", g_hash_table_size (set->hash), n_chunks); + + g_hash_table_iter_init (&iter, set->hash); + while (g_hash_table_iter_next (&iter, &key, NULL)) + { + char *string = key; + g_print ("%s\n", string); + } +} +#endif + static void gtk_string_set_init (GtkStringSet *set) { - set->hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); + set->hash = g_hash_table_new (g_str_hash, g_str_equal); set->chunks = NULL; set->used_in_chunk = STRING_SET_CHUNK_SIZE; /* To trigger a grow directly */ } @@ -306,6 +331,8 @@ struct _GtkIconTheme GtkIconPaintable *lru_cache[LRU_CACHE_SIZE]; /* Protected by icon_cache lock */ int lru_cache_current; /* Protected by icon_cache lock */ + GtkStringSet icons; + char *current_theme; char **search_path; char **resource_path; @@ -409,7 +436,6 @@ typedef struct GArray *dir_sizes; /* IconThemeDirSize */ GArray *dirs; /* IconThemeDir */ - GtkStringSet icons; } IconTheme; typedef struct @@ -465,8 +491,6 @@ static GtkIconPaintable *theme_lookup_icon (IconTheme *the int size, int scale, gboolean allow_svg); -static gboolean theme_has_icon (IconTheme *theme, - const char *icon_name); static void theme_subdir_load (GtkIconTheme *self, IconTheme *theme, GKeyFile *theme_file, @@ -1358,6 +1382,7 @@ blow_themes (GtkIconTheme *self) g_list_free_full (self->themes, (GDestroyNotify) theme_destroy); g_array_set_size (self->dir_mtimes, 0); g_hash_table_destroy (self->unthemed_icons); + gtk_string_set_destroy (&self->icons); } self->themes = NULL; self->unthemed_icons = NULL; @@ -1939,6 +1964,8 @@ load_themes (GtkIconTheme *self) GStatBuf stat_buf; int j; + gtk_string_set_init (&self->icons); + if (self->current_theme) insert_theme (self, self->current_theme); @@ -2014,6 +2041,8 @@ load_themes (GtkIconTheme *self) } gdk_debug_message ("%s", s->str); g_string_free (s, TRUE); + + dump_string_set (&self->icons); } #endif } @@ -2159,10 +2188,13 @@ real_choose_icon (GtkIconTheme *self, theme = l->data; for (i = 0; icon_names[i] && icon_name_is_symbolic (icon_names[i], -1); i++) { - icon_name = icon_names[i]; - icon = theme_lookup_icon (theme, icon_name, size, scale, self->pixbuf_supports_svg); - if (icon) - goto out; + icon_name = gtk_string_set_lookup (&self->icons, icon_names[i]); + if (icon_name) + { + icon = theme_lookup_icon (theme, icon_name, size, scale, self->pixbuf_supports_svg); + if (icon) + goto out; + } } } @@ -2172,10 +2204,13 @@ real_choose_icon (GtkIconTheme *self, for (i = 0; icon_names[i]; i++) { - icon_name = icon_names[i]; - icon = theme_lookup_icon (theme, icon_name, size, scale, self->pixbuf_supports_svg); - if (icon) - goto out; + icon_name = gtk_string_set_lookup (&self->icons, icon_names[i]); + if (icon_name) + { + icon = theme_lookup_icon (theme, icon_name, size, scale, self->pixbuf_supports_svg); + if (icon) + goto out; + } } } @@ -2556,7 +2591,6 @@ gboolean gtk_icon_theme_has_icon (GtkIconTheme *self, const char *icon_name) { - GList *l; gboolean res = FALSE; g_return_val_if_fail (GTK_IS_ICON_THEME (self), FALSE); @@ -2566,13 +2600,10 @@ gtk_icon_theme_has_icon (GtkIconTheme *self, ensure_valid_themes (self, FALSE); - for (l = self->themes; l; l = l->next) + if (gtk_string_set_lookup (&self->icons, icon_name) != NULL) { - if (theme_has_icon (l->data, icon_name)) - { - res = TRUE; - goto out; - } + res = TRUE; + goto out; } out: @@ -2611,13 +2642,10 @@ gtk_icon_theme_has_gicon (GtkIconTheme *self, for (int i = 0; names[i]; i++) { - for (GList *l = self->themes; l; l = l->next) + if (gtk_string_set_lookup (&self->icons, names[i]) != NULL) { - if (theme_has_icon (l->data, names[i])) - { - res = TRUE; - goto out; - } + res = TRUE; + goto out; } } @@ -2663,6 +2691,7 @@ gtk_icon_theme_get_icon_sizes (GtkIconTheme *self, int i; GHashTable *sizes; int *result, *r; + const char *interned_icon_name; g_return_val_if_fail (GTK_IS_ICON_THEME (self), NULL); @@ -2672,10 +2701,11 @@ gtk_icon_theme_get_icon_sizes (GtkIconTheme *self, sizes = g_hash_table_new (g_direct_hash, g_direct_equal); + interned_icon_name = gtk_string_set_lookup (&self->icons, icon_name); + for (l = self->themes; l; l = l->next) { IconTheme *theme = l->data; - const char *interned_icon_name = gtk_string_set_lookup (&theme->icons, icon_name); for (i = 0; i < theme->dir_sizes->len; i++) { @@ -2732,25 +2762,15 @@ gtk_icon_theme_get_icon_names (GtkIconTheme *self) char **names; char *key; int i; - GList *l; gtk_icon_theme_lock (self); ensure_valid_themes (self, FALSE); icons = g_hash_table_new (g_str_hash, g_str_equal); + gtk_string_set_list (&self->icons, icons); - l = self->themes; - while (l != NULL) - { - IconTheme *theme = l->data; - gtk_string_set_list (&theme->icons, icons); - l = l->next; - } - - g_hash_table_foreach (self->unthemed_icons, - add_key_to_hash, - icons); + g_hash_table_foreach (self->unthemed_icons, add_key_to_hash, icons); names = g_new (char *, g_hash_table_size (icons) + 1); @@ -2809,7 +2829,6 @@ theme_new (const char *theme_name, theme->name = g_strdup (theme_name); theme->dir_sizes = g_array_new (FALSE, FALSE, sizeof (IconThemeDirSize)); theme->dirs = g_array_new (FALSE, FALSE, sizeof (IconThemeDir)); - gtk_string_set_init (&theme->icons); theme->display_name = g_key_file_get_locale_string (theme_file, "Icon Theme", "Name", NULL, NULL); @@ -2840,8 +2859,6 @@ theme_destroy (IconTheme *theme) theme_dir_destroy (&g_array_index (theme->dirs, IconThemeDir, i)); g_array_free (theme->dirs, TRUE); - gtk_string_set_destroy (&theme->icons); - g_free (theme); } @@ -3040,13 +3057,6 @@ theme_lookup_icon (IconTheme *theme, IconCacheFlag min_suffix; int i; - /* Its not uncommon with misses, so we do an early check which allows us do - * do a lot less work. - * We also intern the name so later hash lookups are faster. */ - icon_name = gtk_string_set_lookup (&theme->icons, icon_name); - if (icon_name == NULL) - return FALSE; - min_difference = G_MAXINT; min_dir_size = NULL; @@ -3106,13 +3116,6 @@ theme_lookup_icon (IconTheme *theme, return NULL; } -static gboolean -theme_has_icon (IconTheme *theme, - const char *icon_name) -{ - return gtk_string_set_lookup (&theme->icons, icon_name) != NULL; -} - static GHashTable * scan_directory (GtkIconTheme *self, char *full_dir,