[Xfce4-commits] <thunar:jannis/new-shortcuts-pane> Implement lazy loading of regular and network file shortcuts.

Jannis Pohlmann noreply at xfce.org
Fri Jul 15 21:10:33 CEST 2011


Updating branch refs/heads/jannis/new-shortcuts-pane
         to e3bf9971d0478ec2c89531e42eb358e25f3b1e5a (commit)
       from adab1506c51f450b95f58160a80a70d3981474da (commit)

commit e3bf9971d0478ec2c89531e42eb358e25f3b1e5a
Author: Jannis Pohlmann <jannis at xfce.org>
Date:   Thu Jun 9 18:16:28 2011 +0200

    Implement lazy loading of regular and network file shortcuts.
    
    File shortcuts are now created with a GFile that is asynchronously
    resolved into a ThunarFile in the background. The ThunarShortcut and its
    corresponding ThunarShortcutRow are updated as soon as ThunarFile is
    available.
    
    This required several changes to the model, the synchronization between
    shortcuts, the model and the rows as well as additional properties for
    custom names to override file display names etc.
    
    The next step will be to create file shortcuts with URIs only and
    resolve those into GFiles before those are resolved into ThunarFiles.
    This will perhaps fix the startup delay issues with current versions of
    Thunar.

 thunar/thunar-file.c            |   70 ++++++++--
 thunar/thunar-file.h            |   13 +-
 thunar/thunar-shortcut-row.c    |  118 ++++++++++++----
 thunar/thunar-shortcut-row.h    |    3 +
 thunar/thunar-shortcut.c        |  280 ++++++++++++++++++++++++++++++++++-----
 thunar/thunar-shortcut.h        |    6 +
 thunar/thunar-shortcuts-model.c |   78 +++++------
 thunar/thunar-shortcuts-view.c  |   13 +-
 8 files changed, 448 insertions(+), 133 deletions(-)

diff --git a/thunar/thunar-file.c b/thunar/thunar-file.c
index a4e4f79..50564e8 100644
--- a/thunar/thunar-file.c
+++ b/thunar/thunar-file.c
@@ -92,6 +92,11 @@ enum
 
 
 
+/* type definition for asynchronous file loading */
+typedef struct _ThunarFileGetData ThunarFileGetData;
+
+
+
 static void               thunar_file_info_init                (ThunarxFileInfoIface   *iface);
 static void               thunar_file_dispose                  (GObject                *object);
 static void               thunar_file_finalize                 (GObject                *object);
