[Xfce4-commits] <xfdesktop:master> Merge branch 'eric/icon-changes'

Eric Koegel noreply at xfce.org
Sun Sep 1 16:20:14 CEST 2013


Updating branch refs/heads/master
         to deed58cbb4fc984bd3bcfc5808533e21c57d1148 (commit)
       from 9599d57779735e28af0b497c784e7e9b0bf2b416 (commit)

commit deed58cbb4fc984bd3bcfc5808533e21c57d1148
Merge: 9599d57 9becad1
Author: Eric Koegel <eric.koegel at gmail.com>
Date:   Sun Sep 1 17:18:38 2013 +0300

    Merge branch 'eric/icon-changes'

commit 9becad1569798894bdae9beaffc9076338fed299
Author: Eric Koegel <eric.koegel at gmail.com>
Date:   Sun Sep 1 15:23:27 2013 +0300

    Don't call wnck_screen_force_update
    
    Remove the call to wnck_screen_force_update and let wnck initialize
    during the main idle loop. Also fix a couple memory leaks.

commit 3b18c3b222314c65789006477a2f0e5e6d9e78c3
Author: Eric Koegel <eric.koegel at gmail.com>
Date:   Fri Aug 30 15:01:53 2013 +0300

    Custom folder icons (Bug 8326)
    
    When showing thumbnails on the desktop, xfdesktop will search
    inside folder for semi-standard image files to use as the folder
    icon (folder.jpg, cover.jpg, albumart.jpg, & fanart.jpg).

commit 4c889999cb73b5f5f3224265641acb60e0cb7ecd
Author: Eric Koegel <eric.koegel at gmail.com>
Date:   Fri Aug 30 11:20:08 2013 +0300

    Monitor the gvfs directory
    
    Added a file monitor watching the gvfs directory since there's no
    other way to be notified of these events. Now when the user adds
    an emblem to a file and gvfs commits the change to the db, xfdesktop
    will update the icons to reflect this change. There is about a one
    minute delay from setting the emblem and gvfs changing the file.

commit dc9f86912900c7d6461b273953ae6fad6c00daed
Author: Eric Koegel <eric.koegel at gmail.com>
Date:   Mon Aug 26 10:17:37 2013 +0300

    Icon spacing
    
    Fix the spacing the between the icon pix and label. Also calculate
    the label radius once rather than all the time.

commit 104d482576b8538c9d2443d15817934876f16c8a
Author: Eric Koegel <eric.koegel at gmail.com>
Date:   Fri Apr 6 18:24:29 2012 +0300

    Unselect the desktop icon after activating it. (Bug #8640)

commit f606524d5d8b91c983c2412af291e6d4d6c66678
Author: Eric Koegel <eric.koegel at gmail.com>
Date:   Sun Aug 25 16:42:24 2013 +0300

    Icon stays in place when renamed (Bug 1678)

commit de26505ba425ca939241e0c51b860c5763850386
Author: Eric Koegel <eric.koegel at gmail.com>
Date:   Sun Aug 25 14:08:37 2013 +0300

    Better icon pixbuf caching
    
    With the inclusion of tooltip pixbuf previews the icon pixbuf would
    get recreated every time the tooltip pixbuf was generated. So now it
    will cache both the normal size icon pixbuf and the tooltip pixbuf.
    The pixbufs are stored in the base icon so that all the different
    icon types don't have to do the same redundant checks.

commit 21fe3ab4185b7eba72b5554f4645c8945be3da27
Author: Eric Koegel <eric.koegel at gmail.com>
Date:   Mon Aug 19 11:47:00 2013 +0300

    Check GFileInfo before trying to use it.

commit f6252759fcb4aa2e510237aa45c77b84bfab3cc4
Author: Eric Koegel <eric.koegel at gmail.com>
Date:   Sat Aug 17 15:47:21 2013 +0300

    Make the GIcon for file icons private

commit 2cdfde11b827b97576347c2eacb043780abc9415
Author: Eric Koegel <eric.koegel at gmail.com>
Date:   Mon Aug 12 16:26:58 2013 +0300

    Fill in the icon area better
    
    It bypasses the thumbnailer for svg icons so they look better.

commit bc48d533bd0dbaaad8d865bd6f26bc9c8f47e042
Author: Eric Koegel <eric.koegel at gmail.com>
Date:   Mon Aug 12 12:24:13 2013 +0300

    Use GIcons and add support for emblems on icons

commit e2af8b45c6bb1a7f18cd8ac36c072fd024cfa664
Author: Eric Koegel <eric.koegel at gmail.com>
Date:   Sun Aug 11 10:31:49 2013 +0300

    Align icon labels and allow them to be multi-line (Bug 8646)
    
    When thumbnails are turned on the icon labels can become unaligned with others
    in that row. There's also unused space in the icon's label area that is now
    used to display more of the text. Additionally, some effort was made to lower
    the number of times the icon redraws itself in response to expose events,
    especially during xfdesktop's startup.

 common/xfdesktop-common.h         |    6 +-
 src/xfce-desktop.c                |   91 ++++++------
 src/xfdesktop-file-icon-manager.c |  281 ++++++++++++++++++++++++++++++++----
 src/xfdesktop-file-icon.c         |  137 +++++++++++++++++-
 src/xfdesktop-file-icon.h         |   10 ++
 src/xfdesktop-file-utils.c        |  191 +++++++++++++++++--------
 src/xfdesktop-file-utils.h        |    7 +-
 src/xfdesktop-icon-view.c         |  187 +++++++++++++-----------
 src/xfdesktop-icon.c              |   85 ++++++++++-
 src/xfdesktop-icon.h              |   15 +-
 src/xfdesktop-regular-file-icon.c |  284 ++++++++++++++++++++-----------------
 src/xfdesktop-special-file-icon.c |  128 ++++++++++-------
 src/xfdesktop-volume-icon.c       |  118 ++++++++-------
 src/xfdesktop-window-icon.c       |   49 ++-----
 14 files changed, 1094 insertions(+), 495 deletions(-)

diff --git a/common/xfdesktop-common.h b/common/xfdesktop-common.h
index d95ec59..8e5947c 100644
--- a/common/xfdesktop-common.h
+++ b/common/xfdesktop-common.h
@@ -37,8 +37,7 @@
 #define DEFAULT_ICON_FONT_SIZE   12
 #define DEFAULT_ICON_SIZE        32
 #define ITHEME_FLAGS             (GTK_ICON_LOOKUP_USE_BUILTIN \
-                                  | GTK_ICON_LOOKUP_GENERIC_FALLBACK \
-                                  | GTK_ICON_LOOKUP_FORCE_SIZE)
+                                  | GTK_ICON_LOOKUP_GENERIC_FALLBACK)
 
 #define LIST_TEXT                "# xfce backdrop list"
 #define XFDESKTOP_SELECTION_FMT  "XFDESKTOP_SELECTION_%d"
@@ -65,7 +64,8 @@
   "time::*," \
   "thumbnail::*," \
   "trash::*," \
-  "unix::*"
+  "unix::*," \
+  "metadata::*"
 
 /**
  * Filesystem information namespaces queried for #GFileInfo * objects.
diff --git a/src/xfce-desktop.c b/src/xfce-desktop.c
index 70a326d..42712aa 100644
--- a/src/xfce-desktop.c
+++ b/src/xfce-desktop.c
@@ -316,6 +316,40 @@ set_real_root_window_pixmap(GdkScreen *gscreen,
 #endif
 }
 
+static GdkPixmap *
+create_bg_pixmap(GdkScreen *gscreen, gpointer user_data)
+{
+    XfceDesktop *desktop = user_data;
+    gint w, h;
+
+    TRACE("entering");
+
+    g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), NULL);
+
+    if(desktop->priv->workspaces == NULL)
+        return NULL;
+
+    w = gdk_screen_get_width(gscreen);
+    h = gdk_screen_get_height(gscreen);
+    gtk_widget_set_size_request(GTK_WIDGET(desktop), w, h);
+    gtk_window_resize(GTK_WINDOW(desktop), w, h);
+
+    if(desktop->priv->bg_pixmap)
+        g_object_unref(G_OBJECT(desktop->priv->bg_pixmap));
+    desktop->priv->bg_pixmap = gdk_pixmap_new(GDK_DRAWABLE(gtk_widget_get_window(GTK_WIDGET(desktop))),
+                                              w, h, -1);
+
+    if(!GDK_IS_PIXMAP(desktop->priv->bg_pixmap))
+        return NULL;
+
+    set_real_root_window_pixmap(desktop->priv->gscreen,
+                                desktop->priv->bg_pixmap);
+    gdk_window_set_back_pixmap(gtk_widget_get_window(GTK_WIDGET(desktop)),
+                               desktop->priv->bg_pixmap, FALSE);
+
+    return desktop->priv->bg_pixmap;
+}
+
 static void
 backdrop_changed_cb(XfceBackdrop *backdrop, gpointer user_data)
 {
@@ -332,7 +366,14 @@ backdrop_changed_cb(XfceBackdrop *backdrop, gpointer user_data)
     
     if(desktop->priv->updates_frozen || !gtk_widget_get_realized(GTK_WIDGET(desktop)))
         return;
-    
+
+    if(!GDK_IS_PIXMAP(pmap)) {
+        pmap = create_bg_pixmap(gscreen, desktop);
+
+        if(!GDK_IS_PIXMAP(pmap))
+            return;
+    }
+
     TRACE("really entering");
 
     current_workspace = xfce_desktop_get_current_workspace(desktop);
@@ -458,28 +499,12 @@ static void
 screen_size_changed_cb(GdkScreen *gscreen, gpointer user_data)
 {
     XfceDesktop *desktop = user_data;
-    gint w, h, current_workspace;
+    gint current_workspace;
 
     TRACE("entering");
 
-    g_return_if_fail(XFCE_IS_DESKTOP(desktop));
-
-    if(desktop->priv->workspaces == NULL)
+    if(!create_bg_pixmap(gscreen, desktop))
         return;
-    
-    w = gdk_screen_get_width(gscreen);
-    h = gdk_screen_get_height(gscreen);
-    gtk_widget_set_size_request(GTK_WIDGET(desktop), w, h);
-    gtk_window_resize(GTK_WINDOW(desktop), w, h);
-    
-    if(desktop->priv->bg_pixmap)
-        g_object_unref(G_OBJECT(desktop->priv->bg_pixmap));
-    desktop->priv->bg_pixmap = gdk_pixmap_new(GDK_DRAWABLE(gtk_widget_get_window(GTK_WIDGET(desktop))),
-                                              w, h, -1);
-    set_real_root_window_pixmap(desktop->priv->gscreen,
-                                desktop->priv->bg_pixmap);
-    gdk_window_set_back_pixmap(gtk_widget_get_window(GTK_WIDGET(desktop)),
-                               desktop->priv->bg_pixmap, FALSE);
 
     current_workspace = xfce_desktop_get_current_workspace(desktop);
 
@@ -571,7 +596,7 @@ workspace_changed_cb(WnckScreen *wnck_screen,
     for(i = 0; i < xfce_desktop_get_n_monitors(desktop); i++) {
         /* We want to compare the current workspace backdrop with the new one
          * and see if we can avoid changing them if they are the same image/style */
-        if(current_workspace < desktop->priv->nworkspaces) {
+        if(current_workspace < desktop->priv->nworkspaces && current_workspace >= 0) {
             current_backdrop = xfce_workspace_get_backdrop(desktop->priv->workspaces[current_workspace], i);
             new_backdrop = xfce_workspace_get_backdrop(desktop->priv->workspaces[new_workspace], i);
 
@@ -580,7 +605,8 @@ workspace_changed_cb(WnckScreen *wnck_screen,
                 backdrop_changed_cb(new_backdrop, user_data);
             }
         } else {
-            /* If current_workspace was removed, get the new backdrop and apply it */
+            /* If current_workspace was removed or never existed, get the new
+             * backdrop and apply it */
             new_backdrop = xfce_workspace_get_backdrop(desktop->priv->workspaces[new_workspace], i);
             backdrop_changed_cb(new_backdrop, user_data);
         }
@@ -925,7 +951,7 @@ xfce_desktop_realize(GtkWidget *widget)
 {
     XfceDesktop *desktop = XFCE_DESKTOP(widget);
     GdkAtom atom;
-    gint sw, sh, i;
+    gint sw, sh;
     Window xid;
     GdkWindow *groot;
     WnckScreen *wnck_screen;
@@ -975,7 +1001,6 @@ xfce_desktop_realize(GtkWidget *widget)
 
     /* We have to force wnck to initialize */
     wnck_screen = wnck_screen_get(gdk_screen_get_number(desktop->priv->gscreen));
-    wnck_screen_force_update(wnck_screen);
     desktop->priv->wnck_screen = wnck_screen;
 
     xfconf_g_property_bind(desktop->priv->channel,
@@ -986,24 +1011,8 @@ xfce_desktop_realize(GtkWidget *widget)
                            SINGLE_WORKSPACE_NUMBER, G_TYPE_INT,
                            G_OBJECT(desktop), "single-workspace-number");
 
-    /* Get the current workspace number */
-    desktop->priv->current_workspace = xfce_desktop_get_current_workspace(desktop);
-    desktop->priv->nworkspaces = wnck_screen_get_workspace_count(wnck_screen);
-
-    desktop->priv->workspaces = g_realloc(desktop->priv->workspaces,
-                                          desktop->priv->nworkspaces * sizeof(XfceWorkspace *));
-
-    for(i = 0; i < desktop->priv->nworkspaces; i++) {
-        desktop->priv->workspaces[i] = xfce_workspace_new(desktop->priv->gscreen,
-                                                          desktop->priv->channel,
-                                                          desktop->priv->property_prefix,
-                                                          i);
-        xfce_workspace_monitors_changed(desktop->priv->workspaces[i],
-                                        desktop->priv->gscreen);
-
-        g_signal_connect(desktop->priv->workspaces[i], "workspace-backdrop-changed",
-                         G_CALLBACK(workspace_backdrop_changed_cb), desktop);
-    }
+    /* Start with an invalid workspace so it updates */
+    desktop->priv->current_workspace = -1;
 
     g_signal_connect(desktop->priv->wnck_screen, "active-workspace-changed",
                      G_CALLBACK(workspace_changed_cb), desktop);
diff --git a/src/xfdesktop-file-icon-manager.c b/src/xfdesktop-file-icon-manager.c
index ed4fcde..155be45 100644
--- a/src/xfdesktop-file-icon-manager.c
+++ b/src/xfdesktop-file-icon-manager.c
@@ -113,7 +113,10 @@ struct _XfdesktopFileIconManagerPrivate
     GFileEnumerator *enumerator;
 
     GVolumeMonitor *volume_monitor;
-    
+
+    GFileMonitor *metadata_monitor;
+    guint metadata_timer;
+
     GHashTable *icons;
     GHashTable *removable_icons;
     GHashTable *special_icons;
@@ -413,7 +416,10 @@ xfdesktop_file_icon_manager_finalize(GObject *obj)
     
     g_object_unref(fmanager->priv->folder);
     g_object_unref(fmanager->priv->thumbnailer);
-    
+
+    if(fmanager->priv->volume_monitor != NULL)
+        g_object_unref(fmanager->priv->volume_monitor);
+
     G_OBJECT_CLASS(xfdesktop_file_icon_manager_parent_class)->finalize(obj);
 }
 
@@ -534,6 +540,8 @@ xfdesktop_file_icon_manager_check_create_desktop_folder(GFile *folder)
         }
     }
 
+    g_object_unref(info);
+
     return result;
 }
 
