[Nautilus-list] Icon directory contents caching
- From: Alex Larsson <alexl redhat com>
- To: <nautilus-list lists eazel com>
- Subject: [Nautilus-list] Icon directory contents caching
- Date: Fri, 5 Oct 2001 22:49:09 -0400 (EDT)
Here is a first rough cut at removing all the stats that the icon-factory
does.
There are a couple of issues.
First of all, where it used to use gnome_vfs_icon_path_from_filename() i
now load it manually. This function looks at the files installed in the
gnome-prefix. It now uses the hardcoded /usr, but it really should use the
gnome-libs prefix, or otherwise the nautilus prefix.
There is a small change in behaviour. When it can't find an icon in the
current or default theme, it used to look for icons in the global dir
/usr/share/pixmap and /usr/share/pixmap/$theme_name. Now it only looks in
/usr/share/pixmap. Is this a problem? I thought the original behaviour was
sort of strange.
I didn't change the code for the theme_is_in_user_directory case. Partly
because of laziness, but partly because that code seems kind of broken.
It always seems to read the default icons from the user directory if
theme_is_in_user_directory, ignoring default_theme_is_in_user_directory.
It could be made to work with the cache, simplifying the code, if
fill_theme_icon_dir_cache() took an theme_is_in_user_directory argument
and fill_default_icon_dir_cache() took a
default_theme_is_in_user_directory argument.
Here is the patch:
Index: nautilus-icon-factory.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-icon-factory.c,v
retrieving revision 1.230
diff -u -p -r1.230 nautilus-icon-factory.c
--- nautilus-icon-factory.c 2001/10/05 23:30:27 1.230
+++ nautilus-icon-factory.c 2001/10/06 02:36:37
@@ -64,6 +64,8 @@
#include <librsvg/rsvg.h>
#include <stdio.h>
#include <string.h>
+#include <sys/types.h>
+#include <dirent.h>
/* List of suffixes to search when looking for an icon file. */
static const char *icon_file_name_suffixes[] =
@@ -888,13 +890,190 @@ get_icon_name_for_file (NautilusFile *fi
}
}
+typedef struct {
+ char *directory;
+ char **files;
+} IconDirCache;
+
+static void
+icon_dir_cache_free (IconDirCache *cache)
+{
+ char **file;
+
+ g_free (cache->directory);
+ file = cache->files;;
+ while (*file) {
+ g_free (*file);
+ file++;
+ }
+ g_free (cache->files);
+
+ g_free (cache);
+}
+
+static gboolean
+icon_dir_cache_contains (IconDirCache *cache, char *name)
+{
+ char **file;
+
+ file = cache->files;
+
+ while (*file != NULL) {
+ if (strcmp (*file, name) == 0) {
+ return TRUE;
+ }
+ file++;
+ }
+
+ return FALSE;
+}
+
+static IconDirCache *
+icon_dir_cache_new (char *dir_name)
+{
+ GPtrArray *names;
+ DIR *dir;
+ struct dirent *dirent;
+ IconDirCache *cache;
+
+ cache = g_new (IconDirCache, 1);
+ cache->directory = g_strdup (dir_name);
+
+ names = g_ptr_array_new ();
+
+ dir = opendir(dir_name);
+
+ if (dir) {
+ while ((dirent = readdir (dir)) != NULL) {
+ g_ptr_array_add (names, g_strdup (dirent->d_name));
+ }
+ closedir (dir);
+ }
+ g_ptr_array_add (names, NULL);
+
+ cache->files = (char **) names->pdata;
+ g_ptr_array_free (names, FALSE);
+
+ return cache;
+}
+
+static char *cached_theme = NULL;
+static IconDirCache *themed_icon_dir_cache = NULL;
+static IconDirCache *default_icon_dir_cache = NULL;
+static GList *global_icon_dir_caches = NULL;
+
+static void
+invalidate_icon_dir_caches (void)
+{
+ GList *l;
+ IconDirCache *cache;
+
+ g_free (cached_theme);
+ cached_theme = NULL;
+ if (themed_icon_dir_cache) {
+ icon_dir_cache_free (themed_icon_dir_cache);
+ themed_icon_dir_cache = NULL;
+ }
+
+ if (default_icon_dir_cache) {
+ icon_dir_cache_free (default_icon_dir_cache);
+ default_icon_dir_cache = NULL;
+ }
+
+ l = global_icon_dir_caches;
+ while (l) {
+ cache = l->data;
+ icon_dir_cache_free (cache);
+ l = l->next;
+ }
+ g_list_free (global_icon_dir_caches);
+ global_icon_dir_caches = NULL;
+}
+
+static void
+fill_theme_icon_dir_cache (const char *theme)
+{
+ char *pixmap_dir;
+ char *theme_dir;
+
+ if (cached_theme && strcmp (theme, cached_theme) == 0) {
+ return;
+ }
+
+ /* Free old cached data */
+ g_free (cached_theme);
+ if (themed_icon_dir_cache) {
+ icon_dir_cache_free (themed_icon_dir_cache);
+ }
+
+ pixmap_dir = nautilus_get_pixmap_directory ();
+ theme_dir = nautilus_make_path (pixmap_dir, theme);
+
+ cached_theme = g_strdup (theme);
+ themed_icon_dir_cache = icon_dir_cache_new (theme_dir);
+
+ g_free (theme_dir);
+ g_free (pixmap_dir);
+
+}
+
+static void
+fill_default_icon_dir_cache (void)
+{
+ char *pixmap_dir;
+
+ if (default_icon_dir_cache != NULL) {
+ return;
+ }
+
+ pixmap_dir = nautilus_get_pixmap_directory ();
+ default_icon_dir_cache = icon_dir_cache_new (pixmap_dir);
+ g_free (pixmap_dir);
+}
+
+static void
+fill_global_icon_dir_caches (void)
+{
+ const char *gnome_var;
+ char *dirname;
+ char **paths, **temp_paths;
+ IconDirCache *cache;
+
+ if (global_icon_dir_caches != NULL) {
+ return;
+ }
+
+ gnome_var = g_getenv ("GNOME_PATH");
+
+ if (gnome_var == NULL) {
+ gnome_var = "/usr"; /* FIXME: should be NAUTILUS_PREFIX or better, the gnome prefix? */
+ }
+
+ paths = g_strsplit (gnome_var, ":", 0);
+
+ for (temp_paths = paths; *temp_paths != NULL; temp_paths++) {
+ dirname = g_strconcat (*temp_paths, "/share/pixmaps", NULL);
+ cache = icon_dir_cache_new (dirname);
+ global_icon_dir_caches = g_list_append (global_icon_dir_caches, cache);
+ g_free (dirname);
+ }
+
+ g_strfreev (paths);
+}
+
+
+
static char *
make_full_icon_path (const char *path,
const char *suffix,
+ const char *theme,
gboolean theme_is_in_user_directory)
{
char *partial_path, *full_path;
char *user_directory, *themes_directory;
+ char *themed_icon_name;
+ IconDirCache *cache;
+ GList *l;
partial_path = g_strconcat (path, suffix, NULL);
@@ -904,21 +1083,50 @@ make_full_icon_path (const char *path,
/* Build a path for this icon, depending on the theme_is_in_user_directory boolean. */
if (theme_is_in_user_directory) {
+ if (theme == NULL) {
+ themed_icon_name = g_strdup (partial_path);
+ } else {
+ themed_icon_name = g_strconcat (theme, "/", partial_path, NULL);
+ }
+
user_directory = nautilus_get_user_directory ();
themes_directory = nautilus_make_path (user_directory, "themes");
- full_path = nautilus_make_path (themes_directory, partial_path);
+ full_path = nautilus_make_path (themes_directory, themed_icon_name);
g_free (user_directory);
g_free (themes_directory);
+ g_free (themed_icon_name);
if (!g_file_exists (full_path)) {
g_free (full_path);
full_path = NULL;
}
} else {
- full_path = nautilus_pixmap_file (partial_path);
+ if (theme != NULL) {
+ fill_theme_icon_dir_cache (theme);
+ cache = themed_icon_dir_cache;
+ } else {
+ fill_default_icon_dir_cache ();
+ cache = default_icon_dir_cache;
+ }
+
+ full_path = NULL;
+ if (icon_dir_cache_contains (cache, partial_path)) {
+ full_path = nautilus_make_path (cache->directory, partial_path);
+ }
}
-
+
+ /* Didn't find the icon in the current or default theme, lets look for a global icon */
if (full_path == NULL) {
- full_path = gnome_vfs_icon_path_from_filename (partial_path);
+ fill_global_icon_dir_caches ();
+
+ l = global_icon_dir_caches;
+ while (l) {
+ cache = l->data;
+ if (icon_dir_cache_contains (cache, partial_path)) {
+ full_path = nautilus_make_path (cache->directory, partial_path);
+ break;
+ }
+ l = l->next;
+ }
}
g_free (partial_path);
@@ -969,7 +1177,7 @@ get_themed_icon_file_path (const char *t
{
guint i;
gboolean include_size;
- char *themed_icon_name, *partial_path, *path, *aa_path, *xml_path;
+ char *partial_path, *path, *aa_path, *xml_path;
xmlDocPtr doc;
xmlNodePtr node;
char *size_as_string, *property;
@@ -979,12 +1187,6 @@ get_themed_icon_file_path (const char *t
g_assert (icon_name != NULL);
- if (theme_name == NULL || icon_name[0] == '/') {
- themed_icon_name = g_strdup (icon_name);
- } else {
- themed_icon_name = g_strconcat (theme_name, "/", icon_name, NULL);
- }
-
include_size = icon_size != NAUTILUS_ICON_SIZE_STANDARD;
factory = get_icon_factory ();
@@ -993,10 +1195,10 @@ get_themed_icon_file_path (const char *t
if (include_size && strcasecmp (icon_file_name_suffixes[i], ".svg") != 0) {
/* Build a path for this icon. */
partial_path = g_strdup_printf ("%s-%u",
- themed_icon_name,
+ icon_name,
icon_size);
} else {
- partial_path = g_strdup (themed_icon_name);
+ partial_path = g_strdup (icon_name);
}
/* if we're in anti-aliased mode, try for an optimized one first */
@@ -1004,6 +1206,7 @@ get_themed_icon_file_path (const char *t
aa_path = g_strconcat (partial_path, "-aa", NULL);
path = make_full_icon_path (aa_path,
icon_file_name_suffixes[i],
+ theme_name,
theme_is_in_user_directory);
g_free (aa_path);
@@ -1019,6 +1222,7 @@ get_themed_icon_file_path (const char *t
path = make_full_icon_path (partial_path,
icon_file_name_suffixes[i],
+ theme_name,
theme_is_in_user_directory);
g_free (partial_path);
@@ -1035,8 +1239,9 @@ get_themed_icon_file_path (const char *t
if (path != NULL && details != NULL) {
memset (&details->text_rect, 0, sizeof (details->text_rect));
- xml_path = make_full_icon_path (themed_icon_name,
+ xml_path = make_full_icon_path (icon_name,
".xml",
+ theme_name,
theme_is_in_user_directory);
doc = xmlParseFile (xml_path);
@@ -1104,7 +1309,6 @@ get_themed_icon_file_path (const char *t
path = NULL;
}
}
- g_free (themed_icon_name);
return path;
}
@@ -1206,6 +1410,8 @@ icon_theme_changed_callback (gpointer us
load_thumbnail_frames (get_icon_factory ());
g_free (theme_preference);
g_free (icon_theme);
+
+ invalidate_icon_dir_caches ();
}
static void
/ Alex
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]