GNOME Bugzilla – Bug 525845
right-click menu action item icons do not appear if directory+icon is used (Hardy Heron beta)
Last modified: 2009-11-25 12:47:04 UTC
Please describe the problem: When adding actions in the Nautilus Action Configuration tool, if Icon's full path and file are listed, icon will not display on right-click menu. However, if a stock icon is selected (by using pull-down selection box), works fine. Steps to reproduce: 1. Add a new action for "Terminal" 2. Select icon "/usr/share/pixmaps/gnome-terminal.png" or any of the other terminal icons available on my system. 3. Icon displays fine in both EDIT ACTION dialog and in NAUTILUS ACTIONS list screen. 4. Close list and even killall -HUP nautilus (for giggles) and Terminal displays in the right-click menu with no icon. All other functionality is fine. Actual results: Terminal displays on the right-click menu without the selected icon Expected results: Icon should be displayed with application Does this happen every time? Yep Other information: Running new Ubuntu Hardy Heron 8.04 beta so may be specific to this version, Nautilus 1:2.22.1, Compositing enabled (compiz)--only remotely relevant as I saw icons reappear elsewhere when I enabled this new setting in Gconf. Thanks for this great add-on!
I confirm this. Since I upgraded to Hardy Heron, icons are no more displayed.
Same here, since Hardy Heron upgrade, same result, no icon displayed.
Confirming here aswell. I'm running Hardy Heron Final updated as of today and installed with clean install.
Hi all, Well, maybe I'm wrong, but why this problem associated to 'nautilus-actions' ? Isn't a 'nautilus' problem ? Correct me if I'm in a bad way ... A++
*** Bug 534622 has been marked as a duplicate of this bug. ***
I have found that if you place icons in this path /home/<username>/.icons/gnome/22x22/actions and they are .png then the nautilus right click menu will show the correct icons after restarting nautilus. The trick is that the nautilus action edit menu will [B]not[/B] show the icons as it expects them to be in the current active themes directory path. You could put them there too but that would be a pain to maintain.
Hi Kyle, On my side it doesn't work ... I'm currently running Intrepid Ibex. A++
Hi Bob - thats odd - so am I 8.10 64 bit Did you put the icon name in with out the .png extension? And what is your current theme?
Bob Try making "gnome" the current icon theme and see if nautilus picks up the app icons.
Kyle, I have just copied icons with extension in /home/<username>/.icons/gnome/22x22/actions Does I have made a mistake ? A++
No thats the same as me. The icons must be .png extension.
Then, it doesn't work at my side :-( A++
Ok try this - set your theme to Gnome As root or via sudo go to /usr/share/icons/gnome/16x16/status make a backup copy of dialog-warning.png. Copy in a .png image of say the firefox icon and rename it as dialog-warning.png Go to the Nautilus actions dialog and create firefox as a menu item. Sets it icon to warning - the warning icon should now be Firefox. This will show how the icons are resolved. then we can move on if this works. I went on a search to try and find where the icons are stored - gnome seems to have a preset number for the dropdown and searches thru looking for icons named gtk-xxxxxx.png and for custom icons it will look in the ~/.icon path. Let me know
Hi, Just as a personal remainder : - Ubuntu Hardy ships with Gnome 2.22 - Ubuntu Intrepid targets Gnome 2.24 Obviously, this problem comes from the way icons are resolved in latest versions of Gnome. I will work on that... It is a possibility that I have to remove the "browse anywhere" button, replacing it with a "browse only on theme places"... Stay tuned ;-) Regards Pierre
That is correct. Something changed between 2.20 and 2.22 that broke the code. Great that you've started working on nautilus-actions.
After a bit of search, I do confirm the change. Somewhere between 2.20 and 2.22 releases, Nautilus has replaced a path-based icon lookup with a theme-based one when building its contextual menu actions (cf. libprivate/nautilus-ui-utilities.c). As a matter of fact, Gnome has decided to apply free desktop specifications (cf. http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html) when searching for the icons. So : 1. we cannot really consider the Nautilus change as a regression, but rather as a step toward common desktop standards, even if this breaks some (small) things in nautilus-actions. 2. I confirm the target I only supposed yesterday : replacing the "browse anywhere" button by a "browse themed icons" one. I'm pretty sure that icons that display fine today in contextual menus will continue to do this after the modification. But I'm afraid that this will slightly break the display of icons in nautilus-actions-config when these icons are not in standard places. Sorry for this inconvenience. So, where should one put his nautilus-actions icons ? Icons are searched by name (_not_ pathname) in a set of standard places, depending of the user's current theme. I'm not in front of my dev workstation, but this night, these standard places were something like : ~/.icons ~/.local/share/icons /usr/share/pixmaps /usr/share/local/pixmaps [+ one another I don't remember] These places may depend of your own distribution (I use Fedora 10). ~/.icons is said to be more or less deprecated these days, though yet widely used. Free desktop standards recommend ~/.local/share/icons, and I'd personnaly choose an "Actions" context. For distribution packagers who wish install some default actions with nautilus-actions, I also will add a nautilus-actions dedicated directory, e.g. /usr/share/nautilus-actions/icons, and add this directory to icon search places. But as a /usr hierarchy, this directory will not be writable by users, so falling back to the previous ~/.local/share/icons ;-) Ahh.. A last word for Kile. Yes, gtk-xxxxx icons work, not because of their name, but because of their place. gtk-xxx icons are standard themed icons, named with this gtk- prefix only as a remember they are used for standard gtk stock items. Last thing to do : write this icon chooser...... Regards Pierre
*** Bug 495945 has been marked as a duplicate of this bug. ***
Just wanted to confirm (Ubuntu Jaunty/Linux Mint Gloria i686, up-to-date). Kyle's workaround worked well for me, as long as <themename> in /home/<username>/.icons/<themename>/22x22/actions was the same name as the theme I was currently using (installed to /usr/share/icons). No idea why it needs the 22x22 version when the previews are 16x16. But thanks regardless!
Humm I might have badly interpreted the situation :( See http://mail.gnome.org/archives/nautilus-list/2009-August/msg00015.html To be continued...
Redirecting to Nautilus.
Created attachment 145897 [details] [review] Accept icons addressed by path Hi As stated above, I think that it is not the intention of fds to prevent users to address their icons by their path in some situations.. I so propose the attached patch, tested against gnome-2-28 and master branches. Regards Pierre
Comment on attachment 145897 [details] [review] Accept icons addressed by path >diff --git a/libnautilus-private/nautilus-icon-info.c b/libnautilus-private/nautilus-icon-info.c >index f1ddd7c..8e2b0fb 100644 >--- a/libnautilus-private/nautilus-icon-info.c >+++ b/libnautilus-private/nautilus-icon-info.c >@@ -32,7 +32,7 @@ struct _NautilusIconInfo > gboolean sole_owner; > guint64 last_use_time; > GdkPixbuf *pixbuf; >- >+ > gboolean got_embedded_rect; > GdkRectangle embedded_rect; > gint n_attach_points; >@@ -71,9 +71,9 @@ pixbuf_toggle_notify (gpointer info, > gboolean is_last_ref) > { > NautilusIconInfo *icon = info; >- >+ > if (is_last_ref) { >- icon->sole_owner = TRUE; >+ icon->sole_owner = TRUE; > g_object_remove_toggle_ref (object, > pixbuf_toggle_notify, > info); >@@ -125,8 +125,8 @@ nautilus_icon_info_new_for_pixbuf (GdkPixbuf *pixbuf) > > if (pixbuf) { > icon->pixbuf = g_object_ref (pixbuf); >- } >- >+ } >+ > return icon; > } > >@@ -162,7 +162,7 @@ nautilus_icon_info_new_for_icon_info (GtkIconInfo *icon_info) > } > icon->icon_name = basename; > } >- >+ > return icon; > } > >@@ -177,8 +177,14 @@ typedef struct { > int size; > } ThemedIconKey; > >+typedef struct { >+ char *filename; >+ int size; >+} FileIconKey; >+ > static GHashTable *loadable_icon_cache = NULL; > static GHashTable *themed_icon_cache = NULL; >+static GHashTable *file_icon_cache = NULL; > static guint reap_cache_timeout = 0; > > #define NSEC_PER_SEC ((guint64)1000000000L) >@@ -202,7 +208,7 @@ reap_old_icon (gpointer key, > *reapable_icons_left = TRUE; > } > } >- >+ > return FALSE; > } > >@@ -214,19 +220,25 @@ reap_cache (gpointer data) > reapable_icons_left = TRUE; > > time_now = g_thread_gettime (); >- >+ > if (loadable_icon_cache) { > g_hash_table_foreach_remove (loadable_icon_cache, > reap_old_icon, > &reapable_icons_left); > } >- >+ > if (themed_icon_cache) { > g_hash_table_foreach_remove (themed_icon_cache, > reap_old_icon, > &reapable_icons_left); > } >- >+ >+ if (file_icon_cache) { >+ g_hash_table_foreach_remove (file_icon_cache, >+ reap_old_icon, >+ &reapable_icons_left); >+ } >+ > if (reapable_icons_left) { > return TRUE; > } else { >@@ -251,10 +263,14 @@ nautilus_icon_info_clear_caches (void) > if (loadable_icon_cache) { > g_hash_table_remove_all (loadable_icon_cache); > } >- >+ > if (themed_icon_cache) { > g_hash_table_remove_all (themed_icon_cache); > } >+ >+ if (file_icon_cache) { >+ g_hash_table_remove_all (file_icon_cache); >+ } > } > > static guint >@@ -323,93 +339,201 @@ themed_icon_key_free (ThemedIconKey *key) > g_slice_free (ThemedIconKey, key); > } > >-NautilusIconInfo * >-nautilus_icon_info_lookup (GIcon *icon, >- int size) >+static guint >+file_icon_key_hash (FileIconKey *key) >+{ >+ return g_str_hash (key->filename) ^ key->size; >+} >+ >+static gboolean >+file_icon_key_equal (const FileIconKey *a, >+ const FileIconKey *b) >+{ >+ return a->size == b->size && >+ g_str_equal (a->filename, b->filename); >+} >+ >+static FileIconKey * >+file_icon_key_new (const char *filename, int size) >+{ >+ FileIconKey *key; >+ >+ key = g_slice_new (FileIconKey); >+ key->filename = g_strdup (filename); >+ key->size = size; >+ >+ return key; >+} >+ >+static void >+file_icon_key_free (FileIconKey *key) >+{ >+ g_free (key->filename); >+ g_slice_free (FileIconKey, key); >+} >+ >+static NautilusIconInfo * >+icon_info_file_lookup (GIcon *icon, >+ int size) > { > NautilusIconInfo *icon_info; > GdkPixbuf *pixbuf; >- >- if (G_IS_LOADABLE_ICON (icon)) { >- LoadableIconKey lookup_key; >- LoadableIconKey *key; >- GInputStream *stream; >- >- if (loadable_icon_cache == NULL) { >- loadable_icon_cache = >- g_hash_table_new_full ((GHashFunc)loadable_icon_key_hash, >- (GEqualFunc)loadable_icon_key_equal, >- (GDestroyNotify) loadable_icon_key_free, >- (GDestroyNotify) g_object_unref); >- } >- >- lookup_key.icon = icon; >- lookup_key.size = size; >+ FileIconKey lookup_key; >+ FileIconKey *key; >+ GError *error = NULL; >+ GFile *file; >+ gchar *name; >+ >+ if (file_icon_cache == NULL) { >+ file_icon_cache = >+ g_hash_table_new_full ((GHashFunc) file_icon_key_hash, >+ (GEqualFunc) file_icon_key_equal, >+ (GDestroyNotify) file_icon_key_free, >+ (GDestroyNotify) g_object_unref); >+ } > >- icon_info = g_hash_table_lookup (loadable_icon_cache, &lookup_key); >- if (icon_info) { >- return g_object_ref (icon_info); >- } >+ file = g_file_icon_get_file (G_FILE_ICON (icon)); >+ name = g_file_get_path (file); >+ g_object_unref (file); >+ >+ lookup_key.filename = (char *) name; >+ lookup_key.size = size; >+ >+ icon_info = g_hash_table_lookup (file_icon_cache, &lookup_key); >+ if (icon_info) { >+ return g_object_ref (icon_info); >+ } > >+ pixbuf = gdk_pixbuf_new_from_file_at_size (name, size, size, &error); >+ if (error) { >+ g_warning ("error=%s", error->message); >+ g_error_free (error); >+ error = NULL; > pixbuf = NULL; >- stream = g_loadable_icon_load (G_LOADABLE_ICON (icon), >- size, >- NULL, NULL, NULL); >- if (stream) { >- pixbuf = eel_gdk_pixbuf_load_from_stream_at_size (stream, size); >- g_object_unref (stream); >- } >+ } > >+ if (pixbuf) { > icon_info = nautilus_icon_info_new_for_pixbuf (pixbuf); > >- key = loadable_icon_key_new (icon, size); >- g_hash_table_insert (loadable_icon_cache, key, icon_info); >+ key = file_icon_key_new ((const char *) name, size); >+ g_hash_table_insert (file_icon_cache, key, icon_info); > >+ g_free( name ); > return g_object_ref (icon_info); >- } else if (G_IS_THEMED_ICON (icon)) { >- const char * const *names; >- ThemedIconKey lookup_key; >- ThemedIconKey *key; >- GtkIconTheme *icon_theme; >- GtkIconInfo *gtkicon_info; >- const char *filename; >- >- if (themed_icon_cache == NULL) { >- themed_icon_cache = >- g_hash_table_new_full ((GHashFunc)themed_icon_key_hash, >- (GEqualFunc)themed_icon_key_equal, >- (GDestroyNotify) themed_icon_key_free, >- (GDestroyNotify) g_object_unref); >- } >- >- names = g_themed_icon_get_names (G_THEMED_ICON (icon)); >+ } > >- icon_theme = gtk_icon_theme_get_default (); >- gtkicon_info = gtk_icon_theme_choose_icon (icon_theme, (const char **)names, size, 0); >+ g_free( name ); >+ return NULL; >+} > >- if (gtkicon_info == NULL) { >- return nautilus_icon_info_new_for_pixbuf (NULL); >- } >+static NautilusIconInfo * >+icon_info_loadable_lookup (GIcon *icon, >+ int size) >+{ >+ NautilusIconInfo *icon_info; >+ GdkPixbuf *pixbuf; >+ LoadableIconKey lookup_key; >+ LoadableIconKey *key; >+ GInputStream *stream; >+ >+ if (loadable_icon_cache == NULL) { >+ loadable_icon_cache = >+ g_hash_table_new_full ((GHashFunc)loadable_icon_key_hash, >+ (GEqualFunc)loadable_icon_key_equal, >+ (GDestroyNotify) loadable_icon_key_free, >+ (GDestroyNotify) g_object_unref); >+ } >+ >+ lookup_key.icon = icon; >+ lookup_key.size = size; >+ >+ icon_info = g_hash_table_lookup (loadable_icon_cache, &lookup_key); >+ if (icon_info) { >+ return g_object_ref (icon_info); >+ } > >- filename = gtk_icon_info_get_filename (gtkicon_info); >+ pixbuf = NULL; >+ stream = g_loadable_icon_load (G_LOADABLE_ICON (icon), >+ size, >+ NULL, NULL, NULL); >+ if (stream) { >+ pixbuf = eel_gdk_pixbuf_load_from_stream_at_size (stream, size); >+ g_object_unref (stream); >+ } > >- lookup_key.filename = (char *)filename; >- lookup_key.size = size; >+ icon_info = nautilus_icon_info_new_for_pixbuf (pixbuf); > >- icon_info = g_hash_table_lookup (themed_icon_cache, &lookup_key); >- if (icon_info) { >- gtk_icon_info_free (gtkicon_info); >- return g_object_ref (icon_info); >- } >- >- icon_info = nautilus_icon_info_new_for_icon_info (gtkicon_info); >- >- key = themed_icon_key_new (filename, size); >- g_hash_table_insert (themed_icon_cache, key, icon_info); >+ key = loadable_icon_key_new (icon, size); >+ g_hash_table_insert (loadable_icon_cache, key, icon_info); > >- gtk_icon_info_free (gtkicon_info); >+ return g_object_ref (icon_info); >+} > >+static NautilusIconInfo * >+icon_info_themed_lookup (GIcon *icon, >+ int size) >+{ >+ NautilusIconInfo *icon_info; >+ const char * const *names; >+ ThemedIconKey lookup_key; >+ ThemedIconKey *key; >+ GtkIconTheme *icon_theme; >+ GtkIconInfo *gtkicon_info; >+ const char *filename; >+ >+ if (themed_icon_cache == NULL) { >+ themed_icon_cache = >+ g_hash_table_new_full ((GHashFunc)themed_icon_key_hash, >+ (GEqualFunc)themed_icon_key_equal, >+ (GDestroyNotify) themed_icon_key_free, >+ (GDestroyNotify) g_object_unref); >+ } >+ >+ names = g_themed_icon_get_names (G_THEMED_ICON (icon)); >+ >+ icon_theme = gtk_icon_theme_get_default (); >+ gtkicon_info = gtk_icon_theme_choose_icon (icon_theme, (const char **)names, size, 0); >+ >+ if (gtkicon_info == NULL) { >+ return nautilus_icon_info_new_for_pixbuf (NULL); >+ } >+ >+ filename = gtk_icon_info_get_filename (gtkicon_info); >+ >+ lookup_key.filename = (char *)filename; >+ lookup_key.size = size; >+ >+ icon_info = g_hash_table_lookup (themed_icon_cache, &lookup_key); >+ if (icon_info) { >+ gtk_icon_info_free (gtkicon_info); > return g_object_ref (icon_info); >+ } >+ >+ icon_info = nautilus_icon_info_new_for_icon_info (gtkicon_info); >+ >+ key = themed_icon_key_new (filename, size); >+ g_hash_table_insert (themed_icon_cache, key, icon_info); >+ >+ gtk_icon_info_free (gtkicon_info); >+ >+ return g_object_ref (icon_info); >+} >+ >+NautilusIconInfo * >+nautilus_icon_info_lookup (GIcon *icon, >+ int size) >+{ >+ NautilusIconInfo *icon_info; >+ >+ if (G_IS_FILE_ICON (icon)) { >+ icon_info = icon_info_file_lookup (icon, size); >+ >+ } else if (G_IS_LOADABLE_ICON (icon)) { >+ icon_info = icon_info_loadable_lookup (icon, size); >+ >+ } else if (G_IS_THEMED_ICON (icon)) { >+ icon_info = icon_info_themed_lookup (icon, size); >+ > } else { > GdkPixbuf *pixbuf; > GtkIconInfo *gtk_icon_info; >@@ -425,8 +549,10 @@ nautilus_icon_info_lookup (GIcon *icon, > pixbuf = NULL; > } > >- return nautilus_icon_info_new_for_pixbuf (pixbuf); >+ icon_info = nautilus_icon_info_new_for_pixbuf (pixbuf); > } >+ >+ return icon_info; > } > > NautilusIconInfo * >@@ -434,11 +560,29 @@ nautilus_icon_info_lookup_from_name (const char *name, > int size) > { > GIcon *icon; >+ GFile *icon_file; > NautilusIconInfo *info; >- >- icon = g_themed_icon_new (name); >- info = nautilus_icon_info_lookup (icon, size); >- g_object_unref (icon); >+ >+ info = NULL; >+ >+ if (g_str_has_prefix (name, "/")) { >+ icon_file = g_file_new_for_path (name); >+ icon = g_file_icon_new (icon_file); >+ g_object_unref (icon_file); >+ >+ } else { >+ icon = g_themed_icon_new (name); >+ } >+ >+ if (icon) { >+ info = nautilus_icon_info_lookup (icon, size); >+ g_object_unref (icon); >+ } >+ > return info; > } > >@@ -460,7 +604,7 @@ nautilus_icon_info_get_pixbuf_nodefault (NautilusIconInfo *icon) > icon); > } > } >- >+ > return res; > } > >@@ -481,8 +625,8 @@ nautilus_icon_info_get_pixbuf (NautilusIconInfo *icon) > nautilus_default_file_icon_width * 4, /* stride */ > NULL, /* don't destroy info */ > NULL); >- } >- >+ } >+ > return res; > } > >@@ -498,7 +642,7 @@ nautilus_icon_info_get_pixbuf_nodefault_at_size (NautilusIconInfo *icon, > > if (pixbuf == NULL) > return NULL; >- >+ > w = gdk_pixbuf_get_width (pixbuf); > h = gdk_pixbuf_get_height (pixbuf); > s = MAX (w, h); >@@ -572,7 +716,7 @@ nautilus_icon_info_get_used_name (NautilusIconInfo *icon) > > /* Return nominal icon size for given zoom level. > * @zoom_level: zoom level for which to find matching icon size. >- * >+ * > * Return value: icon size between NAUTILUS_ICON_SIZE_SMALLEST and > * NAUTILUS_ICON_SIZE_LARGEST, inclusive. > */ >@@ -659,7 +803,7 @@ nautilus_get_icon_size_for_stock_size (GtkIconSize size) > > if (gtk_icon_size_lookup (size, &w, &h)) { > return MAX (w, h); >- } >+ } > return NAUTILUS_ZOOM_LEVEL_STANDARD; > } > >@@ -677,6 +821,6 @@ nautilus_icon_get_emblem_size_for_icon_size (guint size) > return 16; > if (size >= 16) > return 12; >- >+ > return 0; /* no emblems for smaller sizes */ > }
Created attachment 145899 [details] [review] Accept icons addressed by path [2] Remove second g_object_unref (file).
Patch has been committed this morning by Alexander in master and gnome-2-28 branches.