@@ -1818,27 +1826,123 @@ _icon_notify_destroy(gpointer data,
 }
 #endif
 
+/* builds a folder/file path and then tests if that file is a valid image.
+ * returns the file location if it does, NULL if it doesn't */
+static gchar *
+xfdesktop_check_file_is_valid(const gchar *folder, const gchar *file)
+{
+    gchar *path = g_strconcat(folder, "/", file, NULL);
+
+    if(gdk_pixbuf_get_file_info(path, NULL, NULL) == NULL) {
+        g_free(path);
+        path = NULL;
+    }
+
+    return path;
+}
+
+static gchar *
+xfdesktop_load_icon_location_from_folder(XfdesktopFileIcon *icon)
+{
+    gchar *icon_file = g_file_get_path(xfdesktop_file_icon_peek_file(icon));
+    gchar *path;
+
+    g_return_val_if_fail(icon_file, NULL);
+
+    /* So much for standards */
+    path = xfdesktop_check_file_is_valid(icon_file, "Folder.jpg");
+    if(path == NULL) {
+        path = xfdesktop_check_file_is_valid(icon_file, "folder.jpg");
+    }
+    if(path == NULL) {
+        path = xfdesktop_check_file_is_valid(icon_file, "Folder.JPG");
+    }
+    if(path == NULL) {
+        path = xfdesktop_check_file_is_valid(icon_file, "folder.JPG");
+    }
+    if(path == NULL) {
+        path = xfdesktop_check_file_is_valid(icon_file, "Cover.jpg");
+    }
+    if(path == NULL) {
+        path = xfdesktop_check_file_is_valid(icon_file, "cover.jpg");
+    }
+    if(path == NULL) {
+        path = xfdesktop_check_file_is_valid(icon_file, "albumart.jpg");
+    }
+    if(path == NULL) {
+        path = xfdesktop_check_file_is_valid(icon_file, "fanart.jpg");
+    }
+    if(path == NULL) {
+        path = xfdesktop_check_file_is_valid(icon_file, "Fanart.jpg");
+    }
+    if(path == NULL) {
+        path = xfdesktop_check_file_is_valid(icon_file, "fanart.JPG");
+    }
+    if(path == NULL) {
+        path = xfdesktop_check_file_is_valid(icon_file, "Fanart.JPG");
+    }
+    if(path == NULL) {
+        path = xfdesktop_check_file_is_valid(icon_file, "FANART.JPG");
+    }
+    if(path == NULL) {
+        path = xfdesktop_check_file_is_valid(icon_file, "FANART.jpg");
+    }
+
+    g_free(icon_file);
+
+    /* the file *should* already be a thumbnail */
+    return path;
+}
+
+static void
+xfdesktop_file_icon_manager_queue_thumbnail(XfdesktopFileIconManager *fmanager,
+                                            XfdesktopFileIcon *icon)
+{
+    GFile *file;
+    GFileInfo *file_info;
+    gchar *path = NULL, *thumbnail_file = NULL;
+
+    file = xfdesktop_file_icon_peek_file(icon);
+    file_info = xfdesktop_file_icon_peek_file_info(icon);
+
+    if(file != NULL)
+        path = g_file_get_path(file);
+
+    if(fmanager->priv->show_thumbnails && path != NULL) {
+        if(g_file_info_get_file_type(file_info) == G_FILE_TYPE_DIRECTORY) {
+            /* Try to load a thumbnail from the standard folder image locations */
+            thumbnail_file = xfdesktop_load_icon_location_from_folder(icon);
+
+            if(thumbnail_file) {
+                GFile *temp = g_file_new_for_path(thumbnail_file);
+                xfdesktop_icon_set_thumbnail_file(XFDESKTOP_ICON(icon), temp);
+            }
+        } else {
+            xfdesktop_thumbnailer_queue_thumbnail(fmanager->priv->thumbnailer,
+                                                  path);
+        }
+    }
+}
+
 static gboolean
 xfdesktop_file_icon_manager_add_icon(XfdesktopFileIconManager *fmanager,
                                      XfdesktopFileIcon *icon,
+                                     gint16 row, gint16 col,
                                      gboolean defer_if_missing)
 {
-    gint16 row = -1, col = -1;
+    GFile *file = xfdesktop_file_icon_peek_file(icon);
     gboolean do_add = FALSE;
     const gchar *name;
-    GFile *file;
-
-    file = xfdesktop_file_icon_peek_file(icon);
-
-    if(fmanager->priv->show_thumbnails && g_file_get_path(file) != NULL) {
-        xfdesktop_thumbnailer_queue_thumbnail(fmanager->priv->thumbnailer,
-                                              g_file_get_path(file));
-    }
 
+    xfdesktop_file_icon_manager_queue_thumbnail(fmanager, icon);
     
     name = xfdesktop_icon_peek_label(XFDESKTOP_ICON(icon));
-    if(xfdesktop_file_icon_manager_get_cached_icon_position(fmanager, name,
-                                                            &row, &col))
+    if(row >= 0 && col >= 0) {
+        DBG("attempting to set icon '%s' to position (%d,%d)", name, row, col);
+        xfdesktop_icon_set_position(XFDESKTOP_ICON(icon), row, col);
+        do_add = TRUE;
+    } else if(xfdesktop_file_icon_manager_get_cached_icon_position(fmanager, name,
+                                                                   &row, &col))
     {
         DBG("attempting to set icon '%s' to position (%d,%d)", name, row, col);
         xfdesktop_icon_set_position(XFDESKTOP_ICON(icon), row, col);
@@ -1869,10 +1973,13 @@ xfdesktop_file_icon_manager_add_icon(XfdesktopFileIconManager *fmanager,
     return do_add;
 }
 
+/* If row and col are set then they will be used, otherwise set them to -1
+ * and it will lookup the position in the rc file */
 static XfdesktopFileIcon *
 xfdesktop_file_icon_manager_add_regular_icon(XfdesktopFileIconManager *fmanager,
                                              GFile *file,
                                              GFileInfo *info,
+                                             guint16 row, guint16 col,
                                              gboolean defer_if_missing)
 {
     XfdesktopRegularFileIcon *icon = NULL;
@@ -1932,6 +2039,7 @@ xfdesktop_file_icon_manager_add_regular_icon(XfdesktopFileIconManager *fmanager,
     
     if(xfdesktop_file_icon_manager_add_icon(fmanager,
                                              XFDESKTOP_FILE_ICON(icon),
+                                             row, col,
                                              defer_if_missing))
     {
         g_hash_table_replace(fmanager->priv->icons, g_object_ref(file), icon);
@@ -1955,6 +2063,7 @@ xfdesktop_file_icon_manager_add_volume_icon(XfdesktopFileIconManager *fmanager,
     
     if(xfdesktop_file_icon_manager_add_icon(fmanager,
                                             XFDESKTOP_FILE_ICON(icon),
+                                            -1, -1,
                                             FALSE))
     {
         g_hash_table_replace(fmanager->priv->removable_icons,
@@ -1979,6 +2088,7 @@ xfdesktop_file_icon_manager_add_special_file_icon(XfdesktopFileIconManager *fman
     
     if(xfdesktop_file_icon_manager_add_icon(fmanager,
                                             XFDESKTOP_FILE_ICON(icon),
+                                            -1, -1,
                                             FALSE))
     {
         g_hash_table_replace(fmanager->priv->special_icons,
@@ -2154,10 +2264,52 @@ xfdesktop_file_icon_manager_file_changed(GFileMonitor     *monitor,
     XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
     XfdesktopFileIcon *icon;
     GFileInfo *file_info;
+    guint16 row, col;
 
     switch(event) {
+        case G_FILE_MONITOR_EVENT_MOVED:
+            DBG("got a moved event");
+
+            icon = g_hash_table_lookup(fmanager->priv->icons, file);
+            if(!icon) {
+                g_critical("G_FILE_MONITOR_EVENT_MOVED for an icon that doesn't exist");
+                return;
+            }
+
+            file_info = g_file_query_info(other_file, XFDESKTOP_FILE_INFO_NAMESPACE,
+                                          G_FILE_QUERY_INFO_NONE, NULL, NULL);
+
+            if(file_info) {
+                gboolean is_hidden;
+
+                /* Get the old position so we can use it for the new icon */
+                xfdesktop_icon_get_position(XFDESKTOP_ICON(icon), &row, &col);
+
+                /* Remove the icon from the icon_view and this manager's
+                 * hash table */
+                xfdesktop_icon_view_remove_item(fmanager->priv->icon_view,
+                                            XFDESKTOP_ICON(icon));
+                g_hash_table_remove(fmanager->priv->icons, file);
+
+                is_hidden = g_file_info_get_attribute_boolean(file_info,
+                                                              G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN);
+                if(!is_hidden) {
+                    /* Add the icon adding the row/col info */
+                    xfdesktop_file_icon_manager_add_regular_icon(fmanager,
+                                                                 other_file,
+                                                                 file_info,
+                                                                 row,
+                                                                 col,
+                                                                 FALSE);
+                    xfdesktop_file_icon_position_changed(icon, fmanager);
+                }
+
+                g_object_unref(file_info);
+            }
+            break;
+        case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
         case G_FILE_MONITOR_EVENT_CHANGED:
-            DBG("got changed event: %s", g_file_get_path(file));
+            DBG("got changed event");
             
             icon = g_hash_table_lookup(fmanager->priv->icons, file);
             if(icon) {
@@ -2199,7 +2351,8 @@ xfdesktop_file_icon_manager_file_changed(GFileMonitor     *monitor,
                                                                        G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN);
                 if(!is_hidden) {
                     xfdesktop_file_icon_manager_add_regular_icon(fmanager,
-                                                                 file, file_info, 
+                                                                 file, file_info,
+                                                                 -1, -1,
                                                                  FALSE);
                 }
 
@@ -2238,6 +2391,70 @@ xfdesktop_file_icon_manager_file_changed(GFileMonitor     *monitor,
 }
 
 static void
+xfdesktop_file_icon_manager_update_file_info(gpointer key,
+                                             gpointer value,
+                                             gpointer user_data)
+{
+    XfdesktopFileIcon *icon = XFDESKTOP_FILE_ICON(value);
+    GFileInfo *file_info;
+
+    if(icon) {
+        file_info = g_file_query_info(key, XFDESKTOP_FILE_INFO_NAMESPACE,
+                                      G_FILE_QUERY_INFO_NONE, NULL, NULL);
+
+        if(file_info) {
+            /* update the icon if the file still exists */
+            xfdesktop_file_icon_update_file_info(icon, file_info);
+            g_object_unref(file_info);
+        }
+    }
+}
+
+static gboolean
+xfdesktop_file_icon_manager_metadata_timer(gpointer user_data)
+{
+    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
+
+    g_hash_table_foreach(fmanager->priv->icons,
+                         (GHFunc)xfdesktop_file_icon_manager_update_file_info,
+                         fmanager);
+
+    fmanager->priv->metadata_timer = 0;
+
+    return FALSE;
+}
+
+static void
+xfdesktop_file_icon_manager_metadata_changed(GFileMonitor     *monitor,
+                                             GFile            *file,
+                                             GFile            *other_file,
+                                             GFileMonitorEvent event,
+                                             gpointer          user_data)
+{
+    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
+
+    switch(event) {
+        case G_FILE_MONITOR_EVENT_CHANGED:
+            DBG("metadata file changed event");
+
+            /* cool down timer so we don't call this due to multiple file
+             * changes at the same time. */
+            if(fmanager->priv->metadata_timer == 0) {
+                guint timer;
+
+                timer = g_timeout_add_seconds(5,
+                                              (GSourceFunc)xfdesktop_file_icon_manager_metadata_timer,
+                                              fmanager);
+
+                fmanager->priv->metadata_timer = timer;
+            }
+            break;
+        default:
+            break;
+    }
+}
+
+static void
 xfdesktop_file_icon_manager_files_ready(GFileEnumerator *enumerator,
                                         GAsyncResult *result,
                                         gpointer user_data)
@@ -2277,7 +2494,8 @@ xfdesktop_file_icon_manager_files_ready(GFileEnumerator *enumerator,
                                                     NULL, NULL);
 
                 xfdesktop_file_icon_manager_add_regular_icon(fmanager, 
-                                                             file, info, 
+                                                             file, info,
+                                                             -1, -1,
                                                              FALSE);
                 g_object_unref(info);
                 g_object_unref(file);
@@ -2287,14 +2505,30 @@ xfdesktop_file_icon_manager_files_ready(GFileEnumerator *enumerator,
         }
 
 
+        /* initialize the file monitor */
         if(!fmanager->priv->monitor) {
             fmanager->priv->monitor = g_file_monitor(fmanager->priv->folder,
-                                                     G_FILE_MONITOR_NONE,
+                                                     G_FILE_MONITOR_SEND_MOVED,
                                                      NULL, NULL);
             g_signal_connect(fmanager->priv->monitor, "changed",
                              G_CALLBACK(xfdesktop_file_icon_manager_file_changed),
                              fmanager);
         }
+
+        /* initialize the metadata watching the gvfs files since it doesn't
+         * send notification messages when monitored files change */
+        if(!fmanager->priv->metadata_monitor) {
+            gchar *location = xfce_resource_lookup(XFCE_RESOURCE_DATA, "gvfs-metadata/");
+            GFile *metadata_location = g_file_new_for_path(location);
+
+            fmanager->priv->metadata_monitor = g_file_monitor(metadata_location,
+                                                              G_FILE_MONITOR_NONE,
+                                                              NULL, NULL);
+            g_signal_connect(fmanager->priv->metadata_monitor, "changed",
+                             G_CALLBACK(xfdesktop_file_icon_manager_metadata_changed),
+                             fmanager);
+            g_free(location);
+        }
     } else {
         for(l = files; l; l = l->next) {
             DBG("got a GFileInfo: %s", g_file_info_get_display_name(l->data));
@@ -2307,6 +2541,7 @@ xfdesktop_file_icon_manager_files_ready(GFileEnumerator *enumerator,
 
                 xfdesktop_file_icon_manager_add_regular_icon(fmanager, 
                                                              file, l->data,
+                                                             -1, -1,
                                                              TRUE);
 
                 g_object_unref(file);
@@ -2448,12 +2683,8 @@ xfdesktop_file_icon_manager_load_removable_media(XfdesktopFileIconManager *fmana
     if(fmanager->priv->removable_icons)
         return;
     
-    if(!fmanager->priv->volume_monitor) {
+    if(!fmanager->priv->volume_monitor)
         fmanager->priv->volume_monitor = g_volume_monitor_get();
-        g_object_add_weak_pointer(G_OBJECT(fmanager->priv->volume_monitor),
-                                  (gpointer)&fmanager->priv->volume_monitor);
-    } else
-       g_object_ref(G_OBJECT(fmanager->priv->volume_monitor));
     
     fmanager->priv->removable_icons = g_hash_table_new_full(g_direct_hash,
                                                             g_direct_equal,
@@ -2514,6 +2745,7 @@ xfdesktop_file_icon_manager_remove_removable_media(XfdesktopFileIconManager *fma
                                              fmanager);
     
         g_object_unref(fmanager->priv->volume_monitor);
+        fmanager->priv->volume_monitor = NULL;
     }
 }
 
@@ -3265,11 +3497,10 @@ xfdesktop_file_icon_manager_requeue_thumbnails(gpointer key,
                                                gpointer value,
                                                gpointer data)
 {
-    GFile *file = key;
     XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(data);
+    XfdesktopFileIcon *icon = XFDESKTOP_FILE_ICON(value);
 
-    xfdesktop_thumbnailer_queue_thumbnail(fmanager->priv->thumbnailer,
-                                          g_file_get_path(file));
+    xfdesktop_file_icon_manager_queue_thumbnail(fmanager, icon);
 }
 
 static void
diff --git a/src/xfdesktop-file-icon.c b/src/xfdesktop-file-icon.c
index 1088e99..c4dd11a 100644
--- a/src/xfdesktop-file-icon.c
+++ b/src/xfdesktop-file-icon.c
@@ -30,37 +30,112 @@
 #include "xfdesktop-file-utils.h"
 #include "xfdesktop-file-icon.h"
 
+struct _XfdesktopFileIconPrivate
+{
+    GIcon *gicon;
+};
+
 static void xfdesktop_file_icon_finalize(GObject *obj);
 
 static gboolean xfdesktop_file_icon_activated(XfdesktopIcon *icon);
 
+static void xfdesktop_file_icon_set_property(GObject *object,
+                                             guint property_id,
+                                             const GValue *value,
+                                             GParamSpec *pspec);
+static void xfdesktop_file_icon_get_property(GObject *object,
+                                             guint property_id,
+                                             GValue *value,
+                                             GParamSpec *pspec);
 
 G_DEFINE_ABSTRACT_TYPE(XfdesktopFileIcon, xfdesktop_file_icon,
                        XFDESKTOP_TYPE_ICON)
 
+enum
+{
+    PROP_0,
+    PROP_GICON,
+};
 
 static void
 xfdesktop_file_icon_class_init(XfdesktopFileIconClass *klass)
 {
     GObjectClass *gobject_class = (GObjectClass *)klass;
     XfdesktopIconClass *icon_class = (XfdesktopIconClass *)klass;
-    
+
+    g_type_class_add_private(klass, sizeof(XfdesktopFileIconPrivate));
+
     gobject_class->finalize = xfdesktop_file_icon_finalize;
+    gobject_class->set_property = xfdesktop_file_icon_set_property;
+    gobject_class->get_property = xfdesktop_file_icon_get_property;
     
     icon_class->activated = xfdesktop_file_icon_activated;
+
+    g_object_class_install_property(gobject_class,
+                                    PROP_GICON,
+                                    g_param_spec_pointer("gicon",
+                                                         "gicon",
+                                                         "gicon",
+                                                         G_PARAM_READWRITE));
 }
 
 static void
 xfdesktop_file_icon_init(XfdesktopFileIcon *icon)
 {
+    icon->priv = G_TYPE_INSTANCE_GET_PRIVATE(icon,
+                                             XFDESKTOP_TYPE_FILE_ICON,
+                                             XfdesktopFileIconPrivate);
 }
 
 static void
 xfdesktop_file_icon_finalize(GObject *obj)
 {
+    XfdesktopFileIcon *icon = XFDESKTOP_FILE_ICON(obj);
+
+    xfdesktop_file_icon_invalidate_icon(icon);
+
     G_OBJECT_CLASS(xfdesktop_file_icon_parent_class)->finalize(obj);
 }
 
+static void
+xfdesktop_file_icon_set_property(GObject *object,
+                                 guint property_id,
+                                 const GValue *value,
+                                 GParamSpec *pspec)
+{
+    XfdesktopFileIcon *file_icon = XFDESKTOP_FILE_ICON(object);
+
+    switch(property_id) {
+        case PROP_GICON:
+            xfdesktop_file_icon_invalidate_icon(file_icon);
+            file_icon->priv->gicon = g_value_get_pointer(value);
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+            break;
+    }
+}
+
+static void
+xfdesktop_file_icon_get_property(GObject *object,
+                                 guint property_id,
+                                 GValue *value,
+                                 GParamSpec *pspec)
+{
+    XfdesktopFileIcon *file_icon = XFDESKTOP_FILE_ICON(object);
+
+    switch(property_id) {
+        case PROP_GICON:
+            g_value_set_pointer(value, file_icon->priv->gicon);
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+            break;
+    }
+}
+
 static gboolean
 xfdesktop_file_icon_activated(XfdesktopIcon *icon)
 {
@@ -178,3 +253,63 @@ xfdesktop_file_icon_can_delete_file(XfdesktopFileIcon *icon)
     else
         return FALSE;
 }
+
+GIcon *
+xfdesktop_file_icon_add_emblems(XfdesktopFileIcon *icon)
+{
+    GIcon *emblemed_icon = NULL;
+    gchar **emblem_names;
+
+    TRACE("entering");
+
+    g_return_val_if_fail(XFDESKTOP_IS_FILE_ICON(icon), NULL);
+
+    if(G_IS_ICON(icon->priv->gicon))
+        emblemed_icon = g_emblemed_icon_new(icon->priv->gicon, NULL);
+    else
+        return NULL;
+
+    if(!G_IS_FILE_INFO(xfdesktop_file_icon_peek_file_info(icon)))
+        return icon->priv->gicon = emblemed_icon;
+
+    /* Get the list of emblems */
+    emblem_names = g_file_info_get_attribute_stringv(xfdesktop_file_icon_peek_file_info(icon),
+                                                     "metadata::emblems");
+
+    if(emblem_names != NULL) {
+        /* for each item in the list create an icon, pack it into an emblem,
+         * and attach it to our icon. */
+        for (; *emblem_names != NULL; ++emblem_names) {
+            GIcon *themed_icon = g_themed_icon_new(*emblem_names);
+            GEmblem *emblem = g_emblem_new(themed_icon);
+
+            g_emblemed_icon_add_emblem(G_EMBLEMED_ICON(emblemed_icon), emblem);
+
+            g_object_unref(emblem);
+            g_object_unref(themed_icon);
+        }
+    } else
+
+    /* Clear out the old icon and set the new one */
+    xfdesktop_file_icon_invalidate_icon(icon);
+    return icon->priv->gicon = emblemed_icon;
+}
+
+void
+xfdesktop_file_icon_invalidate_icon(XfdesktopFileIcon *icon)
+{
+    g_return_if_fail(XFDESKTOP_IS_FILE_ICON(icon));
+
+    if(G_IS_ICON(icon->priv->gicon)) {
+        g_object_unref(icon->priv->gicon);
+        icon->priv->gicon = NULL;
+    }
+}
+
+gboolean
+xfdesktop_file_icon_has_gicon(XfdesktopFileIcon *icon)
+{
+    g_return_val_if_fail(XFDESKTOP_IS_FILE_ICON(icon), FALSE);
+
+    return G_IS_ICON(icon->priv->gicon);
+}
diff --git a/src/xfdesktop-file-icon.h b/src/xfdesktop-file-icon.h
index 4ca703f..2cd7319 100644
--- a/src/xfdesktop-file-icon.h
+++ b/src/xfdesktop-file-icon.h
@@ -36,10 +36,14 @@ G_BEGIN_DECLS
 
 typedef struct _XfdesktopFileIcon        XfdesktopFileIcon;
 typedef struct _XfdesktopFileIconClass   XfdesktopFileIconClass;
+typedef struct _XfdesktopFileIconPrivate XfdesktopFileIconPrivate;
 
 struct _XfdesktopFileIcon
 {
     XfdesktopIcon parent;
+
+    /*< private >*/
+    XfdesktopFileIconPrivate *priv;
 };
 
 struct _XfdesktopFileIconClass
@@ -68,6 +72,12 @@ gboolean xfdesktop_file_icon_can_rename_file(XfdesktopFileIcon *icon);
 
 gboolean xfdesktop_file_icon_can_delete_file(XfdesktopFileIcon *icon);
 
+GIcon *xfdesktop_file_icon_add_emblems(XfdesktopFileIcon *icon);
+
+void xfdesktop_file_icon_invalidate_icon(XfdesktopFileIcon *icon);
+
+gboolean xfdesktop_file_icon_has_gicon(XfdesktopFileIcon *icon);
+
 G_END_DECLS
 
 #endif  /* __XFDESKTOP_FILE_ICON_H__ */
diff --git a/src/xfdesktop-file-utils.c b/src/xfdesktop-file-utils.c
index 28e4706..e593c65 100644
--- a/src/xfdesktop-file-utils.c
+++ b/src/xfdesktop-file-utils.c
@@ -63,6 +63,8 @@
 #include "xfdesktop-file-utils.h"
 #include "xfdesktop-trash-proxy.h"
 
+static void xfdesktop_file_utils_add_emblems(GdkPixbuf *pix, GList *emblems);
+
 gboolean
 xfdesktop_file_utils_is_desktop_file(GFileInfo *info)
 {
@@ -488,42 +490,54 @@ xfdesktop_file_utils_get_fallback_icon(gint size)
 }
 
 GdkPixbuf *
-xfdesktop_file_utils_get_icon(const gchar *custom_icon_name,
-                              GIcon *icon,
-                              gint size,
-                              const GdkPixbuf *emblem,
+xfdesktop_file_utils_get_icon(GIcon *icon,
+                              gint width,
+                              gint height,
                               guint opacity)
 {
     GtkIconTheme *itheme = gtk_icon_theme_get_default();
     GdkPixbuf *pix_theme = NULL, *pix = NULL;
+    GIcon *base_icon = NULL;
+    gint size = MIN(width, height);
 
-    if(custom_icon_name) {
-        pix_theme = gtk_icon_theme_load_icon(itheme, custom_icon_name, size,
-                                             ITHEME_FLAGS, NULL);
-        if(!pix_theme && *custom_icon_name == '/' && g_file_test(custom_icon_name, G_FILE_TEST_IS_REGULAR))
-            pix_theme = gdk_pixbuf_new_from_file_at_size(custom_icon_name, size, size, NULL);
-    }
+    g_return_val_if_fail(width > 0 && height > 0 && icon != NULL, NULL);
 
-    if(!pix_theme && icon) {
-        if(G_IS_THEMED_ICON(icon)) {
-          GtkIconInfo *icon_info = gtk_icon_theme_lookup_by_gicon(itheme,
-                                                                  icon, size,
-                                                                  ITHEME_FLAGS);
-          if(icon_info) {
-              pix_theme = gtk_icon_info_load_icon(icon_info, NULL);
-              gtk_icon_info_free(icon_info);
-          }
-        } else if(G_IS_LOADABLE_ICON(icon)) {
-            GInputStream *stream = g_loadable_icon_load(G_LOADABLE_ICON(icon),
-                                                        size, NULL, NULL, NULL);
-            if(stream) {
-                pix = gdk_pixbuf_new_from_stream(stream, NULL, NULL);
-                g_object_unref(stream);
-            }
+    /* Extract the base icon if available */
+    if(G_IS_EMBLEMED_ICON(icon))
+        base_icon = g_emblemed_icon_get_icon(G_EMBLEMED_ICON(icon));
+    else
+        base_icon = icon;
+
+    if(!base_icon)
+        return NULL;
+
+    if(G_IS_THEMED_ICON(base_icon)) {
+      GtkIconInfo *icon_info = gtk_icon_theme_lookup_by_gicon(itheme,
+                                                              base_icon, size,
+                                                              ITHEME_FLAGS);
+      if(icon_info) {
+          pix_theme = gtk_icon_info_load_icon(icon_info, NULL);
+          gtk_icon_info_free(icon_info);
+      }
+    } else if(G_IS_LOADABLE_ICON(base_icon)) {
+        GInputStream *stream = g_loadable_icon_load(G_LOADABLE_ICON(base_icon),
+                                                    size, NULL, NULL, NULL);
+        if(stream) {
+            pix = gdk_pixbuf_new_from_stream_at_scale(stream, width, height, TRUE, NULL, NULL);
+            g_object_unref(stream);
         }
+    } else if(G_IS_FILE_ICON(base_icon)) {
+        GFile *file = g_file_icon_get_file(G_FILE_ICON(icon));
+        gchar *path = g_file_get_path(file);
+
+        pix = gdk_pixbuf_new_from_file_at_size(path, width, height, NULL);
+
+        g_free(path);
+        g_object_unref(file);
     }
 
-    if(G_LIKELY(pix_theme)) {
+
+    if(pix_theme) {
         /* we can't edit thsese icons */
         pix = gdk_pixbuf_copy(pix_theme);
         g_object_unref(G_OBJECT(pix_theme));
@@ -540,35 +554,9 @@ xfdesktop_file_utils_get_icon(const gchar *custom_icon_name,
         return NULL;
     }
 
-    if(emblem) {
-        gint emblem_pix_size = gdk_pixbuf_get_width(emblem);
-        gint dest_size = size - emblem_pix_size;
-
-        /* if we're using the fallback icon, we don't want to draw an emblem on
-         * it, since other icons might use it without the emblem */
-        if(G_UNLIKELY(pix == xfdesktop_fallback_icon)) {
-            GdkPixbuf *tmp = gdk_pixbuf_copy(pix);
-            g_object_unref(G_OBJECT(pix));
-            pix = tmp;
-        }
-
-        if(dest_size < 0)
-            g_critical("xfdesktop_file_utils_get_file_icon(): (dest_size > 0) failed");
-        else {
-            DBG("calling gdk_pixbuf_composite(%p, %p, %d, %d, %d, %d, %.1f, %.1f, %.1f, %.1f, %d, %d)",
-                emblem, pix,
-                dest_size, dest_size,
-                emblem_pix_size, emblem_pix_size,
-                (gdouble)dest_size, (gdouble)dest_size,
-                1.0, 1.0, GDK_INTERP_BILINEAR, 255);
-
-            gdk_pixbuf_composite(emblem, pix,
-                                 dest_size, dest_size,
-                                 emblem_pix_size, emblem_pix_size,
-                                 dest_size, dest_size,
-                                 1.0, 1.0, GDK_INTERP_BILINEAR, 255);
-        }
-    }
+    /* Add the emblems */
+    if(G_IS_EMBLEMED_ICON(icon))
+        xfdesktop_file_utils_add_emblems(pix, g_emblemed_icon_get_emblems(G_EMBLEMED_ICON(icon)));
 
     if(opacity != 100) {
         GdkPixbuf *tmp = exo_gdk_pixbuf_lucent(pix, opacity);
@@ -579,6 +567,97 @@ xfdesktop_file_utils_get_icon(const gchar *custom_icon_name,
     return pix;
 }
 
+static void
+xfdesktop_file_utils_add_emblems(GdkPixbuf *pix, GList *emblems)
+{
+    GdkPixbuf *emblem_pix;
+    gint max_emblems;
+    gint pix_width, pix_height;
+    gint emblem_size;
+    gint dest_x, dest_y, dest_width, dest_height;
+    gint position;
+    GList *iter;
+    GtkIconTheme *itheme = gtk_icon_theme_get_default();
+
+    g_return_if_fail(pix != NULL);
+
+    pix_width = gdk_pixbuf_get_width(pix);
+    pix_height = gdk_pixbuf_get_height(pix);
+
+    emblem_size = MIN(pix_width, pix_height) / 2;
+
+    /* render up to four emblems for sizes from 48 onwards, else up to 2 emblems */
+    max_emblems = (pix_height < 48 && pix_width < 48) ? 2 : 4;
+
+    for(iter = emblems, position = 0; iter != NULL && position < max_emblems; iter = iter->next) {
+        /* extract the icon from the emblem and load it */
+        GIcon *emblem = g_emblem_get_icon(iter->data);
+        GtkIconInfo *icon_info = gtk_icon_theme_lookup_by_gicon(itheme,
+                                                                emblem,
+                                                                emblem_size,
+                                                                ITHEME_FLAGS);
+        if(icon_info) {
+            emblem_pix = gtk_icon_info_load_icon(icon_info, NULL);
+            gtk_icon_info_free(icon_info);
+        }
+
+        if(emblem_pix) {
+            if(gdk_pixbuf_get_width(emblem_pix) != emblem_size
+               || gdk_pixbuf_get_height(emblem_pix) != emblem_size)
+            {
+                GdkPixbuf *tmp = gdk_pixbuf_scale_simple(emblem_pix,
+                                                         emblem_size,
+                                                         emblem_size,
+                                                         GDK_INTERP_BILINEAR);
+                g_object_unref(emblem_pix);
+                emblem_pix = tmp;
+            }
+
+            dest_width = pix_width - emblem_size;
+            dest_height = pix_height - emblem_size;
+
+            switch(position) {
+                case 0: /* bottom right */
+                    dest_x = dest_width;
+                    dest_y = dest_height;
+                    break;
+                case 1: /* bottom left */
+                    dest_x = 0;
+                    dest_y = dest_height;
+                    break;
+                case 2: /* upper right */
+                    dest_x = dest_width;
+                    dest_y = 0;
+                    break;
+                case 3: /* upper left */
+                    dest_x = dest_y = 0;
+                    break;
+                default:
+                    g_warning("Invalid emblem position in xfdesktop_file_utils_add_emblems");
+            }
+
+            DBG("calling gdk_pixbuf_composite(%p, %p, %d, %d, %d, %d, %d, %d, %.1f, %.1f, %d, %d) pixbuf w: %d h: %d",
+                emblem_pix, pix,
+                dest_x, dest_y,
+                emblem_size, emblem_size,
+                dest_x, dest_y,
+                1.0, 1.0, GDK_INTERP_BILINEAR, 255, pix_width, pix_height);
+
+            /* Add the emblem */
+            gdk_pixbuf_composite(emblem_pix, pix,
+                                 dest_x, dest_y,
+                                 emblem_size, emblem_size,
+                                 dest_x, dest_y,
+                                 1.0, 1.0, GDK_INTERP_BILINEAR, 255);
+
+            g_object_unref(emblem_pix);
+            emblem_pix = NULL;
+
+            position++;
+        }
+    }
+}
+
 void
 xfdesktop_file_utils_set_window_cursor(GtkWindow *window,
                                        GdkCursorType cursor_type)
diff --git a/src/xfdesktop-file-utils.h b/src/xfdesktop-file-utils.h
index a44e53f..1975ae5 100644
--- a/src/xfdesktop-file-utils.h
+++ b/src/xfdesktop-file-utils.h
@@ -50,10 +50,9 @@ void xfdesktop_file_utils_file_list_free(GList *file_list);
 
 GdkPixbuf *xfdesktop_file_utils_get_fallback_icon(gint size);
 
-GdkPixbuf *xfdesktop_file_utils_get_icon(const gchar *custom_icon_name,
-                                         GIcon *icon,
-                                         gint size,
-                                         const GdkPixbuf *emblem,
+GdkPixbuf *xfdesktop_file_utils_get_icon(GIcon *icon,
+                                         gint width,
+                                         gint height,
                                          guint opacity);
 
 void xfdesktop_file_utils_set_window_cursor(GtkWindow *window,
diff --git a/src/xfdesktop-icon-view.c b/src/xfdesktop-icon-view.c
index 0691570..7c526eb 100644
--- a/src/xfdesktop-icon-view.c
+++ b/src/xfdesktop-icon-view.c
@@ -57,9 +57,12 @@
 
 #define ICON_SIZE         (icon_view->priv->icon_size)
 #define TEXT_WIDTH        ((icon_view->priv->cell_text_width_proportion) * ICON_SIZE)
+#define ICON_WIDTH        (TEXT_WIDTH)
 #define CELL_PADDING      (icon_view->priv->cell_padding)
 #define CELL_SIZE         (TEXT_WIDTH + CELL_PADDING * 2)
 #define SPACING           (icon_view->priv->cell_spacing)
+#define LABEL_RADIUS      (icon_view->priv->label_radius)
+#define TEXT_HEIGHT       (CELL_SIZE - ICON_SIZE - SPACING - (CELL_PADDING * 2) - LABEL_RADIUS)
 #define SCREEN_MARGIN     8
 #define DEFAULT_RUBBERBAND_ALPHA  64
 
@@ -171,6 +174,7 @@ struct _XfdesktopIconViewPrivate
 
     gint cell_padding;
     gint cell_spacing;
+    gdouble label_radius;
     gdouble cell_text_width_proportion;
 
     gboolean ellipsize_icon_labels;
@@ -330,6 +334,8 @@ static gboolean xfdesktop_icon_view_show_tooltip(GtkWidget *widget,
                                                  GtkTooltip *tooltip,
                                                  gpointer user_data);
 
+static gboolean xfdesktop_icon_view_is_icon_selected(XfdesktopIconView *icon_view,
+                                                     XfdesktopIcon *icon);
 static void xfdesktop_icon_view_real_select_all(XfdesktopIconView *icon_view);
 static void xfdesktop_icon_view_real_unselect_all(XfdesktopIconView *icon_view);
 static void xfdesktop_icon_view_real_select_cursor_item(XfdesktopIconView *icon_view);
@@ -790,7 +796,7 @@ xfdesktop_icon_view_button_press(GtkWidget *widget,
         icon_l = g_list_find_custom(icon_view->priv->icons, evt,
                                     (GCompareFunc)xfdesktop_check_icon_clicked);
         if(icon_l && (icon = icon_l->data)) {
-            if(g_list_find(icon_view->priv->selected_icons, icon)) {
+            if(xfdesktop_icon_view_is_icon_selected(icon_view, icon)) {
                 /* clicked an already-selected icon */
                 
                 if(evt->state & GDK_CONTROL_MASK) {
@@ -874,6 +880,7 @@ xfdesktop_icon_view_button_press(GtkWidget *widget,
                 g_signal_emit(G_OBJECT(icon_view), __signals[SIG_ICON_ACTIVATED],
                               0, NULL);
                 xfdesktop_icon_activated(icon);
+                xfdesktop_icon_view_unselect_item(icon_view, icon);
             }
         }
         
@@ -915,6 +922,7 @@ xfdesktop_icon_view_button_release(GtkWidget *widget,
             g_signal_emit(G_OBJECT(icon_view), __signals[SIG_ICON_ACTIVATED],
                           0, NULL);
             xfdesktop_icon_activated(icon);
+            xfdesktop_icon_view_unselect_item(icon_view, icon);
         }
     }
 
@@ -1058,8 +1066,9 @@ xfdesktop_icon_view_show_tooltip(GtkWidget *widget,
 
     if(icon_view->priv->tooltip_size > 0) {
         gtk_tooltip_set_icon(tooltip,
-                xfdesktop_icon_peek_pixbuf(icon_view->priv->item_under_pointer,
-                                           icon_view->priv->tooltip_size));
+                xfdesktop_icon_peek_tooltip_pixbuf(icon_view->priv->item_under_pointer,
+                                                   icon_view->priv->tooltip_size * 1.5f,
+                                                   icon_view->priv->tooltip_size));
     }
 
     gtk_tooltip_set_text(tooltip, padded_tip_text);
@@ -1175,7 +1184,7 @@ xfdesktop_icon_view_motion_notify(GtkWidget *widget,
 
                 if(xfdesktop_icon_get_extents(icon, NULL, NULL, &extents)
                    && gdk_rectangle_intersect(&extents, new_rect, &dummy)
-                   && !g_list_find(icon_view->priv->selected_icons, icon))
+                   && !xfdesktop_icon_view_is_icon_selected(icon_view, icon))
                 {
                     /* since _select_item() prepends to the list, we
                      * should be ok just calling this */
@@ -1263,7 +1272,7 @@ xfdesktop_icon_view_drag_begin(GtkWidget *widget,
     if(xfdesktop_icon_get_extents(icon, NULL, NULL, &extents)) {
         GdkPixbuf *pix;
         
-        pix = xfdesktop_icon_peek_pixbuf(icon, ICON_SIZE);
+        pix = xfdesktop_icon_peek_pixbuf(icon, ICON_WIDTH, ICON_SIZE);
         if(pix)
             gtk_drag_set_icon_pixbuf(context, pix, 0, 0);
     }
@@ -1837,6 +1846,7 @@ xfdesktop_icon_view_style_set(GtkWidget *widget,
                          "cell-text-width-proportion", &icon_view->priv->cell_text_width_proportion,
                          "ellipsize-icon-labels", &icon_view->priv->ellipsize_icon_labels,
                          "tooltip-size", &icon_view->priv->tooltip_size,
+                         "label-radius", &icon_view->priv->label_radius,
                          NULL);
 
     DBG("cell spacing is %d", icon_view->priv->cell_spacing);
@@ -1844,6 +1854,7 @@ xfdesktop_icon_view_style_set(GtkWidget *widget,
     DBG("cell text width proportion is %f", icon_view->priv->cell_text_width_proportion);
     DBG("ellipsize icon label is %s", icon_view->priv->ellipsize_icon_labels?"true":"false");
     DBG("tooltip size is %d", icon_view->priv->tooltip_size);
+    DBG("label radius is %f", icon_view->priv->label_radius);
 
     if(icon_view->priv->selection_box_color) {
         gdk_color_free(icon_view->priv->selection_box_color);
@@ -1900,7 +1911,8 @@ xfdesktop_icon_view_realize(GtkWidget *widget)
     
     pctx = gtk_widget_get_pango_context(GTK_WIDGET(icon_view));
     icon_view->priv->playout = pango_layout_new(pctx);
-    
+    g_object_unref(pctx);
+
     if(icon_view->priv->font_size > 0) {
         xfdesktop_icon_view_modify_font_size(icon_view,
                                              icon_view->priv->font_size);
@@ -2033,6 +2045,7 @@ xfdesktop_icon_view_expose(GtkWidget *widget,
 {
     XfdesktopIconView *icon_view = XFDESKTOP_ICON_VIEW(widget);
     GdkRectangle *rects = NULL;
+    GdkRectangle clipbox;
     gint n_rects = 0, i;
 
     /*TRACE("entering");*/
@@ -2041,9 +2054,9 @@ xfdesktop_icon_view_expose(GtkWidget *widget,
         return FALSE;
 
     gdk_region_get_rectangles(evt->region, &rects, &n_rects);
+    gdk_region_get_clipbox(evt->region, &clipbox);
 
-    for(i = 0; i < n_rects; ++i)
-        xfdesktop_icon_view_repaint_icons(icon_view, &rects[i]);
+    xfdesktop_icon_view_repaint_icons(icon_view, &clipbox);
 
     if(icon_view->priv->definitely_rubber_banding) {
         GdkRectangle intersect;
@@ -2145,6 +2158,8 @@ xfdesktop_icon_view_real_activate_cursor_item(XfdesktopIconView *icon_view)
 
     g_signal_emit(G_OBJECT(icon_view), __signals[SIG_ICON_ACTIVATED], 0, NULL);
     xfdesktop_icon_activated(icon_view->priv->cursor);
+    xfdesktop_icon_view_unselect_item(icon_view, icon_view->priv->cursor);
+    icon_view->priv->cursor = NULL;
 
     return TRUE;
 }
@@ -2452,7 +2467,7 @@ xfdesktop_icon_view_repaint_icons(XfdesktopIconView *icon_view,
     /* fist paint non-selected items, then paint selected items */
     for(l = icon_view->priv->icons; l; l = l->next) {
         icon = (XfdesktopIcon *)l->data;
-        if (g_list_find(icon_view->priv->selected_icons, icon))
+        if (xfdesktop_icon_view_is_icon_selected(icon_view, icon))
             continue;
 
         if(!xfdesktop_icon_get_extents(icon, NULL, NULL, &extents)
@@ -2464,7 +2479,7 @@ xfdesktop_icon_view_repaint_icons(XfdesktopIconView *icon_view,
     
     for(l = icon_view->priv->icons; l; l = l->next) {
         icon = (XfdesktopIcon *)l->data;
-        if (!g_list_find(icon_view->priv->selected_icons, icon))
+        if (!xfdesktop_icon_view_is_icon_selected(icon_view, icon))
             continue;
 
         if(!xfdesktop_icon_get_extents(icon, NULL, NULL, &extents)
@@ -2671,7 +2686,7 @@ xfdesktop_icon_view_invalidate_icon_pixbuf(XfdesktopIconView *icon_view,
 {
     GdkPixbuf *pix;
     
-    pix = xfdesktop_icon_peek_pixbuf(icon, ICON_SIZE);
+    pix = xfdesktop_icon_peek_pixbuf(icon, ICON_WIDTH, ICON_SIZE);
     if(pix) {
         GdkRectangle rect = { 0, };
         
@@ -2682,7 +2697,7 @@ xfdesktop_icon_view_invalidate_icon_pixbuf(XfdesktopIconView *icon_view,
             return;
         
         rect.x += CELL_PADDING + ((CELL_SIZE - 2 * CELL_PADDING) - rect.width) / 2;
-        rect.y += CELL_PADDING + SPACING;
+        rect.y += CELL_PADDING;
     
         if(gtk_widget_get_realized(GTK_WIDGET(icon_view))) {
             gtk_widget_queue_draw_area(GTK_WIDGET(icon_view), rect.x, rect.y,
@@ -2698,17 +2713,12 @@ xfdesktop_paint_rounded_box(XfdesktopIconView *icon_view,
                             GdkRectangle *expose_area)
 {
     GdkRectangle box_area, intersection;
-    gdouble label_radius = 4.0;
-
-    gtk_widget_style_get(GTK_WIDGET(icon_view),
-                         "label-radius", &label_radius,
-                         NULL);
     
     box_area = *text_area;
-    box_area.x -= label_radius;
-    box_area.y -= label_radius;
-    box_area.width += label_radius * 2;
-    box_area.height += label_radius * 2;
+    box_area.x -= LABEL_RADIUS;
+    box_area.y -= LABEL_RADIUS;
+    box_area.width += LABEL_RADIUS * 2;
+    box_area.height += LABEL_RADIUS * 2;
     
     if(gdk_rectangle_intersect(&box_area, expose_area, &intersection)) {
         cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(GTK_WIDGET(icon_view)));
@@ -2729,29 +2739,29 @@ xfdesktop_paint_rounded_box(XfdesktopIconView *icon_view,
         gdk_cairo_rectangle(cr, expose_area);
         cairo_clip(cr);
 
-        if(label_radius < 0.1)
+        if(LABEL_RADIUS < 0.1)
             gdk_cairo_rectangle(cr, &box_area);
         else {
-            cairo_move_to(cr, box_area.x, box_area.y + label_radius);
-            cairo_arc(cr, box_area.x + label_radius,
-                      box_area.y + label_radius, label_radius,
+            cairo_move_to(cr, box_area.x, box_area.y + LABEL_RADIUS);
+            cairo_arc(cr, box_area.x + LABEL_RADIUS,
+                      box_area.y + LABEL_RADIUS, LABEL_RADIUS,
                       M_PI, 3.0*M_PI/2.0);
-            cairo_line_to(cr, box_area.x + box_area.width - label_radius,
+            cairo_line_to(cr, box_area.x + box_area.width - LABEL_RADIUS,
                           box_area.y);
-            cairo_arc(cr, box_area.x + box_area.width - label_radius,
-                      box_area.y + label_radius, label_radius,
+            cairo_arc(cr, box_area.x + box_area.width - LABEL_RADIUS,
+                      box_area.y + LABEL_RADIUS, LABEL_RADIUS,
                       3.0+M_PI/2.0, 0.0);
             cairo_line_to(cr, box_area.x + box_area.width,
-                          box_area.y + box_area.height - label_radius);
-            cairo_arc(cr, box_area.x + box_area.width - label_radius,
-                      box_area.y + box_area.height - label_radius,
-                      label_radius,
+                          box_area.y + box_area.height - LABEL_RADIUS);
+            cairo_arc(cr, box_area.x + box_area.width - LABEL_RADIUS,
+                      box_area.y + box_area.height - LABEL_RADIUS,
+                      LABEL_RADIUS,
                       0.0, M_PI/2.0);
-            cairo_line_to(cr, box_area.x + label_radius,
+            cairo_line_to(cr, box_area.x + LABEL_RADIUS,
                           box_area.y + box_area.height);
-            cairo_arc(cr, box_area.x + label_radius,
-                      box_area.y + box_area.height - label_radius,
-                      label_radius,
+            cairo_arc(cr, box_area.x + LABEL_RADIUS,
+                      box_area.y + box_area.height - LABEL_RADIUS,
+                      LABEL_RADIUS,
                       M_PI/2.0, M_PI);
             cairo_close_path(cr);
         }
@@ -2776,7 +2786,7 @@ xfdesktop_icon_view_calculate_icon_pixbuf_area(XfdesktopIconView *icon_view,
     pixbuf_area->x = 0;
     pixbuf_area->y = 0;
 
-    pix = xfdesktop_icon_peek_pixbuf(icon, ICON_SIZE);
+    pix = xfdesktop_icon_peek_pixbuf(icon, ICON_WIDTH, ICON_SIZE);
     if(G_LIKELY(pix)) {
         pixbuf_area->width = gdk_pixbuf_get_width(pix);
         pixbuf_area->height = gdk_pixbuf_get_height(pix);
@@ -2795,22 +2805,20 @@ xfdesktop_icon_view_setup_pango_layout(XfdesktopIconView *icon_view,
                                        PangoLayout *playout)
 {
     const gchar *label = xfdesktop_icon_peek_label(icon);
-    PangoRectangle prect;
 
-    pango_layout_set_width(playout, -1);
+    g_return_if_fail(XFDESKTOP_IS_ICON_VIEW(icon_view)
+                     && XFDESKTOP_IS_ICON(icon));
+
     pango_layout_set_ellipsize(playout, PANGO_ELLIPSIZE_NONE);
-    pango_layout_set_wrap(playout, PANGO_WRAP_WORD);
+    pango_layout_set_wrap(playout, PANGO_WRAP_WORD_CHAR);
+    pango_layout_set_width(playout, TEXT_WIDTH * PANGO_SCALE);
     pango_layout_set_text(playout, label, -1);
 
-    pango_layout_get_pixel_extents(playout, NULL, &prect);
-    if(prect.width > TEXT_WIDTH) {
-        if(!g_list_find(icon_view->priv->selected_icons, icon) && icon_view->priv->ellipsize_icon_labels)
-            pango_layout_set_ellipsize(playout, PANGO_ELLIPSIZE_END);
-        else {
-            pango_layout_set_ellipsize(playout, PANGO_ELLIPSIZE_NONE);
-            pango_layout_set_wrap(playout, PANGO_WRAP_WORD_CHAR);
-        }
-        pango_layout_set_width(playout, TEXT_WIDTH * PANGO_SCALE);
+    if(!xfdesktop_icon_view_is_icon_selected(icon_view, icon)
+       && icon_view->priv->ellipsize_icon_labels) {
+        /* constrain the text area */
+        pango_layout_set_height(playout, TEXT_HEIGHT * PANGO_SCALE);
+        pango_layout_set_ellipsize(playout, PANGO_ELLIPSIZE_END);
     }
 }
 
@@ -2865,17 +2873,12 @@ xfdesktop_icon_view_update_icon_extents(XfdesktopIconView *icon_view,
                                         GdkRectangle *total_extents)
 {
     GdkRectangle tmp_text;
-    gdouble label_radius = 4.0;
 
     g_return_val_if_fail(XFDESKTOP_IS_ICON_VIEW(icon_view)
                          && XFDESKTOP_IS_ICON(icon)
                          && pixbuf_extents && text_extents
                          && total_extents, FALSE);
 
-    gtk_widget_style_get(GTK_WIDGET(icon_view),
-                         "label-radius", &label_radius,
-                         NULL);
-
     if(!xfdesktop_icon_view_calculate_icon_pixbuf_area(icon_view, icon,
                                                        pixbuf_extents)
        || !xfdesktop_icon_view_shift_area_to_cell(icon_view, icon,
@@ -2884,7 +2887,7 @@ xfdesktop_icon_view_update_icon_extents(XfdesktopIconView *icon_view,
         return FALSE;
     }
     pixbuf_extents->x += CELL_PADDING + ((CELL_SIZE - CELL_PADDING * 2) - pixbuf_extents->width) / 2;
-    pixbuf_extents->y += CELL_PADDING + SPACING;
+    pixbuf_extents->y += CELL_PADDING;
 
     if(!xfdesktop_icon_view_calculate_icon_text_area(icon_view, icon,
                                                      text_extents)
@@ -2894,13 +2897,13 @@ xfdesktop_icon_view_update_icon_extents(XfdesktopIconView *icon_view,
         return FALSE;
     }
     text_extents->x += (CELL_SIZE - text_extents->width) / 2;
-    text_extents->y = pixbuf_extents->y + pixbuf_extents->height + SPACING + label_radius;
+    text_extents->y += ICON_SIZE + SPACING + LABEL_RADIUS + CELL_PADDING;
 
     tmp_text = *text_extents;
-    tmp_text.x -= label_radius;
-    tmp_text.y -= label_radius;
-    tmp_text.width += label_radius * 2;
-    tmp_text.height += label_radius * 2;
+    tmp_text.x -= LABEL_RADIUS;
+    tmp_text.y -= LABEL_RADIUS;
+    tmp_text.width += LABEL_RADIUS * 2;
+    tmp_text.height += LABEL_RADIUS * 2;
     gdk_rectangle_union(pixbuf_extents, &tmp_text, total_extents);
 
     xfdesktop_icon_set_extents(icon, pixbuf_extents, text_extents, total_extents);
@@ -2959,7 +2962,6 @@ xfdesktop_icon_view_paint_icon(XfdesktopIconView *icon_view,
     
     xfdesktop_icon_get_extents(icon, &pixbuf_extents,
                                &text_extents, &total_extents);
-    xfdesktop_icon_view_setup_pango_layout(icon_view, icon, playout);
 
     if(!xfdesktop_icon_view_update_icon_extents(icon_view, icon,
                                                 &pixbuf_extents,
@@ -2970,7 +2972,7 @@ xfdesktop_icon_view_paint_icon(XfdesktopIconView *icon_view,
                   xfdesktop_icon_peek_label(icon));
     }
 
-    if(g_list_find(icon_view->priv->selected_icons, icon)) {
+    if(xfdesktop_icon_view_is_icon_selected(icon_view, icon)) {
         if(gtk_widget_has_focus(widget))
             state = GTK_STATE_SELECTED;
         else
@@ -2979,7 +2981,7 @@ xfdesktop_icon_view_paint_icon(XfdesktopIconView *icon_view,
         state = GTK_STATE_NORMAL;
     
     if(gdk_rectangle_intersect(area, &pixbuf_extents, &intersection)) {
-        GdkPixbuf *pix = xfdesktop_icon_peek_pixbuf(icon, ICON_SIZE);
+        GdkPixbuf *pix = xfdesktop_icon_peek_pixbuf(icon, ICON_WIDTH, ICON_SIZE);
         GdkPixbuf *pix_free = NULL;
 
         if(state != GTK_STATE_NORMAL) {
@@ -3004,31 +3006,39 @@ xfdesktop_icon_view_paint_icon(XfdesktopIconView *icon_view,
         if(pix_free)
             g_object_unref(G_OBJECT(pix_free));
     }
-    
-    xfdesktop_paint_rounded_box(icon_view, state, &text_extents, area);
 
-    if (state == GTK_STATE_NORMAL) {
-        x_offset = icon_view->priv->shadow_x_offset;
-        y_offset = icon_view->priv->shadow_y_offset;
-        sh_text_col = icon_view->priv->shadow_color;
-    } else {
-        x_offset = icon_view->priv->selected_shadow_x_offset;
-        y_offset = icon_view->priv->selected_shadow_y_offset;
-        sh_text_col = icon_view->priv->selected_shadow_color;
-    }
+    /* Only redraw the text if the text area requires it.  */
+    if(gdk_rectangle_intersect(area, &text_extents, &intersection)) {
+        xfdesktop_paint_rounded_box(icon_view, state, &text_extents, area);
+
+        if (state == GTK_STATE_NORMAL) {
+            x_offset = icon_view->priv->shadow_x_offset;
+            y_offset = icon_view->priv->shadow_y_offset;
+            sh_text_col = icon_view->priv->shadow_color;
+        } else {
+            x_offset = icon_view->priv->selected_shadow_x_offset;
+            y_offset = icon_view->priv->selected_shadow_y_offset;
+            sh_text_col = icon_view->priv->selected_shadow_color;
+        }
+
+        /* draw text shadow for the label text if an offset was defined */
+        if(x_offset || y_offset) {
+            xfdesktop_icon_view_draw_text(cr, playout,
+                                          text_extents.x + x_offset,
+                                          text_extents.y + y_offset,
+                                          sh_text_col);
+        }
+
+        TRACE("painting text at %dx%d+%d+%d",
+              text_extents.width, text_extents.height,
+              text_extents.x, text_extents.y);
 
-    /* draw text shadow for the label text if an offset was defined */
-    if(x_offset || y_offset) {
         xfdesktop_icon_view_draw_text(cr, playout,
-                                      text_extents.x + x_offset,
-                                      text_extents.y + y_offset,
-                                      sh_text_col);
+                                      text_extents.x,
+                                      text_extents.y,
+                                      gtk_widget_get_style(widget)->fg);
     }
 
-    xfdesktop_icon_view_draw_text(cr, playout,
-                                  text_extents.x,
-                                  text_extents.y,
-                                  gtk_widget_get_style(widget)->fg);
 
 #if 0 /*def DEBUG*/
     {
@@ -3036,7 +3046,7 @@ xfdesktop_icon_view_paint_icon(XfdesktopIconView *icon_view,
         guint16 row, col;
 
         xfdesktop_icon_get_position(icon, &row, &col);
-        //DBG("for icon at (%hu,%hu) (%s)", row, col, xfdesktop_icon_peek_label(icon));
+        DBG("for icon at (%hu,%hu) (%s)", row, col, xfdesktop_icon_peek_label(icon));
 
         cairo_set_line_width(cr, 1.0);
 
@@ -3512,7 +3522,12 @@ xfdesktop_icon_view_icon_changed(XfdesktopIcon *icon,
                                         icon, TRUE);
 }
 
-
+static gboolean
+xfdesktop_icon_view_is_icon_selected(XfdesktopIconView *icon_view,
+                                     XfdesktopIcon *icon)
+{
+    return (g_list_find(icon_view->priv->selected_icons, icon)) == NULL ? FALSE : TRUE;
+}
 
 
 /* public api */
@@ -3904,7 +3919,7 @@ xfdesktop_icon_view_select_item(XfdesktopIconView *icon_view,
 {
     g_return_if_fail(XFDESKTOP_IS_ICON_VIEW(icon_view));
     
-    if(g_list_find(icon_view->priv->selected_icons, icon))
+    if(xfdesktop_icon_view_is_icon_selected(icon_view, icon))
         return;
     
     if(icon_view->priv->sel_mode == GTK_SELECTION_SINGLE)
diff --git a/src/xfdesktop-icon.c b/src/xfdesktop-icon.c
index ffe3d2f..b6c2ce7 100644
--- a/src/xfdesktop-icon.c
+++ b/src/xfdesktop-icon.c
@@ -40,6 +40,10 @@ struct _XfdesktopIconPrivate
     GdkRectangle pixbuf_extents;
     GdkRectangle text_extents;
     GdkRectangle total_extents;
+
+    GdkPixbuf *pix, *tooltip_pix;
+    gint cur_pix_width, cur_pix_height;
+    gint cur_tooltip_pix_width, cur_tooltip_pix_height;
 };
 
 enum {
@@ -54,6 +58,7 @@ enum {
 
 static guint __signals[SIG_N_SIGNALS] = { 0, };
 
+static void xfdesktop_icon_finalize(GObject *obj);
 
 G_DEFINE_ABSTRACT_TYPE(XfdesktopIcon, xfdesktop_icon, G_TYPE_OBJECT)
 
@@ -61,8 +66,12 @@ G_DEFINE_ABSTRACT_TYPE(XfdesktopIcon, xfdesktop_icon, G_TYPE_OBJECT)
 static void
 xfdesktop_icon_class_init(XfdesktopIconClass *klass)
 {
+    GObjectClass *gobject_class = (GObjectClass *)klass;
+
     g_type_class_add_private(klass, sizeof(XfdesktopIconPrivate));
-    
+
+    gobject_class->finalize = xfdesktop_icon_finalize;
+
     __signals[SIG_PIXBUF_CHANGED] = g_signal_new("pixbuf-changed",
                                                  XFDESKTOP_TYPE_ICON,
                                                  G_SIGNAL_RUN_LAST,
@@ -117,6 +126,13 @@ xfdesktop_icon_init(XfdesktopIcon *icon)
                                              XfdesktopIconPrivate);
 }
 
+static void
+xfdesktop_icon_finalize(GObject *obj)
+{
+    XfdesktopIcon *icon = XFDESKTOP_ICON(obj);
+
+    xfdesktop_icon_invalidate_pixbuf(icon);
+}
 
 void
 xfdesktop_icon_set_position(XfdesktopIcon *icon,
@@ -179,15 +195,26 @@ xfdesktop_icon_get_extents(XfdesktopIcon *icon,
 /*< required >*/
 GdkPixbuf *
 xfdesktop_icon_peek_pixbuf(XfdesktopIcon *icon,
-                           gint size)
+                           gint width, gint height)
 {
     XfdesktopIconClass *klass;
     
     g_return_val_if_fail(XFDESKTOP_IS_ICON(icon), NULL);
     klass = XFDESKTOP_ICON_GET_CLASS(icon);
     g_return_val_if_fail(klass->peek_pixbuf, NULL);
-    
-    return klass->peek_pixbuf(icon, size);
+
+    if(width != icon->priv->cur_pix_width || height != icon->priv->cur_pix_height)
+        xfdesktop_icon_invalidate_regular_pixbuf(icon);
+
+    if(icon->priv->pix == NULL) {
+        icon->priv->cur_pix_width = width;
+        icon->priv->cur_pix_height = height;
+
+        /* Generate a new pixbuf */
+        icon->priv->pix = klass->peek_pixbuf(icon, width, height);
+    }
+
+    return icon->priv->pix;
 }
 
 /*< required >*/
@@ -255,6 +282,31 @@ xfdesktop_icon_do_drop_dest(XfdesktopIcon *icon,
 }
 
 /*< optional >*/
+GdkPixbuf *
+xfdesktop_icon_peek_tooltip_pixbuf(XfdesktopIcon *icon,
+                                   gint width, gint height)
+{
+    XfdesktopIconClass *klass;
+
+    g_return_val_if_fail(XFDESKTOP_IS_ICON(icon), NULL);
+    klass = XFDESKTOP_ICON_GET_CLASS(icon);
+    g_return_val_if_fail(klass->peek_tooltip_pixbuf, NULL);
+
+    if(width != icon->priv->cur_tooltip_pix_width || height != icon->priv->cur_tooltip_pix_height)
+        xfdesktop_icon_invalidate_tooltip_pixbuf(icon);
+
+    if(icon->priv->tooltip_pix == NULL) {
+        icon->priv->cur_tooltip_pix_width = width;
+        icon->priv->cur_tooltip_pix_height = height;
+
+        /* Generate a new pixbuf */
+        icon->priv->tooltip_pix = klass->peek_tooltip_pixbuf(icon, width, height);
+    }
+
+    return icon->priv->tooltip_pix;
+}
+
+/*< optional >*/
 G_CONST_RETURN gchar *
 xfdesktop_icon_peek_tooltip(XfdesktopIcon *icon)
 {
@@ -325,6 +377,31 @@ xfdesktop_icon_peek_icon_view(XfdesktopIcon *icon)
     return g_object_get_data(G_OBJECT(icon), "--xfdesktop-icon-view");
 }
 
+void
+xfdesktop_icon_invalidate_regular_pixbuf(XfdesktopIcon *icon)
+{
+    if(icon->priv->pix) {
+        g_object_unref(G_OBJECT(icon->priv->pix));
+        icon->priv->pix = NULL;
+    }
+}
+
+void
+xfdesktop_icon_invalidate_tooltip_pixbuf(XfdesktopIcon *icon)
+{
+    if(icon->priv->tooltip_pix) {
+        g_object_unref(G_OBJECT(icon->priv->tooltip_pix));
+        icon->priv->tooltip_pix = NULL;
+    }
+}
+
+void
+xfdesktop_icon_invalidate_pixbuf(XfdesktopIcon *icon)
+{
+    xfdesktop_icon_invalidate_regular_pixbuf(icon);
+    xfdesktop_icon_invalidate_tooltip_pixbuf(icon);
+}
+
 /*< signal triggers >*/
 
 void
diff --git a/src/xfdesktop-icon.h b/src/xfdesktop-icon.h
index 5b750fd..00b3fe2 100644
--- a/src/xfdesktop-icon.h
+++ b/src/xfdesktop-icon.h
@@ -63,14 +63,15 @@ struct _XfdesktopIconClass
     gboolean (*activated)(XfdesktopIcon *icon);
     
     /*< virtual functions >*/
-    GdkPixbuf *(*peek_pixbuf)(XfdesktopIcon *icon, gint size);
+    GdkPixbuf *(*peek_pixbuf)(XfdesktopIcon *icon, gint width, gint height);
     G_CONST_RETURN gchar *(*peek_label)(XfdesktopIcon *icon);
     
     GdkDragAction (*get_allowed_drag_actions)(XfdesktopIcon *icon);
     
     GdkDragAction (*get_allowed_drop_actions)(XfdesktopIcon *icon, GdkDragAction *suggested_action);
     gboolean (*do_drop_dest)(XfdesktopIcon *icon, XfdesktopIcon *src_icon, GdkDragAction action);
-    
+
+    GdkPixbuf *(*peek_tooltip_pixbuf)(XfdesktopIcon *icon, gint width, gint height);
     G_CONST_RETURN gchar *(*peek_tooltip)(XfdesktopIcon *icon);
     
     void (*set_thumbnail_file)(XfdesktopIcon *icon, GFile *file);
@@ -85,8 +86,12 @@ GType xfdesktop_icon_get_type(void) G_GNUC_CONST;
 /* xfdesktop virtual function accessors */
 
 GdkPixbuf *xfdesktop_icon_peek_pixbuf(XfdesktopIcon *icon,
-                                     gint size);
+                                     gint width,
+                                     gint height);
 G_CONST_RETURN gchar *xfdesktop_icon_peek_label(XfdesktopIcon *icon);
+GdkPixbuf *xfdesktop_icon_peek_tooltip_pixbuf(XfdesktopIcon *icon,
+                                              gint width,
+                                              gint height);
 G_CONST_RETURN gchar *xfdesktop_icon_peek_tooltip(XfdesktopIcon *icon);
 
 void xfdesktop_icon_set_position(XfdesktopIcon *icon,
@@ -112,6 +117,10 @@ GtkWidget *xfdesktop_icon_peek_icon_view(XfdesktopIcon *icon);
 void xfdesktop_icon_set_thumbnail_file(XfdesktopIcon *icon, GFile *file);
 void xfdesktop_icon_delete_thumbnail(XfdesktopIcon *icon);
 
+void xfdesktop_icon_invalidate_regular_pixbuf(XfdesktopIcon *icon);
+void xfdesktop_icon_invalidate_tooltip_pixbuf(XfdesktopIcon *icon);
+void xfdesktop_icon_invalidate_pixbuf(XfdesktopIcon *icon);
+
 /*< signal triggers >*/
 
 void xfdesktop_icon_pixbuf_changed(XfdesktopIcon *icon);
diff --git a/src/xfdesktop-regular-file-icon.c b/src/xfdesktop-regular-file-icon.c
index a247a43..342f806 100644
--- a/src/xfdesktop-regular-file-icon.c
+++ b/src/xfdesktop-regular-file-icon.c
@@ -55,14 +55,13 @@
 #include "xfdesktop-regular-file-icon.h"
 
 #define EMBLEM_SYMLINK  "emblem-symbolic-link"
+#define EMBLEM_READONLY "emblem-readonly"
 
 struct _XfdesktopRegularFileIconPrivate
 {
-    GdkPixbuf *pix;
     gchar *display_name;
     gchar *tooltip;
     guint pix_opacity;
-    gint cur_pix_size;
     GFileInfo *file_info;
     GFileInfo *filesystem_info;
     GFile *file;
@@ -76,8 +75,10 @@ static void xfdesktop_regular_file_icon_set_thumbnail_file(XfdesktopIcon *icon,
 static void xfdesktop_regular_file_icon_delete_thumbnail_file(XfdesktopIcon *icon);
 
 static GdkPixbuf *xfdesktop_regular_file_icon_peek_pixbuf(XfdesktopIcon *icon,
-                                                          gint size);
+                                                          gint width, gint height);
 static G_CONST_RETURN gchar *xfdesktop_regular_file_icon_peek_label(XfdesktopIcon *icon);
+static GdkPixbuf *xfdesktop_regular_file_icon_peek_tooltip_pixbuf(XfdesktopIcon *icon,
+                                                                  gint width, gint height);
 static G_CONST_RETURN gchar *xfdesktop_regular_file_icon_peek_tooltip(XfdesktopIcon *icon);
 static GdkDragAction xfdesktop_regular_file_icon_get_allowed_drag_actions(XfdesktopIcon *icon);
 static GdkDragAction xfdesktop_regular_file_icon_get_allowed_drop_actions(XfdesktopIcon *icon,
@@ -95,12 +96,7 @@ static gboolean xfdesktop_regular_file_can_write_parent(XfdesktopFileIcon *icon)
 
 #ifdef HAVE_THUNARX
 static void xfdesktop_regular_file_icon_tfi_init(ThunarxFileInfoIface *iface);
-#endif
-
-static inline void xfdesktop_regular_file_icon_invalidate_pixbuf(XfdesktopRegularFileIcon *icon);
 
-
-#ifdef HAVE_THUNARX
 G_DEFINE_TYPE_EXTENDED(XfdesktopRegularFileIcon, xfdesktop_regular_file_icon,
                        XFDESKTOP_TYPE_FILE_ICON, 0,
                        G_IMPLEMENT_INTERFACE(THUNARX_TYPE_FILE_INFO,
@@ -126,6 +122,7 @@ xfdesktop_regular_file_icon_class_init(XfdesktopRegularFileIconClass *klass)
     
     icon_class->peek_pixbuf = xfdesktop_regular_file_icon_peek_pixbuf;
     icon_class->peek_label = xfdesktop_regular_file_icon_peek_label;
+    icon_class->peek_tooltip_pixbuf = xfdesktop_regular_file_icon_peek_tooltip_pixbuf;
     icon_class->peek_tooltip = xfdesktop_regular_file_icon_peek_tooltip;
     icon_class->get_allowed_drag_actions = xfdesktop_regular_file_icon_get_allowed_drag_actions;
     icon_class->get_allowed_drop_actions = xfdesktop_regular_file_icon_get_allowed_drop_actions;
@@ -158,11 +155,8 @@ xfdesktop_regular_file_icon_finalize(GObject *obj)
     GtkIconTheme *itheme = gtk_icon_theme_get_for_screen(icon->priv->gscreen);
     
     g_signal_handlers_disconnect_by_func(G_OBJECT(itheme),
-                                         G_CALLBACK(xfdesktop_regular_file_icon_invalidate_pixbuf),
+                                         G_CALLBACK(xfdesktop_icon_invalidate_pixbuf),
                                          icon);
-
-    if(icon->priv->pix)
-        g_object_unref(G_OBJECT(icon->priv->pix));
     
     if(icon->priv->file_info)
         g_object_unref(icon->priv->file_info);
@@ -173,7 +167,7 @@ xfdesktop_regular_file_icon_finalize(GObject *obj)
     g_object_unref(icon->priv->file);
     
     g_free(icon->priv->display_name);
-    
+
     if(icon->priv->tooltip)
         g_free(icon->priv->tooltip);
 
@@ -200,15 +194,6 @@ xfdesktop_regular_file_icon_tfi_init(ThunarxFileInfoIface *iface)
 }
 #endif
 
-static inline void
-xfdesktop_regular_file_icon_invalidate_pixbuf(XfdesktopRegularFileIcon *icon)
-{
-    if(icon->priv->pix) {
-        g_object_unref(G_OBJECT(icon->priv->pix));
-        icon->priv->pix = NULL;
-    }
-}
-
 static void
 xfdesktop_regular_file_icon_delete_thumbnail_file(XfdesktopIcon *icon)
 {
@@ -224,8 +209,10 @@ xfdesktop_regular_file_icon_delete_thumbnail_file(XfdesktopIcon *icon)
         file_icon->priv->thumbnail_file = NULL;
     }
 
-    xfdesktop_regular_file_icon_invalidate_pixbuf(file_icon);
-    xfdesktop_icon_pixbuf_changed(XFDESKTOP_ICON(icon));
+    xfdesktop_file_icon_invalidate_icon(XFDESKTOP_FILE_ICON(icon));
+
+    xfdesktop_icon_invalidate_pixbuf(icon);
+    xfdesktop_icon_pixbuf_changed(icon);
 }
 
 static void
@@ -243,124 +230,154 @@ xfdesktop_regular_file_icon_set_thumbnail_file(XfdesktopIcon *icon, GFile *file)
 
     file_icon->priv->thumbnail_file = file;
 
-    xfdesktop_regular_file_icon_invalidate_pixbuf(file_icon);
-    xfdesktop_icon_pixbuf_changed(XFDESKTOP_ICON(icon));
+    xfdesktop_file_icon_invalidate_icon(XFDESKTOP_FILE_ICON(icon));
+
+    xfdesktop_icon_invalidate_pixbuf(icon);
+    xfdesktop_icon_pixbuf_changed(icon);
 }
 
-static GdkPixbuf *
-xfdesktop_regular_file_icon_peek_pixbuf(XfdesktopIcon *icon,
-                                        gint size)
+static GIcon *
+xfdesktop_load_icon_from_desktop_file(XfdesktopRegularFileIcon *regular_icon)
 {
-    XfdesktopRegularFileIcon *file_icon = XFDESKTOP_REGULAR_FILE_ICON(icon);
-    gchar *icon_name = NULL;
-    GdkPixbuf *emblem_pix = NULL;
-
-    if(size != file_icon->priv->cur_pix_size)
-        xfdesktop_regular_file_icon_invalidate_pixbuf(file_icon);
-
-    if(!file_icon->priv->pix) {
-        GIcon *gicon = NULL;
-
-        /* create a GFile for the $HOME/.thumbnails/ directory */
-        gchar *thumbnail_dir_path = g_build_filename(xfce_get_homedir(), 
-                                                     ".thumbnails", NULL);
-        GFile *thumbnail_dir = g_file_new_for_path(thumbnail_dir_path);
-
-        if(g_file_has_prefix(file_icon->priv->file, thumbnail_dir)) {
-            /* use the filename as custom icon name for thumbnails */
-            icon_name = g_file_get_path(file_icon->priv->file);
-
-            /* release thumbnail path */
-            g_object_unref(thumbnail_dir);
-            g_free(thumbnail_dir_path);
-        } else if(xfdesktop_file_utils_is_desktop_file(file_icon->priv->file_info)) {
-            gchar *contents;
-            gsize length;
-
-            /* try to load the file into memory */
-            if(g_file_load_contents(file_icon->priv->file, NULL, &contents, &length, 
-                                    NULL, NULL)) 
-            {
-                /* allocate a new key file */
-                GKeyFile *key_file = g_key_file_new();
-
-                /* try to parse the key file from the contents of the file */
-                if (g_key_file_load_from_data(key_file, contents, length, 0, NULL)) {
-                    /* try to determine the custom icon name */
-                    icon_name = g_key_file_get_string(key_file,
-                                                      G_KEY_FILE_DESKTOP_GROUP,
-                                                      G_KEY_FILE_DESKTOP_KEY_ICON,
-                                                      NULL);
-                }
-
-                /* free key file and in-memory data */
-                g_key_file_free(key_file);
-                g_free(contents);
-            }
-        } else {
-            /* If we have a thumbnail then they are enabled, use it. */
-            if(file_icon->priv->thumbnail_file)
-            {
-                file_icon->priv->pix = gdk_pixbuf_new_from_file_at_size(g_file_get_path(file_icon->priv->thumbnail_file),
-                                                                        size, size,
-                                                                        NULL);
-            }
-        }
+    gchar *contents;
+    gsize length;
+    GIcon *gicon = NULL;
 
-        /* load the symlink emblem if necessary */
-        if(g_file_info_get_attribute_boolean(file_icon->priv->file_info, 
-                                             G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK)) 
-        {
-            GtkIconTheme *itheme = gtk_icon_theme_get_default();
-            gint sym_pix_size = size * 2 / 3;
-            
-            emblem_pix = gtk_icon_theme_load_icon(itheme, EMBLEM_SYMLINK,
-                                                  sym_pix_size, ITHEME_FLAGS,
-                                                  NULL);
-            if(emblem_pix) {
-                if(gdk_pixbuf_get_width(emblem_pix) != sym_pix_size
-                   || gdk_pixbuf_get_height(emblem_pix) != sym_pix_size)
-                {
-                    GdkPixbuf *tmp = gdk_pixbuf_scale_simple(emblem_pix,
-                                                             sym_pix_size,
-                                                             sym_pix_size,
-                                                             GDK_INTERP_BILINEAR);
-                    g_object_unref(emblem_pix);
-                    emblem_pix = tmp;
-                }
+    /* try to load the file into memory */
+    if(g_file_load_contents(regular_icon->priv->file, NULL, &contents, &length,
+                            NULL, NULL))
+    {
+        /* allocate a new key file */
+        GKeyFile *key_file = g_key_file_new();
+
+        /* try to parse the key file from the contents of the file */
+        if (g_key_file_load_from_data(key_file, contents, length, 0, NULL)) {
+            gchar *icon_name;
+            /* try to determine the custom icon name */
+            icon_name = g_key_file_get_string(key_file,
+                                              G_KEY_FILE_DESKTOP_GROUP,
+                                              G_KEY_FILE_DESKTOP_KEY_ICON,
+                                              NULL);
+
+            /* Create the themed icon for it */
+            if(icon_name) {
+                gicon = g_themed_icon_new(icon_name);
+                g_free(icon_name);
             }
         }
 
-        if(file_icon->priv->file_info)
-            gicon = g_file_info_get_icon(file_icon->priv->file_info);
+        /* free key file and in-memory data */
+        g_key_file_free(key_file);
+        g_free(contents);
+    }
 
-        if(file_icon->priv->pix) {
-            if(emblem_pix) {
-                gint emblem_pix_size = gdk_pixbuf_get_width(emblem_pix);
-                gint dest_size = size - emblem_pix_size;
+    return gicon;
+}
 
-                /* We have to add the emblem */
-                gdk_pixbuf_composite(emblem_pix, file_icon->priv->pix,
-                                     dest_size, dest_size,
-                                     emblem_pix_size, emblem_pix_size,
-                                     dest_size, dest_size,
-                                     1.0, 1.0, GDK_INTERP_BILINEAR, 255);
-            }
-        } else {
-            file_icon->priv->pix = xfdesktop_file_utils_get_icon(icon_name, gicon,
-                                                                 size, emblem_pix,
-                                                                 file_icon->priv->pix_opacity);
+static GIcon *
+xfdesktop_regular_file_icon_load_icon(XfdesktopIcon *icon)
+{
+    XfdesktopRegularFileIcon *regular_icon = XFDESKTOP_REGULAR_FILE_ICON(icon);
+    XfdesktopFileIcon *file_icon = XFDESKTOP_FILE_ICON(icon);
+    GIcon *gicon = NULL;
+
+    TRACE("entering");
+
+    /* Try to load the icon referenced in the .desktop file */
+    if(xfdesktop_file_utils_is_desktop_file(regular_icon->priv->file_info)) {
+        gicon = xfdesktop_load_icon_from_desktop_file(regular_icon);
+    } else {
+        /* If we have a thumbnail then they are enabled, use it. */
+        if(regular_icon->priv->thumbnail_file) {
+            gchar *file = g_file_get_path(regular_icon->priv->file);
+            gchar *mimetype = xfdesktop_get_file_mimetype(file);
+
+            /* Don't use thumbnails for svg, use the file itself */
+            if(g_strcmp0(mimetype, "image/svg+xml") == 0)
+                gicon = g_file_icon_new(regular_icon->priv->file);
+            else
+                gicon = g_file_icon_new(regular_icon->priv->thumbnail_file);
+
+            g_free(mimetype);
+            g_free(file);
         }
-        
-        file_icon->priv->cur_pix_size = size;
+    }
 
-        if(emblem_pix)
-             g_object_unref(emblem_pix);
-        
-        g_free(icon_name);
+    /* If we still don't have an icon, use the default */
+    if(!G_IS_ICON(gicon)) {
+        gicon = g_file_info_get_icon(regular_icon->priv->file_info);
+        if(G_IS_ICON(gicon))
+            g_object_ref(gicon);
     }
-    
-    return file_icon->priv->pix;
+
+    g_object_set(file_icon, "gicon", gicon, NULL);
+
+    /* Add any user set emblems */
+    gicon = xfdesktop_file_icon_add_emblems(file_icon);
+
+    /* load the read only emblem if necessary */
+    if(!g_file_info_get_attribute_boolean(regular_icon->priv->file_info,
+                                          G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
+    {
+        GIcon *themed_icon = g_themed_icon_new(EMBLEM_READONLY);
+        GEmblem *emblem = g_emblem_new(themed_icon);
+
+        g_emblemed_icon_add_emblem(G_EMBLEMED_ICON(gicon), emblem);
+
+        g_object_unref(emblem);
+        g_object_unref(themed_icon);
+    }
+
+    /* load the symlink emblem if necessary */
+    if(g_file_info_get_attribute_boolean(regular_icon->priv->file_info,
+                                         G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK))
+    {
+        GIcon *themed_icon = g_themed_icon_new(EMBLEM_SYMLINK);
+        GEmblem *emblem = g_emblem_new(themed_icon);
+
+        g_emblemed_icon_add_emblem(G_EMBLEMED_ICON(gicon), emblem);
+
+        g_object_unref(emblem);
+        g_object_unref(themed_icon);
+    }
+
+    return gicon;
+}
+
+static GdkPixbuf *
+xfdesktop_regular_file_icon_peek_pixbuf(XfdesktopIcon *icon,
+                                        gint width, gint height)
+{
+    XfdesktopRegularFileIcon *regular_icon = XFDESKTOP_REGULAR_FILE_ICON(icon);
+    GIcon *gicon = NULL;
+    GdkPixbuf *pix = NULL;
+
+    if(!xfdesktop_file_icon_has_gicon(XFDESKTOP_FILE_ICON(icon)))
+        gicon = xfdesktop_regular_file_icon_load_icon(icon);
+    else
+        g_object_get(XFDESKTOP_FILE_ICON(icon), "gicon", &gicon, NULL);
+
+    pix = xfdesktop_file_utils_get_icon(gicon, width, height,
+                                        regular_icon->priv->pix_opacity);
+
+    return pix;
+}
+
+static GdkPixbuf *
+xfdesktop_regular_file_icon_peek_tooltip_pixbuf(XfdesktopIcon *icon,
+                                                gint width, gint height)
+{
+    GIcon *gicon = NULL;
+    GdkPixbuf *tooltip_pix = NULL;
+
+    if(!xfdesktop_file_icon_has_gicon(XFDESKTOP_FILE_ICON(icon)))
+        gicon = xfdesktop_regular_file_icon_load_icon(icon);
+    else
+        g_object_get(XFDESKTOP_FILE_ICON(icon), "gicon", &gicon, NULL);
+
+    tooltip_pix = xfdesktop_file_utils_get_icon(gicon, width, height, 100);
+
+    return tooltip_pix;
 }
 
 static G_CONST_RETURN gchar *
@@ -702,7 +719,8 @@ xfdesktop_regular_file_icon_update_file_info(XfdesktopFileIcon *icon,
     regular_file_icon->priv->tooltip = NULL;
     
     /* not really easy to check if this changed or not, so just invalidate it */
-    xfdesktop_regular_file_icon_invalidate_pixbuf(regular_file_icon);
+    xfdesktop_file_icon_invalidate_icon(XFDESKTOP_FILE_ICON(icon));
+    xfdesktop_icon_invalidate_pixbuf(XFDESKTOP_ICON(icon));
     xfdesktop_icon_pixbuf_changed(XFDESKTOP_ICON(icon));
 }
 
@@ -744,7 +762,7 @@ xfdesktop_regular_file_icon_new(GFile *file,
 
     g_signal_connect_swapped(G_OBJECT(gtk_icon_theme_get_for_screen(screen)),
                              "changed",
-                             G_CALLBACK(xfdesktop_regular_file_icon_invalidate_pixbuf),
+                             G_CALLBACK(xfdesktop_icon_invalidate_pixbuf),
                              regular_file_icon);
     
     return regular_file_icon;
@@ -761,6 +779,6 @@ xfdesktop_regular_file_icon_set_pixbuf_opacity(XfdesktopRegularFileIcon *icon,
     
     icon->priv->pix_opacity = opacity;
     
-    xfdesktop_regular_file_icon_invalidate_pixbuf(icon);
+    xfdesktop_icon_invalidate_pixbuf(XFDESKTOP_ICON(icon));
     xfdesktop_icon_pixbuf_changed(XFDESKTOP_ICON(icon));
 }
diff --git a/src/xfdesktop-special-file-icon.c b/src/xfdesktop-special-file-icon.c
index 955263c..fb418ad 100644
--- a/src/xfdesktop-special-file-icon.c
+++ b/src/xfdesktop-special-file-icon.c
@@ -55,9 +55,7 @@
 struct _XfdesktopSpecialFileIconPrivate
 {
     XfdesktopSpecialFileIconType type;
-    GdkPixbuf *pix;
     gchar *tooltip;
-    gint cur_pix_size;
     GFileMonitor *monitor;
     GFileInfo *file_info;
     GFileInfo *filesystem_info;
@@ -71,8 +69,10 @@ struct _XfdesktopSpecialFileIconPrivate
 static void xfdesktop_special_file_icon_finalize(GObject *obj);
 
 static GdkPixbuf *xfdesktop_special_file_icon_peek_pixbuf(XfdesktopIcon *icon,
-                                                          gint size);
+                                                          gint width, gint height);
 static G_CONST_RETURN gchar *xfdesktop_special_file_icon_peek_label(XfdesktopIcon *icon);
+static GdkPixbuf *xfdesktop_special_file_icon_peek_tooltip_pixbuf(XfdesktopIcon *icon,
+                                                                  gint width, gint height);
 static G_CONST_RETURN gchar *xfdesktop_special_file_icon_peek_tooltip(XfdesktopIcon *icon);
 static GdkDragAction xfdesktop_special_file_icon_get_allowed_drag_actions(XfdesktopIcon *icon);
 static GdkDragAction xfdesktop_special_file_icon_get_allowed_drop_actions(XfdesktopIcon *icon,
@@ -95,13 +95,7 @@ static void xfdesktop_special_file_icon_update_trash_count(XfdesktopSpecialFileI
 
 #ifdef HAVE_THUNARX
 static void xfdesktop_special_file_icon_tfi_init(ThunarxFileInfoIface *iface);
-#endif
-
-
-static inline void xfdesktop_special_file_icon_invalidate_pixbuf(XfdesktopSpecialFileIcon *icon);
 
-
-#ifdef HAVE_THUNARX
 G_DEFINE_TYPE_EXTENDED(XfdesktopSpecialFileIcon, xfdesktop_special_file_icon,
                        XFDESKTOP_TYPE_FILE_ICON, 0,
                        G_IMPLEMENT_INTERFACE(THUNARX_TYPE_FILE_INFO,
@@ -127,6 +121,7 @@ xfdesktop_special_file_icon_class_init(XfdesktopSpecialFileIconClass *klass)
     
     icon_class->peek_pixbuf = xfdesktop_special_file_icon_peek_pixbuf;
     icon_class->peek_label = xfdesktop_special_file_icon_peek_label;
+    icon_class->peek_tooltip_pixbuf = xfdesktop_special_file_icon_peek_tooltip_pixbuf;
     icon_class->peek_tooltip = xfdesktop_special_file_icon_peek_tooltip;
     icon_class->get_allowed_drag_actions = xfdesktop_special_file_icon_get_allowed_drag_actions;
     icon_class->get_allowed_drop_actions = xfdesktop_special_file_icon_get_allowed_drop_actions;
@@ -155,12 +150,9 @@ xfdesktop_special_file_icon_finalize(GObject *obj)
     GtkIconTheme *itheme = gtk_icon_theme_get_for_screen(icon->priv->gscreen);
     
     g_signal_handlers_disconnect_by_func(G_OBJECT(itheme),
-                                         G_CALLBACK(xfdesktop_special_file_icon_invalidate_pixbuf),
+                                         G_CALLBACK(xfdesktop_icon_invalidate_pixbuf),
                                          icon);
 
-    if(icon->priv->pix)
-        g_object_unref(G_OBJECT(icon->priv->pix));
-
     if(icon->priv->monitor) {
         g_signal_handlers_disconnect_by_func(icon->priv->monitor,
                                              G_CALLBACK(xfdesktop_special_file_icon_changed),
@@ -172,7 +164,7 @@ xfdesktop_special_file_icon_finalize(GObject *obj)
 
     if(icon->priv->file_info)
         g_object_unref(icon->priv->file_info);
-    
+
     if(icon->priv->tooltip)
         g_free(icon->priv->tooltip);
     
@@ -207,59 +199,88 @@ xfdesktop_special_file_icon_tfi_init(ThunarxFileInfoIface *iface)
 }
 #endif  /* HAVE_THUNARX */
 
-static inline void
-xfdesktop_special_file_icon_invalidate_pixbuf(XfdesktopSpecialFileIcon *icon)
-{
-    if(icon->priv->pix) {
-        g_object_unref(G_OBJECT(icon->priv->pix));
-        icon->priv->pix = NULL;
-    }
-}
 
-static GdkPixbuf *
-xfdesktop_special_file_icon_peek_pixbuf(XfdesktopIcon *icon,
-                                        gint size)
+static GIcon *
+xfdesktop_special_file_icon_load_icon(XfdesktopIcon *icon)
 {
-    XfdesktopSpecialFileIcon *file_icon = XFDESKTOP_SPECIAL_FILE_ICON(icon);
-    GIcon *gicon = NULL;
-    const gchar *custom_icon_name = NULL;
+    XfdesktopSpecialFileIcon *special_icon = XFDESKTOP_SPECIAL_FILE_ICON(icon);
+    XfdesktopFileIcon *file_icon = XFDESKTOP_FILE_ICON(icon);
+    gchar *icon_name = NULL;
     GFile *parent = NULL;
+    GIcon *gicon = NULL;
 
-    if(size != file_icon->priv->cur_pix_size)
-        xfdesktop_special_file_icon_invalidate_pixbuf(file_icon);
-
-    /* Already have a good icon */
-    if(file_icon->priv->pix != NULL)
-        return file_icon->priv->pix;
+    TRACE("entering");
 
     /* use a custom icon name for the local filesystem root */
-    parent = g_file_get_parent(file_icon->priv->file);
-    if(!parent && g_file_has_uri_scheme(file_icon->priv->file, "file"))
-        custom_icon_name = "drive-harddisk";
+    parent = g_file_get_parent(special_icon->priv->file);
+    if(!parent && g_file_has_uri_scheme(special_icon->priv->file, "file"))
+        icon_name = g_strdup("drive-harddisk");
+
     if(parent)
         g_object_unref(parent);
 
     /* use a custom icon for the trash, based on it having files
      * the user can delete */
-    if(file_icon->priv->type == XFDESKTOP_SPECIAL_FILE_ICON_TRASH) {
-        if(file_icon->priv->trash_item_count == 0)
-            custom_icon_name = "user-trash";
+    if(special_icon->priv->type == XFDESKTOP_SPECIAL_FILE_ICON_TRASH) {
+        if(special_icon->priv->trash_item_count == 0)
+            icon_name = g_strdup("user-trash");
         else
-            custom_icon_name = "user-trash-full";
+            icon_name = g_strdup("user-trash-full");
     }
 
-    if(file_icon->priv->file_info)
-        gicon = g_file_info_get_icon(file_icon->priv->file_info);
+    /* Create the themed icon for it */
+    if(icon_name) {
+        gicon = g_themed_icon_new(icon_name);
+        g_free(icon_name);
+    }
 
-    file_icon->priv->pix = xfdesktop_file_utils_get_icon(custom_icon_name,
-                                                         gicon,
-                                                         size,
-                                                         NULL,
-                                                         100);
+    /* If we still don't have an icon, use the default */
+    if(!G_IS_ICON(gicon)) {
+        gicon = g_file_info_get_icon(special_icon->priv->file_info);
+        if(G_IS_ICON(gicon))
+            g_object_ref(gicon);
+    }
 
-    file_icon->priv->cur_pix_size = size;
-    
-    return file_icon->priv->pix;
+    g_object_set(file_icon, "gicon", gicon, NULL);
+
+    /* Add any user set emblems */
+    gicon = xfdesktop_file_icon_add_emblems(file_icon);
+
+    return gicon;
+}
+
+static GdkPixbuf *
+xfdesktop_special_file_icon_peek_pixbuf(XfdesktopIcon *icon,
+                                        gint width, gint height)
+{
+    GIcon *gicon = NULL;
+    GdkPixbuf *pix = NULL;
+
+    if(!xfdesktop_file_icon_has_gicon(XFDESKTOP_FILE_ICON(icon)))
+        gicon = xfdesktop_special_file_icon_load_icon(icon);
+    else
+        g_object_get(XFDESKTOP_FILE_ICON(icon), "gicon", &gicon, NULL);
+
+    pix = xfdesktop_file_utils_get_icon(gicon, height, height, 100);
+
+    return pix;
+}
+
+static GdkPixbuf *
+xfdesktop_special_file_icon_peek_tooltip_pixbuf(XfdesktopIcon *icon,
+                                                gint width, gint height)
+{
+    GIcon *gicon = NULL;
+    GdkPixbuf *tooltip_pix = NULL;
+
+    if(!xfdesktop_file_icon_has_gicon(XFDESKTOP_FILE_ICON(icon)))
+        gicon = xfdesktop_special_file_icon_load_icon(icon);
+    else
+        g_object_get(XFDESKTOP_FILE_ICON(icon), "gicon", &gicon, NULL);
+
+    tooltip_pix = xfdesktop_file_utils_get_icon(gicon, height, height, 100);
+
+    return tooltip_pix;
 }
 
 static G_CONST_RETURN gchar *
@@ -607,7 +628,8 @@ xfdesktop_special_file_icon_changed(GFileMonitor *monitor,
     special_file_icon->priv->tooltip = NULL;
 
     /* update the icon */
-    xfdesktop_special_file_icon_invalidate_pixbuf(special_file_icon);
+    xfdesktop_file_icon_invalidate_icon(XFDESKTOP_FILE_ICON(special_file_icon));
+    xfdesktop_icon_invalidate_pixbuf(XFDESKTOP_ICON(special_file_icon));
     xfdesktop_icon_pixbuf_changed(XFDESKTOP_ICON(special_file_icon));
 }
 
@@ -710,7 +732,7 @@ xfdesktop_special_file_icon_new(XfdesktopSpecialFileIconType type,
 
     g_signal_connect_swapped(G_OBJECT(gtk_icon_theme_get_for_screen(screen)),
                              "changed",
-                             G_CALLBACK(xfdesktop_special_file_icon_invalidate_pixbuf),
+                             G_CALLBACK(xfdesktop_icon_invalidate_pixbuf),
                              special_file_icon);
 
     special_file_icon->priv->monitor = g_file_monitor(special_file_icon->priv->file,
diff --git a/src/xfdesktop-volume-icon.c b/src/xfdesktop-volume-icon.c
index d642f89..c01b7f2 100644
--- a/src/xfdesktop-volume-icon.c
+++ b/src/xfdesktop-volume-icon.c
@@ -60,9 +60,7 @@
 
 struct _XfdesktopVolumeIconPrivate
 {
-    GdkPixbuf *pix;
     gchar *tooltip;
-    gint cur_pix_size;
     gchar *label;
     GVolume *volume;
     GFileInfo *file_info;
@@ -77,8 +75,10 @@ struct _XfdesktopVolumeIconPrivate
 static void xfdesktop_volume_icon_finalize(GObject *obj);
 
 static GdkPixbuf *xfdesktop_volume_icon_peek_pixbuf(XfdesktopIcon *icon,
-                                                    gint size);
+                                                    gint width, gint height);
 static G_CONST_RETURN gchar *xfdesktop_volume_icon_peek_label(XfdesktopIcon *icon);
+static GdkPixbuf *xfdesktop_volume_icon_peek_tooltip_pixbuf(XfdesktopIcon *icon,
+                                                            gint width, gint height);
 static G_CONST_RETURN gchar *xfdesktop_volume_icon_peek_tooltip(XfdesktopIcon *icon);
 static GdkDragAction xfdesktop_volume_icon_get_allowed_drag_actions(XfdesktopIcon *icon);
 static GdkDragAction xfdesktop_volume_icon_get_allowed_drop_actions(XfdesktopIcon *icon,
@@ -101,12 +101,7 @@ static void xfdesktop_volume_icon_changed(GVolume *volume,
 
 #ifdef HAVE_THUNARX
 static void xfdesktop_volume_icon_tfi_init(ThunarxFileInfoIface *iface);
-#endif
-
-static inline void xfdesktop_volume_icon_invalidate_pixbuf(XfdesktopVolumeIcon *icon);
-
 
-#ifdef HAVE_THUNARX
 G_DEFINE_TYPE_EXTENDED(XfdesktopVolumeIcon, xfdesktop_volume_icon,
                        XFDESKTOP_TYPE_FILE_ICON, 0,
                        G_IMPLEMENT_INTERFACE(THUNARX_TYPE_FILE_INFO,
@@ -138,6 +133,7 @@ xfdesktop_volume_icon_class_init(XfdesktopVolumeIconClass *klass)
     
     icon_class->peek_pixbuf = xfdesktop_volume_icon_peek_pixbuf;
     icon_class->peek_label = xfdesktop_volume_icon_peek_label;
+    icon_class->peek_tooltip_pixbuf = xfdesktop_volume_icon_peek_tooltip_pixbuf;
     icon_class->peek_tooltip = xfdesktop_volume_icon_peek_tooltip;
     icon_class->get_allowed_drag_actions = xfdesktop_volume_icon_get_allowed_drag_actions;
     icon_class->get_allowed_drop_actions = xfdesktop_volume_icon_get_allowed_drop_actions;
@@ -171,17 +167,14 @@ xfdesktop_volume_icon_finalize(GObject *obj)
         g_source_remove(icon->priv->changed_timeout_id);
     
     g_signal_handlers_disconnect_by_func(G_OBJECT(itheme),
-                                         G_CALLBACK(xfdesktop_volume_icon_invalidate_pixbuf),
+                                         G_CALLBACK(xfdesktop_icon_invalidate_pixbuf),
                                          icon);
     
     if(icon->priv->label) {
         g_free(icon->priv->label);
         icon->priv->label = NULL;
     }
-    
-    if(icon->priv->pix)
-        g_object_unref(G_OBJECT(icon->priv->pix));
-    
+
     if(icon->priv->file_info)
         g_object_unref(icon->priv->file_info);
 
@@ -193,7 +186,7 @@ xfdesktop_volume_icon_finalize(GObject *obj)
 
     if(icon->priv->volume)
         g_object_unref(G_OBJECT(icon->priv->volume));
-    
+
     if(icon->priv->tooltip)
         g_free(icon->priv->tooltip);
     
@@ -218,15 +211,6 @@ xfdesktop_volume_icon_tfi_init(ThunarxFileInfoIface *iface)
 #endif  /* HAVE_THUNARX */
 
 
-static inline void
-xfdesktop_volume_icon_invalidate_pixbuf(XfdesktopVolumeIcon *icon)
-{
-    if(icon->priv->pix) {
-        g_object_unref(G_OBJECT(icon->priv->pix));
-        icon->priv->pix = NULL;
-    }
-}
-
 static gboolean
 xfdesktop_volume_icon_is_mounted(XfdesktopIcon *icon)
 {
@@ -252,41 +236,72 @@ xfdesktop_volume_icon_is_mounted(XfdesktopIcon *icon)
     return ret;
 }
 
+static GIcon *
+xfdesktop_volume_icon_load_icon(XfdesktopIcon *icon)
+{
+    XfdesktopVolumeIcon *volume_icon = XFDESKTOP_VOLUME_ICON(icon);
+    XfdesktopFileIcon *file_icon = XFDESKTOP_FILE_ICON(icon);
+    GIcon *gicon = NULL;
+
+    TRACE("entering");
+
+    /* load icon and keep a ref to it */
+    if(volume_icon->priv->volume) {
+        gicon = g_volume_get_icon(volume_icon->priv->volume);
+
+        if(G_IS_ICON(gicon))
+            g_object_ref(gicon);
+
+        g_object_set(file_icon, "gicon", gicon, NULL);
+
+        /* Add any user set emblems */
+        gicon = xfdesktop_file_icon_add_emblems(file_icon);
+    }
+
+    return gicon;
+}
+
 static GdkPixbuf *
 xfdesktop_volume_icon_peek_pixbuf(XfdesktopIcon *icon,
-                                  gint size)
+                                  gint width, gint height)
 {
-    XfdesktopVolumeIcon *file_icon = XFDESKTOP_VOLUME_ICON(icon);
+    gint opacity = 100;
+    GIcon *gicon = NULL;
+    GdkPixbuf *pix = NULL;
     
     g_return_val_if_fail(XFDESKTOP_IS_VOLUME_ICON(icon), NULL);
-    
-    if(size != file_icon->priv->cur_pix_size)
-        xfdesktop_volume_icon_invalidate_pixbuf(file_icon);
 
-    if(!file_icon->priv->pix) {
-        GIcon *gicon = NULL;
+    if(!xfdesktop_file_icon_has_gicon(XFDESKTOP_FILE_ICON(icon)))
+        gicon = xfdesktop_volume_icon_load_icon(icon);
+    else
+        g_object_get(XFDESKTOP_FILE_ICON(icon), "gicon", &gicon, NULL);
 
-        if(file_icon->priv->volume)
-            gicon = g_volume_get_icon(file_icon->priv->volume);
+    /* If the volume isn't mounted show it as semi-transparent */
+    if(!xfdesktop_volume_icon_is_mounted(icon))
+        opacity = 50;
 
-        file_icon->priv->pix = xfdesktop_file_utils_get_icon(NULL, gicon, size, 
-                                                             NULL, 100);
+    pix = xfdesktop_file_utils_get_icon(gicon, height, height, opacity);
 
-        /* If the volume isn't mounted show it as semi-transparent */
-        if(!xfdesktop_volume_icon_is_mounted(icon)) {
-            GdkPixbuf *temp;
-            temp = exo_gdk_pixbuf_lucent(file_icon->priv->pix, 50);
+    return pix;
+}
 
-            if(temp != NULL) {
-                g_object_unref(G_OBJECT(file_icon->priv->pix));
-                file_icon->priv->pix = temp;
-            }
-        }
-        
-        file_icon->priv->cur_pix_size = size;
-    }
-    
-    return file_icon->priv->pix;
+static GdkPixbuf *
+xfdesktop_volume_icon_peek_tooltip_pixbuf(XfdesktopIcon *icon,
+                                          gint width, gint height)
+{
+    GIcon *gicon = NULL;
+    GdkPixbuf *tooltip_pix = NULL;
+
+    g_return_val_if_fail(XFDESKTOP_IS_VOLUME_ICON(icon), NULL);
+
+    if(!xfdesktop_file_icon_has_gicon(XFDESKTOP_FILE_ICON(icon)))
+        gicon = xfdesktop_volume_icon_load_icon(icon);
+    else
+        g_object_get(XFDESKTOP_FILE_ICON(icon), "gicon", &gicon, NULL);
+
+    tooltip_pix = xfdesktop_file_utils_get_icon(gicon, height, height, 100);
+
+    return tooltip_pix;
 }
 
 G_CONST_RETURN gchar *
@@ -891,7 +906,8 @@ xfdesktop_volume_icon_update_file_info(XfdesktopFileIcon *icon,
     }
 
     /* not really easy to check if this changed or not, so just invalidate it */
-    xfdesktop_volume_icon_invalidate_pixbuf(volume_icon);
+    xfdesktop_file_icon_invalidate_icon(XFDESKTOP_FILE_ICON(icon));
+    xfdesktop_icon_invalidate_pixbuf(XFDESKTOP_ICON(icon));
     xfdesktop_icon_pixbuf_changed(XFDESKTOP_ICON(icon));
 }
 
@@ -986,7 +1002,7 @@ volume_icon_changed_timeout(XfdesktopVolumeIcon *volume_icon)
         }
 
         /* not really easy to check if this changed or not, so just invalidate it */
-        xfdesktop_volume_icon_invalidate_pixbuf(volume_icon);
+        xfdesktop_icon_invalidate_pixbuf(XFDESKTOP_ICON(volume_icon));
         xfdesktop_icon_pixbuf_changed(XFDESKTOP_ICON(volume_icon));
 
         /* finalize the timeout source */
@@ -1081,7 +1097,7 @@ xfdesktop_volume_icon_new(GVolume *volume,
 
     g_signal_connect_swapped(G_OBJECT(gtk_icon_theme_get_for_screen(screen)),
                              "changed",
-                             G_CALLBACK(xfdesktop_volume_icon_invalidate_pixbuf),
+                             G_CALLBACK(xfdesktop_icon_invalidate_pixbuf),
                              volume_icon);
 
     g_signal_connect(volume, "changed", 
diff --git a/src/xfdesktop-window-icon.c b/src/xfdesktop-window-icon.c
index c2a9b62..adeb2f7 100644
--- a/src/xfdesktop-window-icon.c
+++ b/src/xfdesktop-window-icon.c
@@ -35,8 +35,6 @@
 struct _XfdesktopWindowIconPrivate
 {
     gint workspace;
-    GdkPixbuf *pix;
-    gint cur_pix_size;
     gchar *label;
     WnckWindow *window;
 };
@@ -44,7 +42,7 @@ struct _XfdesktopWindowIconPrivate
 static void xfdesktop_window_icon_finalize(GObject *obj);
 
 static GdkPixbuf *xfdesktop_window_icon_peek_pixbuf(XfdesktopIcon *icon,
-                                                   gint size);
+                                                   gint width, gint height);
 static G_CONST_RETURN gchar *xfdesktop_window_icon_peek_label(XfdesktopIcon *icon);
 
 static gboolean xfdesktop_window_icon_activated(XfdesktopIcon *icon);
@@ -90,9 +88,6 @@ xfdesktop_window_icon_finalize(GObject *obj)
     gchar data_name[256];
     guint16 row, col;
     
-    if(icon->priv->pix)
-        g_object_unref(G_OBJECT(icon->priv->pix));
-    
     g_free(icon->priv->label);
     
     /* save previous position */
@@ -136,43 +131,27 @@ xfdesktop_window_icon_changed_cb(WnckWindow *window,
                                  gpointer user_data)
 {
     XfdesktopWindowIcon *icon = user_data;
-    
-    if(icon->priv->pix) {
-        g_object_unref(G_OBJECT(icon->priv->pix));
-        icon->priv->pix = NULL;
-    }
-    
+
+    xfdesktop_icon_invalidate_pixbuf(XFDESKTOP_ICON(icon));
     xfdesktop_icon_label_changed(XFDESKTOP_ICON(icon));
 }
 
-
-
-
-
 static GdkPixbuf *
 xfdesktop_window_icon_peek_pixbuf(XfdesktopIcon *icon,
-                                 gint size)
+                                 gint width, gint height)
 {
     XfdesktopWindowIcon *window_icon = XFDESKTOP_WINDOW_ICON(icon);
-    
-    if(!window_icon->priv->pix || window_icon->priv->cur_pix_size != size) {
-        if(window_icon->priv->pix)
-            g_object_unref(G_OBJECT(window_icon->priv->pix));
-        
-        window_icon->priv->pix = wnck_window_get_icon(window_icon->priv->window);
-        if(window_icon->priv->pix) {
-            if(gdk_pixbuf_get_width(window_icon->priv->pix) != size) {
-                window_icon->priv->pix = gdk_pixbuf_scale_simple(window_icon->priv->pix,
-                                                                 size,
-                                                                 size,
-                                                                 GDK_INTERP_BILINEAR);
-            } else
-                g_object_ref(G_OBJECT(window_icon->priv->pix));
-            window_icon->priv->cur_pix_size = size;
-        }
+    GdkPixbuf *pix = NULL;
+
+    pix = wnck_window_get_icon(window_icon->priv->window);
+    if(pix) {
+        if(gdk_pixbuf_get_height(pix) != height) {
+            pix = gdk_pixbuf_scale_simple(pix, height, height, GDK_INTERP_BILINEAR);
+        } else
+            g_object_ref(G_OBJECT(pix));
     }
-    
-    return window_icon->priv->pix;
+
+    return pix;
 }
 
 static G_CONST_RETURN gchar *


More information about the Xfce4-commits mailing list