@@ -127,6 +132,14 @@ static void               thunar_file_finish_reload            (ThunarFile
 
 
 
+struct _ThunarFileGetData
+{
+  ThunarFileGetFunc func;
+  gpointer          user_data;
+};
+
+
+
 G_LOCK_DEFINE_STATIC (file_cache_mutex);
 
 
@@ -695,11 +708,11 @@ thunar_file_get_async_finish (GObject      *object,
                               GAsyncResult *result,
                               gpointer      user_data)
 {
-  ThunarFileGetAsyncFunc func = user_data;
-  ThunarFile            *file;
-  GFileInfo             *file_info;
-  GError                *error = NULL;
-  GFile                 *location = G_FILE (object);
+  ThunarFileGetData *data = user_data;
+  ThunarFile        *file;
+  GFileInfo         *file_info;
+  GError            *error = NULL;
+  GFile             *location = G_FILE (object);
 
   _thunar_return_if_fail (G_IS_FILE (location));
   _thunar_return_if_fail (G_IS_ASYNC_RESULT (result));
@@ -727,7 +740,7 @@ thunar_file_get_async_finish (GObject      *object,
   G_UNLOCK (file_cache_mutex);
 
   /* pass the loaded file and possible errors to the return function */
-  (func) (location, file, error);
+  (data->func) (location, file, error, data->user_data);
 
   /* free the error, if there is any */
   if (error != NULL)
@@ -735,6 +748,9 @@ thunar_file_get_async_finish (GObject      *object,
 
   /* release the file */
   g_object_unref (file);
+
+  /* release the get data */
+  g_slice_free (ThunarFileGetData, data);
 }
 
 
@@ -743,23 +759,31 @@ thunar_file_get_async_finish (GObject      *object,
  * thunar_file_get_async:
  **/
 void
-thunar_file_get_async (GFile                 *location,
-                       GCancellable          *cancellable,
-                       ThunarFileGetAsyncFunc func)
+thunar_file_get_async (GFile            *location,
+                       GCancellable     *cancellable,
+                       ThunarFileGetFunc func,
+                       gpointer          user_data)
 {
-  ThunarFile *file;
+  ThunarFileGetData *data;
+  ThunarFile        *file;
 
   _thunar_return_if_fail (G_IS_FILE (location));
+  _thunar_return_if_fail (func != NULL);
 
   /* check if we already have a cached version of that file */
   file = thunar_file_cache_lookup (location);
   if (G_UNLIKELY (file != NULL))
     {
       /* call the return function with the file from the cache */
-      (func) (location, file, NULL);
+      (func) (location, file, NULL, user_data);
     }
   else
     {
+      /* allocate get data */
+      data = g_slice_new0 (ThunarFileGetData);
+      data->user_data = user_data;
+      data->func = func;
+
       /* load the file information asynchronously */
       g_file_query_info_async (location,
                                THUNARX_FILE_INFO_NAMESPACE,
@@ -767,7 +791,7 @@ thunar_file_get_async (GFile                 *location,
                                0,
                                cancellable,
                                thunar_file_get_async_finish,
-                               func);
+                               data);
     }
 }
 
@@ -2957,6 +2981,28 @@ thunar_file_get_custom_icon (const ThunarFile *file)
 
 
 /**
+ * thunar_file_get_icon:
+ * @file : a #ThunarFile instance.
+ *
+ * Returns the icon for @file if any, else %NULL is returned.
+ *
+ * Return value: the icon for @file or %NULL, the GIcon is owner
+ * by the file, so do not unref it.
+ **/
+GIcon *
+thunar_file_get_icon (const ThunarFile *file)
+{
+  _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
+
+  if (file->info == NULL)
+    return NULL;
+
+  return g_file_info_get_icon (file->info);
+}
+
+
+
+/**
  * thunar_file_get_preview_icon:
  * @file : a #ThunarFile instance.
  *
diff --git a/thunar/thunar-file.h b/thunar/thunar-file.h
index 34b970e..ff424ce 100644
--- a/thunar/thunar-file.h
+++ b/thunar/thunar-file.h
@@ -100,13 +100,14 @@ typedef enum /*< flags >*/
 #define THUNAR_FILE_EMBLEM_NAME_DESKTOP "emblem-desktop"
 
 /**
- * ThunarFileGetAsyncFunc:
+ * ThunarFileGetFunc:
  *
  * Callback type for loading #ThunarFile<!---->s asynchronously.
  **/
-typedef void (*ThunarFileGetAsyncFunc) (GFile      *location,
-                                        ThunarFile *file,
-                                        GError     *error);
+typedef void (*ThunarFileGetFunc) (GFile      *location,
+                                   ThunarFile *file,
+                                   GError     *error,
+                                   gpointer    user_data);
 
 struct _ThunarFileClass
 {
@@ -142,7 +143,8 @@ ThunarFile       *thunar_file_get_for_uri          (const gchar            *uri,
 
 void              thunar_file_get_async            (GFile                 *location,
                                                     GCancellable          *cancellable,
-                                                    ThunarFileGetAsyncFunc func);
+                                                    ThunarFileGetFunc      func,
+                                                    gpointer               user_data);
 
 gboolean          thunar_file_load                 (ThunarFile             *file,
                                                     GCancellable           *cancellable,
@@ -240,6 +242,7 @@ const gchar     *thunar_file_get_thumbnail_path    (const ThunarFile        *fil
 gboolean         thunar_file_is_thumbnail          (const ThunarFile        *file);
 void             thunar_file_set_thumb_state       (ThunarFile              *file, 
                                                     ThunarFileThumbState     state);
+GIcon            *thunar_file_get_icon             (const ThunarFile        *file);
 GIcon            *thunar_file_get_preview_icon     (const ThunarFile        *file);
 gchar            *thunar_file_get_icon_name        (const ThunarFile        *file,
                                                     ThunarFileIconState     icon_state,
diff --git a/thunar/thunar-shortcut-row.c b/thunar/thunar-shortcut-row.c
index de93e6e..932df87 100644
--- a/thunar/thunar-shortcut-row.c
+++ b/thunar/thunar-shortcut-row.c
@@ -52,6 +52,7 @@ enum
   PROP_LABEL,
   PROP_EJECT_ICON,
   PROP_LOCATION,
+  PROP_FILE,
   PROP_VOLUME,
   PROP_MOUNT,
   PROP_SHORTCUT_TYPE,
@@ -132,6 +133,7 @@ static void     thunar_shortcut_row_resolve_and_activate  (ThunarShortcutRow
 static void     thunar_shortcut_row_icon_changed          (ThunarShortcutRow     *row);
 static void     thunar_shortcut_row_label_changed         (ThunarShortcutRow     *row);
 static void     thunar_shortcut_row_location_changed      (ThunarShortcutRow     *row);
+static void     thunar_shortcut_row_file_changed          (ThunarShortcutRow     *row);
 static void     thunar_shortcut_row_eject_icon_changed    (ThunarShortcutRow     *row);
 static void     thunar_shortcut_row_volume_changed        (ThunarShortcutRow     *row);
 static void     thunar_shortcut_row_mount_changed         (ThunarShortcutRow     *row);
@@ -160,6 +162,7 @@ struct _ThunarShortcutRow
   GIcon                 *eject_icon;
 
   GFile                 *location;
+  ThunarFile            *file;
   GVolume               *volume;
   GMount                *mount;
 
@@ -248,6 +251,14 @@ thunar_shortcut_row_class_init (ThunarShortcutRowClass *klass)
                                                         EXO_PARAM_READWRITE));
 
   g_object_class_install_property (gobject_class,
+                                   PROP_FILE,
+                                   g_param_spec_object ("file",
+                                                        "file",
+                                                        "file",
+                                                        THUNAR_TYPE_FILE,
+                                                        EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
                                    PROP_VOLUME,
                                    g_param_spec_object ("volume",
                                                         "volume",
@@ -411,6 +422,9 @@ thunar_shortcut_row_finalize (GObject *object)
   if (row->location != NULL)
     g_object_unref (row->location);
 
+  if (row->file != NULL)
+    g_object_unref (row->file);
+
   if (row->volume != NULL)
     g_object_unref (row->volume);
 
@@ -455,6 +469,10 @@ thunar_shortcut_row_get_property (GObject    *object,
       g_value_set_object (value, row->location);
       break;
 
+    case PROP_FILE:
+      g_value_set_object (value, row->file);
+      break;
+
     case PROP_VOLUME:
       g_value_set_object (value, row->volume);
       break;
@@ -505,6 +523,10 @@ thunar_shortcut_row_set_property (GObject      *object,
       thunar_shortcut_row_set_location (row, g_value_get_object (value));
       break;
 
+    case PROP_FILE:
+      thunar_shortcut_row_set_file (row, g_value_get_object (value));
+      break;
+
     case PROP_VOLUME:
       thunar_shortcut_row_set_volume (row, g_value_get_object (value));
       break;
@@ -1112,6 +1134,8 @@ thunar_shortcut_row_label_changed (ThunarShortcutRow *row)
 {
   _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
 
+  g_debug ("label changed: %s", row->label);
+
   /* update the label widget */
   gtk_label_set_markup (GTK_LABEL (row->label_widget), row->label);
   gtk_widget_set_visible (row->label_widget, row->label != NULL && *row->label != '\0');
@@ -1172,11 +1196,38 @@ thunar_shortcut_row_location_changed (ThunarShortcutRow *row)
 
 
 static void
-thunar_shortcut_row_volume_changed (ThunarShortcutRow *row)
+thunar_shortcut_row_file_changed (ThunarShortcutRow *row)
 {
-  GIcon *icon;
-  gchar *name;
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
+
+  /* don't update the row based on the file if it's not
+   * a regular or network file */
+  if (row->shortcut_type != THUNAR_SHORTCUT_REGULAR_FILE 
+      && row->shortcut_type != THUNAR_SHORTCUT_NETWORK_FILE)
+    {
+      return;
+    }
+
+  if (row->file != NULL)
+    {
+      /* update the visibility of the eject button */
+      if (thunar_file_is_mountable (row->file) && thunar_file_is_mounted (row->file))
+        gtk_widget_set_visible (row->action_button, TRUE);
+      else
+        gtk_widget_set_visible (row->action_button, FALSE);
+    }
+  else
+    {
+      /* update the row based on the location alone */
+      thunar_shortcut_row_location_changed (row);
+    }
+}
 
+
+
+static void
+thunar_shortcut_row_volume_changed (ThunarShortcutRow *row)
+{
   _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
 
   /* don't update the information based on the volume unless
@@ -1189,18 +1240,6 @@ thunar_shortcut_row_volume_changed (ThunarShortcutRow *row)
 
   if (row->volume != NULL)
     {
-      /* update the label widget */
-      name = g_volume_get_name (row->volume);
-      gtk_label_set_markup (GTK_LABEL (row->label_widget), name);
-      gtk_widget_set_visible (row->label_widget, name != NULL && *name != '\0');
-      g_free (name);
-
-      /* update the icon image */
-      icon = g_volume_get_icon (row->volume);
-      gtk_image_set_from_gicon (GTK_IMAGE (row->icon_image), icon, row->icon_size);
-      gtk_widget_set_visible (row->icon_image, icon != NULL);
-      g_object_unref (icon);
-
       /* update the action button */
       if (thunar_g_volume_is_removable (row->volume)
           && thunar_g_volume_is_mounted (row->volume))
@@ -1227,9 +1266,6 @@ thunar_shortcut_row_volume_changed (ThunarShortcutRow *row)
 static void
 thunar_shortcut_row_mount_changed (ThunarShortcutRow *row)
 {
-  GIcon *icon;
-  gchar *name;
-
   _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
 
   /* don't update the row based on the mount unless we have
@@ -1239,18 +1275,6 @@ thunar_shortcut_row_mount_changed (ThunarShortcutRow *row)
 
   if (row->mount != NULL)
     {
-      /* update the label widget */
-      name = g_mount_get_name (row->mount);
-      gtk_label_set_markup (GTK_LABEL (row->label_widget), name);
-      gtk_widget_set_visible (row->label_widget, name != NULL && *name != '\0');
-      g_free (name);
-
-      /* update the icon image */
-      icon = g_mount_get_icon (row->mount);
-      gtk_image_set_from_gicon (GTK_IMAGE (row->icon_image), icon, row->icon_size);
-      gtk_widget_set_visible (row->icon_image, icon != NULL);
-      g_object_unref (icon);
-
       /* update the action button */
       if (g_mount_can_unmount (row->mount) || g_mount_can_eject (row->mount))
         gtk_widget_set_visible (row->action_button, TRUE);
@@ -1454,6 +1478,40 @@ thunar_shortcut_row_get_location (ThunarShortcutRow *row)
 
 
 void
+thunar_shortcut_row_set_file (ThunarShortcutRow *row,
+                              ThunarFile        *file)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
+  _thunar_return_if_fail (file == NULL || THUNAR_IS_FILE (file));
+
+  if (row->file == file)
+    return;
+
+  if (row->file != NULL)
+    g_object_unref (row->file);
+
+  if (file != NULL)
+    row->file = g_object_ref (file);
+  else
+    row->file = NULL;
+
+  thunar_shortcut_row_file_changed (row);
+
+  g_object_notify (G_OBJECT (row), "file");
+}
+
+
+
+ThunarFile *
+thunar_shortcut_row_get_file (ThunarShortcutRow *row)
+{
+  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUT_ROW (row), NULL);
+  return row->file;
+}
+
+
+
+void
 thunar_shortcut_row_set_volume (ThunarShortcutRow *row,
                                 GVolume           *volume)
 {
diff --git a/thunar/thunar-shortcut-row.h b/thunar/thunar-shortcut-row.h
index 3c53e42..23dfa04 100644
--- a/thunar/thunar-shortcut-row.h
+++ b/thunar/thunar-shortcut-row.h
@@ -48,6 +48,9 @@ void               thunar_shortcut_row_set_label         (ThunarShortcutRow *row
 GFile             *thunar_shortcut_row_get_location      (ThunarShortcutRow *row);
 void               thunar_shortcut_row_set_location      (ThunarShortcutRow *row,
                                                           GFile             *location);
+ThunarFile        *thunar_shortcut_row_get_file          (ThunarShortcutRow *row);
+void               thunar_shortcut_row_set_file          (ThunarShortcutRow *row,
+                                                          ThunarFile        *file);
 GVolume           *thunar_shortcut_row_get_volume        (ThunarShortcutRow *row);
 void               thunar_shortcut_row_set_volume        (ThunarShortcutRow *row,
                                                           GVolume           *volume);
diff --git a/thunar/thunar-shortcut.c b/thunar/thunar-shortcut.c
index 96170c7..5f6741b 100644
--- a/thunar/thunar-shortcut.c
+++ b/thunar/thunar-shortcut.c
@@ -43,8 +43,10 @@ enum
   PROP_VOLUME,
   PROP_MOUNT,
   PROP_ICON,
+  PROP_CUSTOM_ICON,
   PROP_EJECT_ICON,
   PROP_NAME,
+  PROP_CUSTOM_NAME,
   PROP_SHORTCUT_TYPE,
   PROP_HIDDEN,
   PROP_MUTABLE,
@@ -54,23 +56,26 @@ enum
 /* signal identifiers */
 enum
 {
-  SIGNAL_CHANGED,
   LAST_SIGNAL,
 };
 
 
 
-static void thunar_shortcut_constructed  (GObject        *object);
-static void thunar_shortcut_finalize     (GObject        *object);
-static void thunar_shortcut_get_property (GObject        *object,
-                                          guint           prop_id,
-                                          GValue         *value,
-                                          GParamSpec     *pspec);
-static void thunar_shortcut_set_property (GObject        *object,
-                                          guint           prop_id,
-                                          const GValue   *value,
-                                          GParamSpec     *pspec);
-static void thunar_shortcut_load_file    (ThunarShortcut *shortcut);
+static void thunar_shortcut_constructed      (GObject        *object);
+static void thunar_shortcut_finalize         (GObject        *object);
+static void thunar_shortcut_get_property     (GObject        *object,
+                                              guint           prop_id,
+                                              GValue         *value,
+                                              GParamSpec     *pspec);
+static void thunar_shortcut_set_property     (GObject        *object,
+                                              guint           prop_id,
+                                              const GValue   *value,
+                                              GParamSpec     *pspec);
+static void thunar_shortcut_load_file_finish (GFile          *location,
+                                              ThunarFile     *file,
+                                              GError         *error,
+                                              gpointer        user_data);
+static void thunar_shortcut_load_file        (ThunarShortcut *shortcut);
 
 
 
@@ -90,9 +95,11 @@ struct _ThunarShortcut
   GMount            *mount;
   
   GIcon             *icon;
+  GIcon             *custom_icon;
   GIcon             *eject_icon;
   
   gchar             *name;
+  gchar             *custom_name;
   
   ThunarShortcutType type;
 
@@ -100,6 +107,7 @@ struct _ThunarShortcut
   guint              mutable : 1;
   guint              persistent : 1;
 
+  guint              constructed : 1;
 };
 
 
@@ -108,10 +116,6 @@ G_DEFINE_TYPE (ThunarShortcut, thunar_shortcut, G_TYPE_OBJECT)
 
 
 
-static guint shortcut_signals[LAST_SIGNAL];
-
-
-
 static void
 thunar_shortcut_class_init (ThunarShortcutClass *klass)
 {
@@ -171,6 +175,15 @@ thunar_shortcut_class_init (ThunarShortcutClass *klass)
                                                         G_PARAM_CONSTRUCT));
 
   g_object_class_install_property (gobject_class,
+                                   PROP_CUSTOM_ICON,
+                                   g_param_spec_object ("custom-icon",
+                                                        "custom-icon",
+                                                        "custom-icon",
+                                                        G_TYPE_ICON,
+                                                        EXO_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT));
+
+  g_object_class_install_property (gobject_class,
                                    PROP_EJECT_ICON,
                                    g_param_spec_object ("eject-icon",
                                                         "eject-icon",
@@ -188,6 +201,15 @@ thunar_shortcut_class_init (ThunarShortcutClass *klass)
                                                         G_PARAM_CONSTRUCT));
 
   g_object_class_install_property (gobject_class,
+                                   PROP_CUSTOM_NAME,
+                                   g_param_spec_string ("custom-name",
+                                                        "custom-name",
+                                                        "custom-name",
+                                                        NULL,
+                                                        EXO_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT));
+
+  g_object_class_install_property (gobject_class,
                                    PROP_SHORTCUT_TYPE,
                                    g_param_spec_enum ("shortcut-type",
                                                       "shortcut-type",
@@ -223,12 +245,6 @@ thunar_shortcut_class_init (ThunarShortcutClass *klass)
                                                          FALSE,
                                                          EXO_PARAM_READWRITE |
                                                          G_PARAM_CONSTRUCT));
-
-  shortcut_signals[SIGNAL_CHANGED] = g_signal_new ("changed",
-                                                   G_TYPE_FROM_CLASS (klass),
-                                                   G_SIGNAL_RUN_LAST,
-                                                   0, NULL, NULL, NULL,
-                                                   G_TYPE_NONE, 0);
 }
 
 
@@ -245,11 +261,8 @@ thunar_shortcut_constructed (GObject *object)
 {
   ThunarShortcut *shortcut = THUNAR_SHORTCUT (object);
 
-  if (shortcut->type == THUNAR_SHORTCUT_REGULAR_FILE
-      || shortcut->type == THUNAR_SHORTCUT_NETWORK_FILE)
-    {
-      thunar_shortcut_load_file (shortcut);
-    }
+  /* mark as constructed so now all properties can be changed as usual */
+  shortcut->constructed = TRUE;
 }
 
 
@@ -274,10 +287,14 @@ thunar_shortcut_finalize (GObject *object)
   if (shortcut->icon != NULL)
     g_object_unref (shortcut->icon);
 
+  if (shortcut->custom_icon != NULL)
+    g_object_unref (shortcut->custom_icon);
+
   if (shortcut->eject_icon != NULL)
     g_object_unref (shortcut->eject_icon);
 
   g_free (shortcut->name);
+  g_free (shortcut->custom_name);
 
   (*G_OBJECT_CLASS (thunar_shortcut_parent_class)->finalize) (object);
 }
@@ -314,6 +331,10 @@ thunar_shortcut_get_property (GObject    *object,
       g_value_set_object (value, thunar_shortcut_get_icon (shortcut));
       break;
 
+    case PROP_CUSTOM_ICON:
+      g_value_set_object (value, thunar_shortcut_get_custom_icon (shortcut));
+      break;
+
     case PROP_EJECT_ICON:
       g_value_set_object (value, thunar_shortcut_get_eject_icon (shortcut));
       break;
@@ -322,6 +343,10 @@ thunar_shortcut_get_property (GObject    *object,
       g_value_set_string (value, thunar_shortcut_get_name (shortcut));
       break;
 
+    case PROP_CUSTOM_NAME:
+      g_value_set_string (value, thunar_shortcut_get_custom_name (shortcut));
+      break;
+
     case PROP_SHORTCUT_TYPE:
       g_value_set_enum (value, thunar_shortcut_get_shortcut_type (shortcut));
       break;
@@ -376,6 +401,10 @@ thunar_shortcut_set_property (GObject      *object,
       thunar_shortcut_set_icon (shortcut, g_value_get_object (value));
       break;
 
+    case PROP_CUSTOM_ICON:
+      thunar_shortcut_set_custom_icon (shortcut, g_value_get_object (value));
+      break;
+
     case PROP_EJECT_ICON:
       thunar_shortcut_set_eject_icon (shortcut, g_value_get_object (value));
       break;
@@ -384,6 +413,10 @@ thunar_shortcut_set_property (GObject      *object,
       thunar_shortcut_set_name (shortcut, g_value_get_string (value));
       break;
 
+    case PROP_CUSTOM_NAME:
+      thunar_shortcut_set_custom_name (shortcut, g_value_get_string (value));
+      break;
+
     case PROP_SHORTCUT_TYPE:
       thunar_shortcut_set_shortcut_type (shortcut, g_value_get_enum (value));
       break;
@@ -408,22 +441,31 @@ thunar_shortcut_set_property (GObject      *object,
 
 
 
-#if 0
 static void
 thunar_shortcut_load_file_finish (GFile      *location,
                                   ThunarFile *file,
-                                  GError     *error)
+                                  GError     *error,
+                                  gpointer    user_data)
 {
+  ThunarShortcut *shortcut = THUNAR_SHORTCUT (user_data);
+
+  _thunar_return_if_fail (G_IS_FILE (location));
+  _thunar_return_if_fail (file == NULL || THUNAR_IS_FILE (file));
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
+  
   if (error != NULL)
     {
-      g_debug ("error: %s", error->message);
+      g_debug ("file load error: %s", error->message);
     }
   else
     {
-      g_debug ("file loaded: %s", thunar_file_get_display_name (file));
+      /* set the file and update the shortcut */
+      thunar_shortcut_set_file (shortcut, file);
     }
+
+  /* release the shortcut */
+  g_object_unref (shortcut);
 }
-#endif
 
 
 
@@ -435,12 +477,11 @@ thunar_shortcut_load_file (ThunarShortcut *shortcut)
   if (shortcut->file != NULL)
     return;
 
-#if 0
   /* load the ThunarFile asynchronously */
   /* TODO pass a cancellable here */
   thunar_file_get_async (shortcut->location, NULL,
-                         thunar_shortcut_load_file_finish);
-#endif
+                         thunar_shortcut_load_file_finish,
+                         g_object_ref (shortcut));
 }
 
 
@@ -458,9 +499,16 @@ void
 thunar_shortcut_set_location (ThunarShortcut *shortcut,
                               GFile          *location)
 {
+  GIcon *icon;
+  gchar *base_name;
+  gchar *uri;
+
   _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
   _thunar_return_if_fail (location == NULL || G_IS_FILE (location));
 
+  if (location == NULL && !shortcut->constructed)
+    return;
+
   if (shortcut->location == location)
     return;
 
@@ -472,6 +520,33 @@ thunar_shortcut_set_location (ThunarShortcut *shortcut,
   else
     shortcut->location = NULL;
 
+  /* check if we have a file shortcut */
+  if (shortcut->type == THUNAR_SHORTCUT_REGULAR_FILE
+      || shortcut->type == THUNAR_SHORTCUT_NETWORK_FILE)
+    {
+      /* check whether we have a location */
+      if (shortcut->location != NULL)
+        {
+          /* use the location base name as the default name */
+          uri = g_file_get_uri (shortcut->location);
+          base_name = g_filename_display_basename (uri);
+          thunar_shortcut_set_name (shortcut, base_name);
+          g_free (base_name);
+          g_free (uri);
+
+          /* use the folder icon as the default icon */
+          if (shortcut->custom_icon == NULL)
+            {
+              icon = g_themed_icon_new ("folder");
+              thunar_shortcut_set_custom_icon (shortcut, icon);
+              g_object_unref (icon);
+            }
+
+          /* load file asynchronously */
+          thunar_shortcut_load_file (shortcut);
+        }
+    }
+
   g_object_notify (G_OBJECT (shortcut), "location");
 }
 
@@ -493,6 +568,9 @@ thunar_shortcut_set_file (ThunarShortcut *shortcut,
   _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
   _thunar_return_if_fail (file == NULL || THUNAR_IS_FILE (file));
 
+  if (file == NULL && !shortcut->constructed)
+    return;
+
   if (shortcut->file == file)
     return;
 
@@ -504,6 +582,20 @@ thunar_shortcut_set_file (ThunarShortcut *shortcut,
   else
     shortcut->file = NULL;
 
+  /* check whether we have a file shortcut */
+  if (shortcut->type == THUNAR_SHORTCUT_REGULAR_FILE
+      || shortcut->type == THUNAR_SHORTCUT_NETWORK_FILE)
+    {
+      /* update only if we have a file */
+      if (shortcut->file != NULL)
+        {
+          /* update the name and icon of the shortcut */
+          thunar_shortcut_set_name (shortcut, 
+                                    thunar_file_get_display_name (shortcut->file));
+          thunar_shortcut_set_custom_icon (shortcut, thunar_file_get_icon (shortcut->file));
+        }
+    }
+
   g_object_notify (G_OBJECT (shortcut), "file");
 }
 
@@ -522,9 +614,15 @@ void
 thunar_shortcut_set_volume (ThunarShortcut *shortcut,
                             GVolume        *volume)
 {
+  GIcon *icon;
+  gchar *name;
+
   _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
   _thunar_return_if_fail (volume == NULL || G_IS_VOLUME (volume));
 
+  if (volume == NULL && !shortcut->constructed)
+    return;
+
   if (shortcut->volume == volume)
     return;
 
@@ -536,6 +634,23 @@ thunar_shortcut_set_volume (ThunarShortcut *shortcut,
   else
     shortcut->volume = NULL;
 
+  /* check if we have a regular or ejectable volume */
+  if (shortcut->type == THUNAR_SHORTCUT_REGULAR_VOLUME
+      || shortcut->type == THUNAR_SHORTCUT_EJECTABLE_VOLUME)
+    {
+      /* only update if we have a volume */
+      if (shortcut->volume != NULL)
+        {
+          /* update the name and icon of the shortcut */
+          name = g_volume_get_name (shortcut->volume);
+          icon = g_volume_get_icon (shortcut->volume);
+          thunar_shortcut_set_name (shortcut, name);
+          thunar_shortcut_set_custom_icon (shortcut, icon);
+          g_object_unref (icon);
+          g_free (name);
+        }
+    }
+
   g_object_notify (G_OBJECT (shortcut), "volume");
 }
 
@@ -554,9 +669,15 @@ void
 thunar_shortcut_set_mount (ThunarShortcut *shortcut,
                            GMount         *mount)
 {
+  GIcon *icon;
+  gchar *name;
+
   _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
   _thunar_return_if_fail (mount == NULL || G_IS_MOUNT (mount));
 
+  if (mount == NULL && !shortcut->constructed)
+    return;
+
   if (shortcut->mount == mount)
     return;
 
@@ -568,6 +689,21 @@ thunar_shortcut_set_mount (ThunarShortcut *shortcut,
   else
     shortcut->mount = NULL;
 
+  /* check if we have a standalone mount */
+  if (shortcut->type == THUNAR_SHORTCUT_STANDALONE_MOUNT)
+    {
+      /* only update if we have a mount */
+      if (shortcut->mount != NULL)
+        {
+          /* update the name and icon of the shortcut  */
+          name = g_mount_get_name (shortcut->mount);
+          icon = g_mount_get_icon (shortcut->mount);
+          thunar_shortcut_set_name (shortcut, name);
+          thunar_shortcut_set_custom_icon (shortcut, icon);
+          g_object_unref (icon);
+          g_free (name);
+        }
+    }
   g_object_notify (G_OBJECT (shortcut), "mount");
 }
 
@@ -589,6 +725,9 @@ thunar_shortcut_set_icon (ThunarShortcut *shortcut,
   _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
   _thunar_return_if_fail (icon == NULL || G_IS_ICON (icon));
 
+  if (icon == NULL && !shortcut->constructed)
+    return;
+
   if (shortcut->icon == icon)
     return;
 
@@ -606,6 +745,41 @@ thunar_shortcut_set_icon (ThunarShortcut *shortcut,
 
 
 GIcon *
+thunar_shortcut_get_custom_icon (ThunarShortcut *shortcut)
+{
+  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUT (shortcut), NULL);
+  return shortcut->custom_icon;
+}
+
+
+
+void
+thunar_shortcut_set_custom_icon (ThunarShortcut *shortcut,
+                                 GIcon          *custom_icon)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
+  _thunar_return_if_fail (custom_icon == NULL || G_IS_ICON (custom_icon));
+
+  if (custom_icon == NULL && !shortcut->constructed)
+    return;
+
+  if (shortcut->custom_icon == custom_icon)
+    return;
+
+  if (shortcut->custom_icon != NULL)
+    g_object_unref (shortcut->custom_icon);
+
+  if (custom_icon != NULL)
+    shortcut->custom_icon = g_object_ref (custom_icon);
+  else
+    shortcut->custom_icon = NULL;
+
+  g_object_notify (G_OBJECT (shortcut), "custom-icon");
+}
+
+
+
+GIcon *
 thunar_shortcut_get_eject_icon (ThunarShortcut *shortcut)
 {
   _thunar_return_val_if_fail (THUNAR_IS_SHORTCUT (shortcut), NULL);
@@ -621,6 +795,9 @@ thunar_shortcut_set_eject_icon (ThunarShortcut *shortcut,
   _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
   _thunar_return_if_fail (eject_icon == NULL || G_IS_ICON (eject_icon));
 
+  if (eject_icon == NULL && !shortcut->constructed)
+    return;
+
   if (shortcut->eject_icon == eject_icon)
     return;
 
@@ -652,6 +829,9 @@ thunar_shortcut_set_name (ThunarShortcut *shortcut,
 {
   _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
 
+  if (name == NULL && !shortcut->constructed)
+    return;
+
   if (g_strcmp0 (shortcut->name, name) == 0)
     return;
 
@@ -664,6 +844,36 @@ thunar_shortcut_set_name (ThunarShortcut *shortcut,
 
 
 
+const gchar *
+thunar_shortcut_get_custom_name (ThunarShortcut *shortcut)
+{
+  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUT (shortcut), NULL);
+  return shortcut->custom_name;
+}
+
+
+
+void
+thunar_shortcut_set_custom_name (ThunarShortcut *shortcut,
+                                 const gchar    *custom_name)
+{
+  _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
+
+  if (custom_name == NULL && !shortcut->constructed)
+    return;
+
+  if (g_strcmp0 (shortcut->custom_name, custom_name) == 0)
+    return;
+
+  g_free (shortcut->custom_name);
+
+  shortcut->custom_name = g_strdup (custom_name);
+
+  g_object_notify (G_OBJECT (shortcut), "custom-name");
+}
+
+
+
 ThunarShortcutType
 thunar_shortcut_get_shortcut_type (ThunarShortcut *shortcut)
 {
diff --git a/thunar/thunar-shortcut.h b/thunar/thunar-shortcut.h
index 4a1c8d6..1a8d6a7 100644
--- a/thunar/thunar-shortcut.h
+++ b/thunar/thunar-shortcut.h
@@ -54,12 +54,18 @@ void               thunar_shortcut_set_mount         (ThunarShortcut    *shortcu
 GIcon             *thunar_shortcut_get_icon          (ThunarShortcut    *shortcut);
 void               thunar_shortcut_set_icon          (ThunarShortcut    *shortcut,
                                                       GIcon             *icon);
+GIcon             *thunar_shortcut_get_custom_icon   (ThunarShortcut    *shortcut);
+void               thunar_shortcut_set_custom_icon   (ThunarShortcut    *shortcut,
+                                                      GIcon             *custom_icon);
 GIcon             *thunar_shortcut_get_eject_icon    (ThunarShortcut    *shortcut);
 void               thunar_shortcut_set_eject_icon    (ThunarShortcut    *shortcut,
                                                       GIcon             *eject_icon);
 const gchar       *thunar_shortcut_get_name          (ThunarShortcut    *shortcut);
 void               thunar_shortcut_set_name          (ThunarShortcut    *shortcut,
                                                       const gchar       *name);
+const gchar       *thunar_shortcut_get_custom_name   (ThunarShortcut    *shortcut);
+void               thunar_shortcut_set_custom_name   (ThunarShortcut    *shortcut,
+                                                      const gchar       *custom_name);
 ThunarShortcutType thunar_shortcut_get_shortcut_type (ThunarShortcut    *shortcut);
 void               thunar_shortcut_set_shortcut_type (ThunarShortcut    *shortcut,
                                                       ThunarShortcutType shortcut_type);
diff --git a/thunar/thunar-shortcuts-model.c b/thunar/thunar-shortcuts-model.c
index cbbded6..69e2c6a 100644
--- a/thunar/thunar-shortcuts-model.c
+++ b/thunar/thunar-shortcuts-model.c
@@ -126,6 +126,7 @@ static gboolean                thunar_shortcuts_model_find_mount            (Thu
 static void                    thunar_shortcuts_model_add_shortcut          (ThunarShortcutsModel      *model,
                                                                              ThunarShortcut            *shortcut);
 static void                    thunar_shortcuts_model_shortcut_changed      (ThunarShortcutsModel      *model,
+                                                                             GParamSpec                *pspec,
                                                                              ThunarShortcut            *shortcut);
 static gboolean                thunar_shortcuts_model_load_system_shortcuts (gpointer                   user_data);
 static gboolean                thunar_shortcuts_model_load_user_dirs        (gpointer                   user_data);
@@ -400,6 +401,8 @@ thunar_shortcuts_model_get_value (GtkTreeModel *tree_model,
   ThunarShortcutCategory *category;
   ThunarShortcutsModel   *model = THUNAR_SHORTCUTS_MODEL (tree_model);
   ThunarShortcut         *shortcut;
+  const gchar            *name;
+  GIcon                  *icon;
   gint                    category_index;
   gint                    shortcut_index;
 
@@ -419,17 +422,33 @@ thunar_shortcuts_model_get_value (GtkTreeModel *tree_model,
     case THUNAR_SHORTCUTS_MODEL_COLUMN_ICON:
       g_value_init (value, G_TYPE_ICON);
       if (shortcut != NULL)
-        g_value_set_object (value, thunar_shortcut_get_icon (shortcut));
+        {
+          icon = thunar_shortcut_get_custom_icon (shortcut);
+          if (icon == NULL)
+            icon = thunar_shortcut_get_icon (shortcut);
+
+          g_value_set_object (value, icon);
+        }
       else
-        g_value_set_object (value, NULL);
+        {
+          g_value_set_object (value, NULL);
+        }
       break;
 
     case THUNAR_SHORTCUTS_MODEL_COLUMN_NAME:
       g_value_init (value, G_TYPE_STRING);
       if (shortcut != NULL)
-        g_value_set_static_string (value, thunar_shortcut_get_name (shortcut));
+        {
+          name = thunar_shortcut_get_custom_name (shortcut);
+          if (name == NULL)
+            name = thunar_shortcut_get_name (shortcut);
+
+          g_value_set_static_string (value, name);
+        }
       else
-        g_value_set_static_string (value, category->name);
+        {
+          g_value_set_static_string (value, category->name);
+        }
       break;
 
     case THUNAR_SHORTCUTS_MODEL_COLUMN_LOCATION:
@@ -1143,7 +1162,7 @@ thunar_shortcuts_model_add_shortcut (ThunarShortcutsModel *model,
   gtk_tree_path_free (path);
 
   /* be notified whenever the shortcut changes */
-  g_signal_connect_swapped (shortcut, "changed", 
+  g_signal_connect_swapped (shortcut, "notify", 
                             G_CALLBACK (thunar_shortcuts_model_shortcut_changed),
                             model);
 }
@@ -1152,6 +1171,7 @@ thunar_shortcuts_model_add_shortcut (ThunarShortcutsModel *model,
 
 static void
 thunar_shortcuts_model_shortcut_changed (ThunarShortcutsModel *model,
+                                         GParamSpec           *pspec,
                                          ThunarShortcut       *shortcut)
 {
   GtkTreePath *path;
@@ -1190,7 +1210,7 @@ thunar_shortcuts_model_load_system_shortcuts (gpointer user_data)
   GFile                *home_file;
   GFile                *location;
   GIcon                *icon;
-  gchar                *name;
+  gchar                *name = NULL;
   gchar                *path;
 
   _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
@@ -1201,15 +1221,13 @@ thunar_shortcuts_model_load_system_shortcuts (gpointer user_data)
   /* create $HOME information */
   icon = g_themed_icon_new ("user-home");
   path = g_file_get_path (home_file);
-  name = g_filename_display_basename (path);
   
   /* create the $HOME shortcut */
   shortcut = g_object_new (THUNAR_TYPE_SHORTCUT,
                            "shortcut-type", THUNAR_SHORTCUT_REGULAR_FILE,
                            "location", home_file,
                            "icon", icon,
-                           "eject-icon", NULL,
-                           "name", name,
+                           "custom-name", NULL,
                            "hidden", FALSE,
                            "mutable", FALSE,
                            "persistent", TRUE,
@@ -1219,7 +1237,6 @@ thunar_shortcuts_model_load_system_shortcuts (gpointer user_data)
   thunar_shortcuts_model_add_shortcut (model, shortcut);
 
   /* release $HOME information */
-  g_free (name);
   g_free (path);
   g_object_unref (icon);
 
@@ -1238,8 +1255,7 @@ thunar_shortcuts_model_load_system_shortcuts (gpointer user_data)
                                "shortcut-type", THUNAR_SHORTCUT_REGULAR_FILE,
                                "location", location,
                                "icon", icon,
-                               "eject-icon", NULL,
-                               "name", name,
+                               "custom-name", name,
                                "hidden", FALSE,
                                "mutable", FALSE,
                                "persistent", TRUE,
@@ -1267,8 +1283,7 @@ thunar_shortcuts_model_load_system_shortcuts (gpointer user_data)
                            "shortcut-type", THUNAR_SHORTCUT_REGULAR_FILE,
                            "location", location,
                            "icon", icon,
-                           "eject-icon", NULL,
-                           "name", name,
+                           "custom-name", name,
                            "hidden", FALSE,
                            "mutable", FALSE,
                            "persistent", TRUE,
@@ -1295,8 +1310,7 @@ thunar_shortcuts_model_load_system_shortcuts (gpointer user_data)
                            "shortcut-type", THUNAR_SHORTCUT_NETWORK_FILE,
                            "location", location,
                            "icon", icon,
-                           "eject-icon", NULL,
-                           "name", name,
+                           "custom-name", name,
                            "hidden", FALSE,
                            "mutable", FALSE,
                            "persistent", TRUE,
@@ -1348,7 +1362,6 @@ thunar_shortcuts_model_load_bookmarks (gpointer user_data)
   gchar                *bookmarks_path;
   gchar                 line[2048];
   gchar                *name;
-  gchar                *unescaped_uri;
   FILE                 *fp;
 
   _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
@@ -1389,17 +1402,8 @@ thunar_shortcuts_model_load_bookmarks (gpointer user_data)
               /* parse the URI */
               location = g_file_new_for_uri (line);
 
-              /* use the base name as a fallback for the display name */
-              if (*name != '\0')
-                {
-                  name = g_strdup (name);
-                }
-              else
-                {
-                  unescaped_uri = g_uri_unescape_string (line, NULL);
-                  name = g_filename_display_basename (unescaped_uri);
-                  g_free (unescaped_uri);
-                }
+              /* only set the name property if the name is not empty */
+              name = *name != '\0' ? g_strdup (name) : NULL;
 
               /* set initial icon and type based on the URI scheme */
               is_local = g_file_has_uri_scheme (location, "file");
@@ -1420,7 +1424,7 @@ thunar_shortcuts_model_load_bookmarks (gpointer user_data)
                                        "location", location,
                                        "icon", icon,
                                        "eject-icon", eject_icon,
-                                       "name", name,
+                                       "custom-name", name,
                                        "hidden", FALSE,
                                        "mutable", TRUE,
                                        "persistent", TRUE,
@@ -1521,17 +1525,13 @@ thunar_shortcuts_model_volume_added (ThunarShortcutsModel *model,
   ThunarShortcut *shortcut;
   gboolean        hidden = FALSE;
   GIcon          *eject_icon;
-  GIcon          *icon;
-  gchar          *name;
 
   _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
   _thunar_return_if_fail (G_IS_VOLUME (volume));
   _thunar_return_if_fail (G_IS_VOLUME_MONITOR (monitor));
 
   /* read information from the volume */
-  icon = g_volume_get_icon (volume);
   eject_icon = g_themed_icon_new ("media-eject");
-  name = g_volume_get_name (volume);
 
   /* hide the volume if there is no media */
   if (!thunar_g_volume_is_present (volume))
@@ -1546,9 +1546,7 @@ thunar_shortcuts_model_volume_added (ThunarShortcutsModel *model,
   shortcut = g_object_new (THUNAR_TYPE_SHORTCUT,
                            "shortcut-type", THUNAR_SHORTCUT_REGULAR_VOLUME,
                            "volume", volume,
-                           "icon", icon,
                            "eject-icon", eject_icon,
-                           "name", name,
                            "hidden", hidden,
                            "mutable", FALSE,
                            "persistent", FALSE,
@@ -1558,9 +1556,7 @@ thunar_shortcuts_model_volume_added (ThunarShortcutsModel *model,
   thunar_shortcuts_model_add_shortcut (model, shortcut);
 
   /* release volume information */
-  g_free (name);
   g_object_unref (eject_icon);
-  g_object_unref (icon);
 }
 
 
@@ -1609,8 +1605,6 @@ thunar_shortcuts_model_mount_added (ThunarShortcutsModel *model,
   GVolume        *volume;
   GFile          *location;
   GIcon          *eject_icon;
-  GIcon          *icon;
-  gchar          *name;
 
   _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
   _thunar_return_if_fail (G_IS_MOUNT (mount));
@@ -1627,18 +1621,14 @@ thunar_shortcuts_model_mount_added (ThunarShortcutsModel *model,
     {
       /* read information from the mount */
       location = g_mount_get_root (mount);
-      icon = g_mount_get_icon (mount);
       eject_icon = g_themed_icon_new ("media-eject");
-      name = g_mount_get_name (mount);
 
       /* create a shortcut for the mount */
       shortcut = g_object_new (THUNAR_TYPE_SHORTCUT,
                                "shortcut-type", THUNAR_SHORTCUT_STANDALONE_MOUNT,
                                "location", location,
                                "mount", mount,
-                               "icon", icon,
                                "eject-icon", eject_icon,
-                               "name", name,
                                "hidden", FALSE,
                                "mutable", FALSE,
                                "persistent", FALSE,
@@ -1648,9 +1638,7 @@ thunar_shortcuts_model_mount_added (ThunarShortcutsModel *model,
       thunar_shortcuts_model_add_shortcut (model, shortcut);
 
       /* release volume information */
-      g_free (name);
       g_object_unref (eject_icon);
-      g_object_unref (icon);
       g_object_unref (location);
     }
 }
diff --git a/thunar/thunar-shortcuts-view.c b/thunar/thunar-shortcuts-view.c
index 217bac0..553a9d1 100644
--- a/thunar/thunar-shortcuts-view.c
+++ b/thunar/thunar-shortcuts-view.c
@@ -514,6 +514,7 @@ thunar_shortcuts_view_row_changed (ThunarShortcutsView *view,
                                    GtkTreeModel        *model)
 {
   ThunarShortcutRow *row;
+  ThunarFile        *file;
   GtkWidget         *expander;
   GtkWidget         *box;
   GIcon             *icon;
@@ -550,21 +551,21 @@ thunar_shortcuts_view_row_changed (ThunarShortcutsView *view,
       row = THUNAR_SHORTCUT_ROW (row_element->data);
 
       /* read updated information from the tree row */
-      /* TODO also read the ThunarFile if we have one etc. */
       gtk_tree_model_get (model, iter,
                           THUNAR_SHORTCUTS_MODEL_COLUMN_NAME, &name,
                           THUNAR_SHORTCUTS_MODEL_COLUMN_ICON, &icon,
+                          THUNAR_SHORTCUTS_MODEL_COLUMN_FILE, &file,
                           -1);
 
       /* update the row */
-      g_object_set (row,
-                    "name", name,
-                    "icon", icon,
-                    NULL);
+      g_object_set (row, "label", name, "icon", icon, "file", file, NULL);
 
       /* release the values */
       g_free (name);
-      g_object_unref (icon);
+      if (icon != NULL)
+        g_object_unref (icon);
+      if (file != NULL)
+        g_object_unref (file);
     }
 
   /* free the row list */



More information about the Xfce4-commits mailing list