gnome-applets r10648 - in trunk: . trashapplet trashapplet/src



Author: ryanl
Date: Wed Feb 13 01:04:10 2008
New Revision: 10648
URL: http://svn.gnome.org/viewvc/gnome-applets?rev=10648&view=rev

Log:
2008-02-12  Ryan Lortie  <desrt desrt ca>

        * configure.in: PKG_CHECK_MODULES for GIO
        * Makefile.am: move trashapplet to not depend on gnome-vfs

2008-02-12  Ryan Lortie  <desrt desrt ca>

        * src/trash-monitor.h:
        * src/trash-monitor.c:
        * src/trashapplet.h:
        * src/trashapplet.c:
        * src/Makefile.am: move from GnomeVFS -> GIO.  Note REGRESSION: no
        longer do we have a progress dialog for emptying the trash.
        Closes bug #509759.



Modified:
   trunk/ChangeLog
   trunk/Makefile.am
   trunk/configure.in
   trunk/trashapplet/ChangeLog
   trunk/trashapplet/src/Makefile.am
   trunk/trashapplet/src/trash-monitor.c
   trunk/trashapplet/src/trash-monitor.h
   trunk/trashapplet/src/trashapplet.c
   trunk/trashapplet/src/trashapplet.h

Modified: trunk/Makefile.am
==============================================================================
--- trunk/Makefile.am	(original)
+++ trunk/Makefile.am	Wed Feb 13 01:04:10 2008
@@ -7,8 +7,7 @@
 
 vfs_applets = \
 	drivemount	\
-	gweather \
-	trashapplet
+	gweather
 if BUILD_GNOME_VFS_APPLETS
 vfs_SUBDIRS = $(vfs_applets)
 endif
@@ -45,12 +44,13 @@
 invest_applet_SUBDIR = invest-applet
 endif
 
-always_built_SUBDIRS = \
+always_built_SUBDIRS =  \
 	charpick	\
 	geyes		\
 	mini-commander	\
 	gkb-new		\
 	stickynotes	\
+	trashapplet	\
 	null_applet
 
 SUBDIRS = \

Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in	(original)
+++ trunk/configure.in	Wed Feb 13 01:04:10 2008
@@ -13,6 +13,7 @@
 dnl ***************************************************************************
 GTK_REQUIRED=2.11.0
 GLIB_REQUIRED=2.13.0
+GIO_REQUIRED=2.15.3
 LIBGNOME_REQUIRED=2.8.0
 LIBGNOMEUI_REQUIRED=2.8.0
 GNOME_VFS_REQUIRED=2.15.4
@@ -110,6 +111,11 @@
 AC_SUBST(GAILUTIL_CFLAGS)
 AC_SUBST(GAILUTIL_LIBS)
 
+dnl -- check for gio (required) ------------------------------------------
+PKG_CHECK_MODULES(GIO, gio-2.0 >= $GIO_REQUIRED)
+AC_SUBST(GIO_CFLAGS)
+AC_SUBST(GIO_LIBS)
+
 dnl -- Check for GTK+ 2.0 (required) ------------------------------------------
 PKG_CHECK_MODULES(GTK, gtk+-2.0 >= $GTK_REQUIRED)
 AC_SUBST(GTK_FLAGS)
@@ -271,13 +277,6 @@
 AC_SUBST(XML2_CFLAGS)
 AC_SUBST(XML2_LIBS)
 
-dnl -- check for libgweather (required for gweather applet) ------------------
-PKG_CHECK_MODULES(LIBGWEATHER, gweather >= $GWEATHER_REQUIRED)
-AC_SUBST(LIBGWEATHER_CFLAGS)
-AC_SUBST(LIBGWEATHER_LIBS)
-LIBGWEATHER_LOCATIONS=`pkg-config --variable=locations_file gweather`
-AC_SUBST(LIBGWEATHER_LOCATIONS)
-
 dnl ***************************************************************************
 dnl *** find paths to installed binaries                                    ***
 dnl ***************************************************************************

Modified: trunk/trashapplet/src/Makefile.am
==============================================================================
--- trunk/trashapplet/src/Makefile.am	(original)
+++ trunk/trashapplet/src/Makefile.am	Wed Feb 13 01:04:10 2008
@@ -1,6 +1,6 @@
 INCLUDES = -I$(top_srcdir)		\
 	   $(GNOME_APPLETS_CFLAGS)	\
-	   $(GNOME_VFS_APPLETS_CFLAGS) \
+	   $(GIO_CFLAGS) 		\
            $(LIBGLADE_CFLAGS)
 
 libexec_PROGRAMS = trashapplet
@@ -13,7 +13,7 @@
 	xstuff.c \
 	xstuff.h
 
-trashapplet_LDADD = \
-	$(GNOME_APPLETS_LIBS) \
-	$(GNOME_VFS_APPLETS_LIBS) \
+trashapplet_LDADD = 		\
+	$(GNOME_APPLETS_LIBS) 	\
+	$(GIO_LIBS) 		\
 	$(LIBGLADE_LIBS)

Modified: trunk/trashapplet/src/trash-monitor.c
==============================================================================
--- trunk/trashapplet/src/trash-monitor.c	(original)
+++ trunk/trashapplet/src/trash-monitor.c	Wed Feb 13 01:04:10 2008
@@ -1,8 +1,7 @@
 /*
  * trash-monitor.c: monitor the state of the trash directories.
  *
- * Copyright (C) 1999, 2000 Eazel, Inc.
- * Copyright (C) 2004 Canonical Ltd.
+ * Copyright  2008 Ryan Lortie, Matthias Clasen
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -20,428 +19,372 @@
  * 02111-1307, USA.
  */
 
+#include <gio/gio.h>
+
 #include "trash-monitor.h"
-#include <string.h>
-#include <libgnomevfs/gnome-vfs.h>
 
-struct _TrashMonitor {
+/* theory of operation:
+ *
+ * it's not possible to use file monitoring to keep track of the exact number
+ * of items in the trash, so we operate in the following way:
+ *
+ * 1) always keep track of if the trash is empty or not.
+ *
+ *   - on initialisation, we check if there is at least one item in the
+ *     trash and decide based on that if it is empty or not.
+ *
+ *   - if we receive a file monitor "created" event then the trash is no
+ *     longer empty
+ *
+ *   - if we receive a file monitor "deleted" event, we need to check again
+ *     (for at least one item) to determine emptiness.  this is done with a
+ *     timeout of 0.1s that is reschedule on each delete so that we don't
+ *     do a query for every single delete event (think: "empty trash").
+ *
+ *   - if the empty state changes, emit "notify::empty"
+ *
+ * 2) only query the actual number of items in the trash when requested
+ *
+ *   - keep a cache and used the cached value if present.
+ *
+ *   - we know when the trash is empty, so no need to check in this case
+ *     either.
+ *
+ *   - else, manually scan the trash directory.
+ *
+ *   - invalidate the cache on file monitor events.  even though we can't
+ *     be *absolutely* sure that it changed, emit "notify::items".
+ */
+
+struct _TrashMonitor
+{
   GObject parent;
 
-  GHashTable *volumes;
-  gint total_item_count;
-  gint notify_id;
+  GFile *trash;
+  gboolean empty;
+  guint empty_check_id;
+  GFileMonitor *file_monitor;
+
+  gboolean counted_items_valid;
+  int counted_items;
 };
 
-struct _TrashMonitorClass {
+struct _TrashMonitorClass
+{
   GObjectClass parent_class;
-
-  void (* item_count_changed) (TrashMonitor *monitor);
 };
 
-typedef struct {
-  TrashMonitor *monitor;
-  GnomeVFSVolume *volume;
-  gchar *trash_uri;
-  GnomeVFSAsyncHandle *find_handle;
-  GnomeVFSMonitorHandle *trash_change_monitor;
-  gint item_count;
-} VolumeInfo;
-
-
-static void trash_monitor_init (TrashMonitor *monitor);
-static void trash_monitor_class_init (TrashMonitorClass *class);
-
-enum {
-  ITEM_COUNT_CHANGED,
-  LAST_SIGNAL
+enum
+{
+  PROP_NONE,
+  PROP_EMPTY,
+  PROP_ITEMS
 };
-static GObjectClass *parent_class;
-static guint signals[LAST_SIGNAL];
-
 
-static void volume_mounted_callback (GnomeVFSVolumeMonitor *volume_monitor,
-				     GnomeVFSVolume *volume,
-				     TrashMonitor *monitor);
-static void volume_unmount_started_callback (GnomeVFSVolumeMonitor *volume_monitor,
-					     GnomeVFSVolume *volume,
-					     TrashMonitor *monitor);
+G_DEFINE_TYPE (TrashMonitor, trash_monitor, G_TYPE_OBJECT);
 
-static void add_volume    (TrashMonitor *monitor, GnomeVFSVolume *volume);
-static void remove_volume (TrashMonitor *monitor, GnomeVFSVolume *volume);
+static void
+trash_monitor_check_empty (TrashMonitor *monitor)
+{
+  GFileEnumerator *enumerator;
+  GError *error = NULL;
+  gboolean empty;
 
-static void trash_changed_queue_notify (TrashMonitor *monitor);
+  enumerator = g_file_enumerate_children (monitor->trash, "",
+                                          G_FILE_QUERY_INFO_NONE,
+                                          NULL, &error);
 
-G_DEFINE_TYPE (TrashMonitor, trash_monitor, G_TYPE_OBJECT)
+  if (enumerator)
+    {
+      GFileInfo *info;
 
+      if ((info = g_file_enumerator_next_file (enumerator, NULL, NULL)))
+        {
+          g_object_unref (info);
 
-static void
-trash_monitor_class_init (TrashMonitorClass *class)
-{
-  parent_class = g_type_class_peek_parent (class);
+          /* not empty, clearly */
+          empty = FALSE;
+        }
+      else
+        {
+          /* couldn't even read one file.  empty. */
+          empty = TRUE;
+        }
 
-  signals[ITEM_COUNT_CHANGED] = g_signal_new
-    ("item_count_changed",
-     G_TYPE_FROM_CLASS (class),
-     G_SIGNAL_RUN_LAST,
-     G_STRUCT_OFFSET (TrashMonitorClass, item_count_changed),
-     NULL, NULL,
-     g_cclosure_marshal_VOID__VOID,
-     G_TYPE_NONE, 0);
-}
+      g_object_unref (enumerator);
+    }
+  else
+    {
+      static gboolean showed_warning;
+
+      if (!showed_warning)
+        {
+          g_warning ("could not obtain enumerator for trash:///: %s",
+                      error->message);
+          showed_warning = TRUE;
+        }
 
-static void
-trash_monitor_init (TrashMonitor *monitor)
-{
-  GnomeVFSVolumeMonitor *volume_monitor;
-  GList *volumes, *tmp;
+      g_error_free (error);
 
-  monitor->volumes = g_hash_table_new (NULL, NULL);
-  monitor->total_item_count = 0;
-  monitor->notify_id = 0;
-
-  volume_monitor = gnome_vfs_get_volume_monitor ();
-  
-  g_signal_connect_object (volume_monitor, "volume_mounted",
-			   G_CALLBACK (volume_mounted_callback),
-			   monitor, 0);
-  g_signal_connect_object (volume_monitor, "volume_pre_unmount",
-			   G_CALLBACK (volume_unmount_started_callback),
-			   monitor, 0);
-
-  volumes = gnome_vfs_volume_monitor_get_mounted_volumes (volume_monitor);
-  for (tmp = volumes; tmp != NULL; tmp = tmp->next) {
-    GnomeVFSVolume *volume = tmp->data;
+      /* can't even open the trash directory.  assume empty. */
+      empty = TRUE;
+    }
 
-    add_volume (monitor, volume);
-    gnome_vfs_volume_unref (volume);
-  }
-  g_list_free (volumes);
+  if (empty != monitor->empty)
+    {
+      monitor->empty = empty;
+      g_object_notify (G_OBJECT (monitor), "empty");
+    }
 }
 
-TrashMonitor *
-trash_monitor_get (void)
+static gboolean
+trash_monitor_idle_check_empty (gpointer user_data)
 {
-  static TrashMonitor *monitor;
+  TrashMonitor *monitor = user_data;
 
-  if (!monitor) {
-    monitor = g_object_new (TRASH_TYPE_MONITOR, NULL);
-  }
-  return monitor;
-}
+  trash_monitor_check_empty (monitor);
+  monitor->empty_check_id = 0;
 
-static void
-volume_mounted_callback (GnomeVFSVolumeMonitor *volume_monitor,
-                         GnomeVFSVolume *volume,
-                         TrashMonitor *monitor)
-{
-  add_volume (monitor, volume);
+  return FALSE;
 }
 
-static void
-volume_unmount_started_callback (GnomeVFSVolumeMonitor *volume_monitor,
-                                 GnomeVFSVolume *volume,
-                                 TrashMonitor *monitor)
+static int
+trash_monitor_count_items (TrashMonitor *monitor)
 {
-  remove_volume (monitor, volume);
-}
-
-static void
-trash_dir_changed (GnomeVFSMonitorHandle *handle,
-		   const gchar *monitor_uri,
-		   const gchar *info_uri,
-		   GnomeVFSMonitorEventType type,
-		   gpointer user_data)
-{
-  VolumeInfo *volinfo;
-  GnomeVFSResult res;
-  GList *dirlist, *tmp;
-  gint count = 0;
-  
-  volinfo = user_data;
-  
-  res = gnome_vfs_directory_list_load (&dirlist, volinfo->trash_uri,
-				       GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
-  if (res != GNOME_VFS_OK) {
-    g_warning("GNOME VFS Error: %s", gnome_vfs_result_to_string (res));
-    return;
-  }
+  GFileEnumerator *enumerator;
+  GError *error = NULL;
+  GFileInfo *info;
+  int total;
+
+  if (monitor->counted_items_valid)
+    return monitor->counted_items;
+
+  if (monitor->empty)
+    {
+      monitor->counted_items = 0;
+      return 0;
+    }
 
-  for (tmp = dirlist; tmp != NULL; tmp = tmp->next) {
-    GnomeVFSFileInfo *info = tmp->data;
+  enumerator = g_file_enumerate_children (monitor->trash, "",
+                                          G_FILE_QUERY_INFO_NONE, NULL, NULL);
 
-    if (!strcmp (info->name, ".") || !strcmp (info->name, ".."))
-      continue;
-    count++;
-  }
-  gnome_vfs_file_info_list_free (dirlist);
-  
-  if (count != volinfo->item_count) {
-    volinfo->item_count = count;
-    trash_changed_queue_notify (volinfo->monitor);
-  }
-}
+  if (enumerator == NULL)
+    /* the empty-check will have already thrown a g_warning for this */
+    return 0;
+
+  total = 0;
+  while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL)))
+    {
+      g_object_unref (info);
+      total++;
+    }
 
-static void
-find_directory_callback (GnomeVFSAsyncHandle *handle,
-                         GList *results,
-                         gpointer callback_data)
-{
-  VolumeInfo *volinfo;
-  GnomeVFSFindDirectoryResult *result;
-  GnomeVFSResult res;
-
-  volinfo = callback_data;
-
-  /* we are done finding the volume */
-  volinfo->find_handle = NULL;
-
-  /* If we can't find the trash, ignore it silently. */
-  result = results->data;
-  if (result->result != GNOME_VFS_OK)
-    return;
+  if (error)
+    {
+      static gboolean showed_warning;
+
+      if (!showed_warning)
+        {
+          g_warning ("error while enumerating trash:///: %s\n",
+                     error->message);
+          showed_warning = TRUE;
+        }
 
-  volinfo->trash_uri = gnome_vfs_uri_to_string (result->uri,
-						GNOME_VFS_URI_HIDE_NONE);
-  /* g_message ("found trash dir: %s", volinfo->trash_uri); */
-
-  /* simulate a change to update the directory count */
-  trash_dir_changed (NULL, NULL, NULL, GNOME_VFS_MONITOR_EVENT_CHANGED,
-		     volinfo);
-
-  res = gnome_vfs_monitor_add (&volinfo->trash_change_monitor,
-			       volinfo->trash_uri, GNOME_VFS_MONITOR_DIRECTORY,
-			       trash_dir_changed,
-			       volinfo);
-
-  if (res != GNOME_VFS_OK) {
-    g_warning("GNOME VFS Error: %s", gnome_vfs_result_to_string (res));
-    volinfo->trash_change_monitor = NULL;
-  }
-}
+      g_error_free (error);
+    }
+  else
+    {
+      monitor->counted_items_valid = TRUE;
+      monitor->counted_items = total;
+    }
 
-static gboolean
-get_trash_volume (TrashMonitor *monitor,
-		  GnomeVFSVolume *volume,
-		  VolumeInfo **volinfo,
-		  GnomeVFSURI **mount_uri)
-{
-  char *uri_str;
-
-  *volinfo = g_hash_table_lookup (monitor->volumes, volume);
-
-  if (*volinfo != NULL && (*volinfo)->trash_uri != NULL)
-    return FALSE;
-
-  if (!gnome_vfs_volume_handles_trash (volume))
-    return FALSE;
-
-  uri_str = gnome_vfs_volume_get_activation_uri (volume);
-  *mount_uri = gnome_vfs_uri_new (uri_str);
-  g_free (uri_str);
-
-  if (*volinfo == NULL) {
-    *volinfo = g_new0 (VolumeInfo, 1);
-    (*volinfo)->monitor = monitor;
-    (*volinfo)->volume = gnome_vfs_volume_ref (volume);
-    g_hash_table_insert (monitor->volumes, volume, *volinfo);
-  }
+  g_object_unref (enumerator);
 
-  return TRUE;
+  return total;
 }
 
 static void
-add_volume (TrashMonitor *monitor, GnomeVFSVolume *volume)
+trash_monitor_changed (GFileMonitor      *file_monitor,
+                       GFile             *child,
+                       GFile             *other_file,
+                       GFileMonitorEvent  event_type,
+                       gpointer           user_data)
 {
-  VolumeInfo *volinfo;
-  GnomeVFSURI *mount_uri;
-  GList vfs_uri_as_list;
-
-  if (!get_trash_volume (monitor, volume, &volinfo, &mount_uri))
-    return;
-
-  if (volinfo->find_handle) {
-    /* already searchinf for trash */
-    gnome_vfs_uri_unref (mount_uri);
-    return;
-  }
+  TrashMonitor *monitor = user_data;
 
-  
-  vfs_uri_as_list.data = mount_uri;
-  vfs_uri_as_list.next = NULL;
-  vfs_uri_as_list.prev = NULL;
-
-  gnome_vfs_async_find_directory (&volinfo->find_handle, &vfs_uri_as_list,
-				  GNOME_VFS_DIRECTORY_KIND_TRASH,
-				  FALSE, TRUE, 0777,
-				  GNOME_VFS_PRIORITY_DEFAULT,
-				  find_directory_callback, volinfo);
-  gnome_vfs_uri_unref (mount_uri);
+  switch (event_type) 
+  {
+    case G_FILE_MONITOR_EVENT_DELETED:
+      /* wait until 0.1s after the last delete event before checking.
+       * this prevents us from re-checking for every delete event while
+       * emptying the trash.
+       */
+      if (monitor->empty_check_id)
+        g_source_remove (monitor->empty_check_id);
+
+      monitor->empty_check_id = g_timeout_add (100,
+                                               trash_monitor_idle_check_empty,
+                                               monitor);
+      break;
+
+    case G_FILE_MONITOR_EVENT_CREATED:
+      if (monitor->empty)
+        {
+          /* not any more... */
+          monitor->empty = FALSE;
+          g_object_notify (G_OBJECT (monitor), "empty");
+        }
+      break;
+
+    default:
+      return;
+  }  
+
+  if (monitor->counted_items_valid)
+    {
+      monitor->counted_items_valid = FALSE;
+      g_object_notify (G_OBJECT (monitor), "items");
+    }
 }
 
 static void
-remove_volume (TrashMonitor *monitor, GnomeVFSVolume *volume)
+trash_monitor_get_property (GObject *object, guint prop_id,
+                            GValue *value, GParamSpec *pspec)
 {
-  VolumeInfo *volinfo;
+  TrashMonitor *monitor = TRASH_MONITOR (object);
 
-  volinfo = g_hash_table_lookup (monitor->volumes, volume);
-  if (volinfo != NULL) {
-    g_hash_table_remove (monitor->volumes, volume);
-
-    /* g_message ("removing volume %s", volinfo->trash_uri); */
-    if (volinfo->find_handle != NULL)
-      gnome_vfs_async_cancel (volinfo->find_handle);
-    if (volinfo->trash_change_monitor != NULL)
-      gnome_vfs_monitor_cancel (volinfo->trash_change_monitor);
-
-    if (volinfo->trash_uri)
-      g_free (volinfo->trash_uri);
-
-    /* if this volume contained some trash, then notify that the trash
-     * state has changed */
-    if (volinfo->item_count != 0)
-      trash_changed_queue_notify (monitor);
+  switch (prop_id)
+  {
+    case PROP_EMPTY:
+      g_value_set_boolean (value, monitor->empty);
+      break;
+
+    case PROP_ITEMS:
+      g_value_set_int (value, trash_monitor_count_items (monitor));
+      break;
 
-    gnome_vfs_volume_unref (volinfo->volume);
-    g_free (volinfo);
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   }
 }
 
-/* --- */
-
 static void
-readd_volumes (gpointer key, gpointer value, gpointer user_data)
-{
-  TrashMonitor *monitor = user_data;
-  GnomeVFSVolume *volume;
-
-  volume = key;
-  add_volume (monitor, volume);
-}
-void
-trash_monitor_recheck_trash_dirs (TrashMonitor *monitor)
+trash_monitor_class_init (TrashMonitorClass *class)
 {
-  /* call add_volume() on each volume, to add trash dirs where missing */
-  g_hash_table_foreach (monitor->volumes, readd_volumes, monitor);
-}
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
 
-/* --- */
+  object_class->get_property = trash_monitor_get_property;
 
-void
-trash_monitor_empty_trash (TrashMonitor *monitor,
-			   GnomeVFSAsyncHandle **handle,
-			   GnomeVFSAsyncXferProgressCallback func,
-			   gpointer user_data)
-{
-  GList *trash_dirs = NULL, *volumes, *tmp;
-  GnomeVFSVolume *volume;
-  GnomeVFSURI *mount_uri, *trash_uri;
-  gchar *uri_str;
-
-  /* collect the trash directories */
-  volumes = gnome_vfs_volume_monitor_get_mounted_volumes (gnome_vfs_get_volume_monitor ());
-  for (tmp = volumes; tmp != NULL; tmp = tmp->next) {
-    volume = tmp->data;
-    if (gnome_vfs_volume_handles_trash (volume)) {
-      /* get the mount point for this volume */
-      uri_str = gnome_vfs_volume_get_activation_uri (volume);
-      mount_uri = gnome_vfs_uri_new (uri_str);
-      g_free (uri_str);
-
-      g_assert (mount_uri != NULL);
-
-      /* Look for the trash directory.  Since we tell it not to create or
-       * look for the dir, it doesn't block. */
-      if (gnome_vfs_find_directory (mount_uri,
-				    GNOME_VFS_DIRECTORY_KIND_TRASH, &trash_uri,
-				    FALSE, FALSE, 0777) == GNOME_VFS_OK) {
-	trash_dirs = g_list_prepend (trash_dirs, trash_uri);
-      }
-      gnome_vfs_uri_unref (mount_uri);
-    }
-    gnome_vfs_volume_unref (volume);
-  }
-  g_list_free (volumes);
-
-  if (trash_dirs != NULL)
-    gnome_vfs_async_xfer (handle, trash_dirs, NULL,
-			  GNOME_VFS_XFER_EMPTY_DIRECTORIES,
-			  GNOME_VFS_XFER_ERROR_MODE_ABORT,
-			  GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE,
-			  GNOME_VFS_PRIORITY_DEFAULT,
-			  func, user_data, NULL, NULL);
-  gnome_vfs_uri_list_free (trash_dirs);
+  g_object_class_install_property (object_class, PROP_EMPTY,
+    g_param_spec_boolean ("empty",
+                          "trash is empty",
+                          "true if the trash is empty",
+                          TRUE,
+                          G_PARAM_READABLE));
+
+  g_object_class_install_property (object_class, PROP_ITEMS,
+    g_param_spec_int ("items",
+                      "item count",
+                      "the number of items in the trash",
+                      0, G_MAXINT, 0,
+                      G_PARAM_READABLE));
 }
 
-
-/* --- */
-
 static void
-count_items (gpointer key, gpointer value, gpointer user_data)
+trash_monitor_init (TrashMonitor *monitor)
 {
-  VolumeInfo *volinfo;
-  gint *item_count;
+  GError *error;
+
+  monitor->trash = g_file_new_for_uri ("trash:///");
+  monitor->file_monitor = g_file_monitor_directory (monitor->trash, 0,
+                                                    NULL, &error);
+
+  if (monitor->file_monitor == NULL)
+    {
+      g_warning ("failed to register watch on trash:///: %s", error->message);
+      g_error_free (error);
+    }
+
+  trash_monitor_check_empty (monitor);
 
-  volinfo = value;
-  item_count = user_data;
-  *item_count += volinfo->item_count;
+  g_signal_connect_object (monitor->file_monitor, "changed",
+			   G_CALLBACK (trash_monitor_changed), monitor, 0);
 }
 
-static gboolean
-trash_changed_notify (gpointer user_data)
+TrashMonitor *
+trash_monitor_new (void)
 {
-  TrashMonitor *monitor = user_data;
-  gint item_count;
-
-  /* reset notification id */
-  monitor->notify_id = 0;
+  static TrashMonitor *monitor;
 
-  /* count the volumes */
-  item_count = 0;
-  g_hash_table_foreach (monitor->volumes, count_items, &item_count);
-
-  /* if the item count has changed ... */
-  if (item_count != monitor->total_item_count) {
-    monitor->total_item_count = item_count;
-    /* g_message ("item count is %d", item_count); */
-    g_signal_emit (monitor, signals[ITEM_COUNT_CHANGED], 0);
-  }
+  if (!monitor)
+    monitor = g_object_new (TRASH_TYPE_MONITOR, NULL);
 
-  return FALSE;
+  return g_object_ref (monitor);
 }
 
+/*
+ * if @file is a directory, delete its contents (but not @file itself).
+ * if @file is not a directory, do nothing.
+ */
 static void
-trash_changed_queue_notify (TrashMonitor *monitor)
+trash_monitor_delete_contents (GFile        *file,
+                               GCancellable *cancellable)
 {
-  /* already queued */
-  if (monitor->notify_id != 0)
+  GFileEnumerator *enumerator;
+  GFileInfo *info;
+  GFile *child;
+
+  if (g_cancellable_is_cancelled (cancellable))
     return;
 
-  monitor->notify_id = g_idle_add (trash_changed_notify, monitor);
-}
+  enumerator = g_file_enumerate_children (file,
+                                          G_FILE_ATTRIBUTE_STANDARD_NAME,
+                                          G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+                                          cancellable, NULL);
+  if (enumerator) 
+    {
+      while ((info = g_file_enumerator_next_file (enumerator,
+                                                  cancellable, NULL)) != NULL)
+        {
+          child = g_file_get_child (file, g_file_info_get_name (info));
+
+          /* it's just as fast to assume that all entries are subdirectories
+           * and try to erase their contents as it is to actually do the
+           * extra stat() call up front...
+           */
+          trash_monitor_delete_contents (child, cancellable);
+
+          g_file_delete (child, cancellable, NULL);
+
+          g_object_unref (child);
+          g_object_unref (info);
+
+          if (g_cancellable_is_cancelled (cancellable))
+            break;
+        }
 
-int
-trash_monitor_get_item_count (TrashMonitor *monitor)
-{
-  return monitor->total_item_count;
+      g_object_unref (enumerator);
+    }
 }
 
-/* --- */
-
-#ifdef TEST_TRASH_MONITOR
-int
-main (int argc, char **argv)
+static gboolean
+trash_monitor_empty_job (GIOSchedulerJob *job,
+                         GCancellable    *cancellable,
+                         gpointer         user_data)
 {
-  TrashMonitor *monitor;
-
-  if (!gnome_vfs_init ()) {
-    g_printerr ("Can not initialise gnome-vfs.\n");
-    return 1;
-  }
+  TrashMonitor *monitor = user_data;
 
-  monitor = trash_monitor_get ();
+  trash_monitor_delete_contents (monitor->trash, cancellable);
 
-  g_main_loop_run (g_main_loop_new (NULL, FALSE));
+  return FALSE;
+}
 
-  return 0;
+void
+trash_monitor_empty_trash (TrashMonitor *monitor,
+			   GCancellable *cancellable,
+			   gpointer      func, 
+			   gpointer      user_data)
+{
+  g_io_scheduler_push_job (trash_monitor_empty_job,
+                           monitor, NULL, 0, cancellable);
 }
-#endif

Modified: trunk/trashapplet/src/trash-monitor.h
==============================================================================
--- trunk/trashapplet/src/trash-monitor.h	(original)
+++ trunk/trashapplet/src/trash-monitor.h	Wed Feb 13 01:04:10 2008
@@ -1,8 +1,7 @@
 /*
  * trash-monitor.h: monitor the state of the trash directories.
  *
- * Copyright (C) 1999, 2000 Eazel, Inc.
- * Copyright (C) 2004 Canonical Ltd.
+ * Copyright  2008 Ryan Lortie, Matthias Clasen
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -23,27 +22,21 @@
 #ifndef __TRASH_MONITOR_H__
 #define __TRASH_MONITOR_H__
 
-#include <libgnomevfs/gnome-vfs.h>
+#include <gio/gio.h>
 
 typedef struct _TrashMonitor TrashMonitor;
 typedef struct _TrashMonitorClass TrashMonitorClass;
 
-#define TRASH_TYPE_MONITOR (trash_monitor_get_type ())
-#define TRASH_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TRASH_TYPE_MONITOR, TrashMonitor))
-#define TRASH_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TRASH_TYPE_MONITOR, TrashMonitorClass))
-#define TRASH_IS_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TRASH_TYPE_MONITOR))
-#define TRASH_IS_MONITOR_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), TRASH_TYPE_MONITOR))
-#define TRASH_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TRASH_TYPE_MONITOR, TrashMonitorClass))
-
-GType         trash_monitor_get_type  (void);
-TrashMonitor *trash_monitor_get       (void);
-
-/* check if new trash dirs have been created */
-void trash_monitor_recheck_trash_dirs (TrashMonitor *monitor);
-void trash_monitor_empty_trash        (TrashMonitor *monitor,
-				       GnomeVFSAsyncHandle **handle,
-				       GnomeVFSAsyncXferProgressCallback func,
-				       gpointer user_data);
-int  trash_monitor_get_item_count     (TrashMonitor *monitor);
+#define         TRASH_TYPE_MONITOR       (trash_monitor_get_type ())
+#define         TRASH_MONITOR(obj)       (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+                                          TRASH_TYPE_MONITOR, TrashMonitor))
+
+GType           trash_monitor_get_type          (void);
+TrashMonitor   *trash_monitor_new               (void);
+
+void            trash_monitor_empty_trash       (TrashMonitor *monitor,
+				                 GCancellable *cancellable,
+				                 gpointer      func,
+				                 gpointer      user_data);
 
 #endif

Modified: trunk/trashapplet/src/trashapplet.c
==============================================================================
--- trunk/trashapplet/src/trashapplet.c	(original)
+++ trunk/trashapplet/src/trashapplet.c	Wed Feb 13 01:04:10 2008
@@ -3,6 +3,8 @@
  *
  * Copyright (c) 2004  Michiel Sikkes <michiel eyesopened nl>,
  *               2004  Emmanuele Bassi <ebassi gmail com>
+ *               2008  Ryan Lortie <desrt desrt ca>
+ *                     Matthias Clasen <mclasen redhat com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -31,6 +33,7 @@
 #include <gconf/gconf-client.h>
 #include <libgnome/gnome-help.h>
 #include <glade/glade.h>
+#include <gio/gio.h>
 
 #include "trashapplet.h"
 #include "trash-monitor.h"
@@ -98,33 +101,66 @@
 };
 
 static void trash_applet_queue_update (TrashApplet  *applet);
-static void item_count_changed        (TrashMonitor *monitor,
-				       TrashApplet  *applet);
+static void empty_changed             (GObject      *monitor,
+                                       GParamSpec   *pspace,
+                                       gpointer      user_data);
+
+static gboolean
+trash_applet_query_tooltip (GtkWidget  *widget,
+                            gint        x,
+                            gint        y,
+                            gboolean    keyboard_tip,
+                            GtkTooltip *tooltip)
+{
+  TrashApplet *applet = TRASH_APPLET (widget);
+  gint items;
+
+  g_object_get (applet->monitor, "items", &items, NULL);
+
+  if (items)
+    {
+      char *text;
+
+      text = g_strdup_printf (ngettext ("%d Item in Trash",
+                                        "%d Items in Trash",
+                                        items), items);
+      gtk_tooltip_set_text (tooltip, text);
+      g_free (text);
+    }
+  else
+    gtk_tooltip_set_text (tooltip, _("No Items in Trash"));
+
+  return TRUE;
+}
 
 static void
 trash_applet_class_init (TrashAppletClass *class)
 {
-	GTK_OBJECT_CLASS (class)->destroy = trash_applet_destroy;
-	GTK_WIDGET_CLASS (class)->size_allocate = trash_applet_size_allocate;
-	GTK_WIDGET_CLASS (class)->button_release_event = trash_applet_button_release;
-	GTK_WIDGET_CLASS (class)->key_press_event = trash_applet_key_press;
-	GTK_WIDGET_CLASS (class)->drag_leave = trash_applet_drag_leave;
-	GTK_WIDGET_CLASS (class)->drag_motion = trash_applet_drag_motion;
-	GTK_WIDGET_CLASS (class)->drag_data_received = trash_applet_drag_data_received;
-	PANEL_APPLET_CLASS (class)->change_orient = trash_applet_change_orient;
-	PANEL_APPLET_CLASS (class)->change_background = trash_applet_change_background;
+  PanelAppletClass *applet_class = PANEL_APPLET_CLASS (class);
+  GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (class);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+
+  gtkobject_class->destroy = trash_applet_destroy;
+  widget_class->size_allocate = trash_applet_size_allocate;
+  widget_class->button_release_event = trash_applet_button_release;
+  widget_class->key_press_event = trash_applet_key_press;
+  widget_class->drag_leave = trash_applet_drag_leave;
+  widget_class->drag_motion = trash_applet_drag_motion;
+  widget_class->drag_data_received = trash_applet_drag_data_received;
+  widget_class->query_tooltip = trash_applet_query_tooltip;
+  applet_class->change_orient = trash_applet_change_orient;
+  applet_class->change_background = trash_applet_change_background;
 }
 
 static void
 trash_applet_init (TrashApplet *applet)
 {
-	GnomeVFSResult res;
-	GnomeVFSURI *trash_uri;
-
 	gtk_window_set_default_icon_name (TRASH_ICON_FULL);
 
 	panel_applet_set_flags (PANEL_APPLET (applet),
 				PANEL_APPLET_EXPAND_MINOR);
+        gtk_widget_set_has_tooltip (GTK_WIDGET (applet), TRUE);
+
 	/* get the default gconf client */
 	if (!client)
 		client = gconf_client_get_default ();
@@ -148,28 +184,13 @@
 	gtk_widget_show (applet->image);
 	applet->icon_state = TRASH_STATE_UNKNOWN;
 
-	/* create local trash directory if needed */
-	res = gnome_vfs_find_directory (NULL,
-					GNOME_VFS_DIRECTORY_KIND_TRASH,
-					&trash_uri,
-					TRUE,
-					TRUE,
-					0700);
-	if (trash_uri)
-		gnome_vfs_uri_unref (trash_uri);
-	if (res != GNOME_VFS_OK) {
-		g_warning (_("Unable to find the Trash directory: %s"),
-				gnome_vfs_result_to_string (res));
-	}
-
 	/* set up trash monitor */
-	applet->monitor = trash_monitor_get ();
+	applet->monitor = trash_monitor_new ();
 	applet->monitor_signal_id =
-		g_signal_connect (applet->monitor, "item_count_changed",
-				  G_CALLBACK (item_count_changed), applet);
+		g_signal_connect (applet->monitor, "notify::empty",
+				  G_CALLBACK (empty_changed), applet);
 
 	/* initial state */
-	applet->item_count = -1;
 	applet->is_empty = TRUE;
 	applet->drag_hover = FALSE;
 
@@ -197,6 +218,8 @@
 					     applet->monitor_signal_id);
 	applet->monitor_signal_id = 0;
 
+        g_object_unref (applet->monitor);
+
 	if (applet->update_id)
 		g_source_remove (applet->update_id);
 	applet->update_id = 0;
@@ -239,6 +262,7 @@
 		break;
 	case PANEL_APPLET_ORIENT_UP:
 	case PANEL_APPLET_ORIENT_DOWN:
+	default:
 		applet->orient = GTK_ORIENTATION_HORIZONTAL;
 		new_size = GTK_WIDGET (applet)->allocation.height;
 		break;
@@ -360,17 +384,17 @@
 }
 
 static void
-item_count_changed (TrashMonitor *monitor,
-		    TrashApplet  *applet)
+empty_changed (GObject    *monitor,
+               GParamSpec *pspac,
+               gpointer    user_data)
 {
-	trash_applet_queue_update (applet);
+  trash_applet_queue_update (TRASH_APPLET (user_data));
 }
 
 static gboolean
 trash_applet_update (gpointer user_data)
 {
 	TrashApplet *applet = TRASH_APPLET (user_data);
-	gint new_item_count;
 	BonoboUIComponent *popup_component;
 	char *tip_text;
 	TrashState new_state = TRASH_STATE_UNKNOWN;
@@ -378,13 +402,14 @@
 	GdkScreen *screen;
 	GtkIconTheme *icon_theme;
 	GdkPixbuf *pixbuf, *scaled;
+        gboolean is_empty;
 
 	applet->update_id = 0;
 
-	new_item_count = trash_monitor_get_item_count (applet->monitor);
-	if (new_item_count != applet->item_count) {
-		applet->item_count = new_item_count;
-		applet->is_empty = (applet->item_count == 0);
+        g_object_get (applet->monitor, "empty", &is_empty, NULL);
+	if (is_empty != applet->is_empty)
+        {
+		applet->is_empty = is_empty;
 
 		/* set sensitivity on the "empty trash" context menu item */
 		popup_component = panel_applet_get_popup_component (PANEL_APPLET (applet));
@@ -393,20 +418,6 @@
 					      "sensitive",
 					      applet->is_empty ? "0" : "1",
 					      NULL);
-
-		switch (applet->item_count) {
-		case 0:
-			tip_text = g_strdup (_("No Items in Trash"));
-			break;
-		default:
-			tip_text = g_strdup_printf (ngettext (
-						"%d Item in Trash",
-						"%d Items in Trash",
-						applet->item_count), 
-						    applet->item_count);
-		}
-		gtk_widget_set_tooltip_text (GTK_WIDGET (applet), tip_text);
-		g_free (tip_text);
 	}
 
 	/* work out what icon to use */
@@ -503,65 +514,6 @@
 	g_free (error_string);
 }
 
-static gint
-update_transfer_callback (GnomeVFSAsyncHandle *handle,
-                          GnomeVFSXferProgressInfo *progress_info,
-                          gpointer user_data)
-{
-	TrashApplet *applet = TRASH_APPLET (user_data);
-	GladeXML *xml = applet->xml;
-
-	if (progress_info->files_total != 0) {
-		GtkWidget *progressbar;
-		gdouble fraction;
-		gchar *progress_message;
-
-		progressbar = glade_xml_get_widget (xml, "progressbar");
-
-		fraction = (gulong) progress_info->file_index / (gulong) progress_info->files_total;
-		gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progressbar), fraction);
-
-		progress_message = g_strdup_printf (_("Removing item %d of %d"),
-						    progress_info->file_index,
-						    progress_info->files_total);
-		gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progressbar),
-					   progress_message);
-
-		g_free (progress_message);
-	}
-
-	if (progress_info->source_name != NULL) {
-		GtkWidget *location_label;
-		GtkWidget *file_label;
-		GnomeVFSURI *uri;
-		gchar *short_name;
-		gchar *from_location;
-		gchar *file;
-
-		location_label = glade_xml_get_widget (xml, "location_label");
-		file_label = glade_xml_get_widget (xml, "file_label");
-
-		uri = gnome_vfs_uri_new (progress_info->source_name);
-
-		from_location = gnome_vfs_uri_extract_dirname (uri);
-
-		short_name = gnome_vfs_uri_extract_short_name (uri);
-		file = g_strdup_printf ("<i>%s %s</i>",
-                                        _("Removing:"),
-                                        short_name);
-		g_free (short_name);
-
-		gtk_label_set_markup (GTK_LABEL (location_label), from_location);
-		gtk_label_set_markup (GTK_LABEL (file_label), file);
-
-		g_free (from_location);
-		g_free (file);
-		gnome_vfs_uri_unref (uri);
-       }
-
-       return 1;
-}
-
 /* this function is based on the one with the same name in
    libnautilus-private/nautilus-file-operations.c */
 #define NAUTILUS_PREFERENCES_CONFIRM_TRASH    "/apps/nautilus/preferences/confirm_trash"
@@ -627,13 +579,11 @@
 }
 
 static void
-on_empty_trash_cancel (GtkWidget *widget, GnomeVFSAsyncHandle **handle)
+on_empty_trash_cancel (GtkWidget    *widget,
+                       GCancellable *cancellable)
 {
-	if (handle != NULL) {
-		gnome_vfs_async_cancel ((GnomeVFSAsyncHandle *) handle);
-	}
-		
-	gtk_widget_hide (widget);
+  g_cancellable_cancel (cancellable);
+  gtk_widget_hide (widget);
 }
 
 static void
@@ -643,7 +593,7 @@
 {
 	GtkWidget *dialog;
 
-	GnomeVFSAsyncHandle *hnd;
+	GCancellable *cancellable;
 
 	g_return_if_fail (TRASH_IS_APPLET (applet));
 
@@ -656,16 +606,17 @@
 	if (!applet->xml)
 	  applet->xml = glade_xml_new (GNOME_GLADEDIR "/trashapplet.glade", NULL, NULL);
 
-        dialog = glade_xml_get_widget(applet->xml, "empty_trash");
+        dialog = glade_xml_get_widget (applet->xml, "empty_trash");
 
-	g_signal_connect(dialog, "response", G_CALLBACK (on_empty_trash_cancel), &hnd);
+	cancellable = g_cancellable_new ();
+	g_signal_connect (dialog, "response", G_CALLBACK (on_empty_trash_cancel), cancellable);
 
-	gtk_widget_show_all(dialog);
+	gtk_widget_show_all (dialog);
 
 	trash_monitor_empty_trash (applet->monitor,
-				   &hnd, update_transfer_callback, applet);
+				   cancellable, NULL, applet);
 
-	gtk_widget_hide(dialog);
+	gtk_widget_hide (dialog);
 
 }
 
@@ -846,80 +797,50 @@
 				 guint             time_)
 {
 	TrashApplet *applet = TRASH_APPLET (widget);
-  	GList *list, *scan;
-	GList *source_uri_list, *target_uri_list, *unmovable_uri_list;
-	GnomeVFSResult result;
-
-	list = gnome_vfs_uri_list_parse ((gchar *)selectiondata->data);
-
-	source_uri_list = NULL;
-	target_uri_list = NULL;
-	unmovable_uri_list = NULL;
-	for (scan = g_list_first (list); scan; scan = g_list_next (scan)) {
-		GnomeVFSURI *source_uri = scan->data;
-		GnomeVFSURI *trash_uri, *target_uri;
-		gchar *source_basename;
-
-		/* find the trash directory for this file */
-		result = gnome_vfs_find_directory (source_uri,
-						   GNOME_VFS_DIRECTORY_KIND_TRASH,
-						   &trash_uri, TRUE, FALSE, 0);
-		if (result != GNOME_VFS_OK) {
-			unmovable_uri_list = g_list_prepend (unmovable_uri_list,
-							     gnome_vfs_uri_ref (source_uri));
-			continue;
+	gchar **list;
+	gint i;
+	GList *trashed = NULL;
+	GList *untrashable = NULL;
+	GList *l;
+	GError *error = NULL;
+
+	list = g_uri_list_extract_uris ((gchar *)selectiondata->data);
+
+	for (i = 0; list[i]; i++) {
+		GFile *file;
+
+		file = g_file_new_for_uri (list[i]);
+		if (!g_file_trash (file, NULL, NULL)) {
+			untrashable = g_list_prepend (untrashable, file);
 		}
-
-		source_basename = gnome_vfs_uri_extract_short_name
-			(source_uri);
-
-		target_uri = gnome_vfs_uri_append_file_name(trash_uri,
-							    source_basename);
-		g_free (source_basename);
-		gnome_vfs_uri_unref (trash_uri);
-
-		source_uri_list = g_list_prepend (source_uri_list,
-						  gnome_vfs_uri_ref (source_uri));
-		target_uri_list = g_list_prepend (target_uri_list,
-						  target_uri);
-	}
-
-	gnome_vfs_uri_list_free(list);
-
-	/* we might have added a trash dir, so recheck */
-	trash_monitor_recheck_trash_dirs (applet->monitor);
-
-	if (source_uri_list) {
-		result = gnome_vfs_xfer_uri_list (source_uri_list, target_uri_list,
-						  GNOME_VFS_XFER_REMOVESOURCE |
-						  GNOME_VFS_XFER_RECURSIVE,
-						  GNOME_VFS_XFER_ERROR_MODE_ABORT,
-						  GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE,
-						  NULL, NULL);
-		gnome_vfs_uri_list_free (source_uri_list);
-		gnome_vfs_uri_list_free (target_uri_list);
-		if (result != GNOME_VFS_OK) {
-			error_dialog (applet, _("Unable to move to trash:\n%s"),
-				      gnome_vfs_result_to_string (result));
+		else {
+			trashed = g_list_prepend (trashed, file);
 		}
 	}
-	if (unmovable_uri_list) {
-		if (confirm_delete_immediately (widget,
-						g_list_length (unmovable_uri_list),
-						source_uri_list == NULL)) {
-			result = gnome_vfs_xfer_delete_list (unmovable_uri_list,
-							     GNOME_VFS_XFER_ERROR_MODE_ABORT,
-							     GNOME_VFS_XFER_RECURSIVE,
-							     NULL, NULL);
-		} else {
-			result = GNOME_VFS_OK;
-		}
-		gnome_vfs_uri_list_free (unmovable_uri_list);
-		if (result != GNOME_VFS_OK) {
-			error_dialog (applet, _("Unable to move to trash:\n%s"),
-				      gnome_vfs_result_to_string (result));
+	
+	if (untrashable) {
+		if (confirm_delete_immediately (widget, 
+						g_list_length (untrashable),
+						trashed == NULL)) {
+			for (l = untrashable; l; l = l->next) {
+				if (!g_file_delete (l->data, NULL, &error)) {
+					error_dialog (applet,
+						      _("Unable to delete '%s': %s"),
+							g_file_get_uri (l->data),
+							error->message);
+					g_clear_error (&error);
+				}	
+			}
 		}
 	}
+
+	g_list_foreach (untrashable, (GFunc)g_object_unref, NULL);
+	g_list_free (untrashable);
+	g_list_foreach (trashed, (GFunc)g_object_unref, NULL);
+	g_list_free (trashed);
+
+	g_strfreev (list);	
+
 	gtk_drag_finish (context, TRUE, FALSE, time_);
 }
 
@@ -951,6 +872,8 @@
 int
 main (int argc, char *argv [])
 {
+	g_thread_init (NULL);
+
 	/* gettext stuff */
         bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
         bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");

Modified: trunk/trashapplet/src/trashapplet.h
==============================================================================
--- trunk/trashapplet/src/trashapplet.h	(original)
+++ trunk/trashapplet/src/trashapplet.h	Wed Feb 13 01:04:10 2008
@@ -59,7 +59,6 @@
 	GtkWidget *image;
 	TrashState icon_state;
 
-	gint item_count;
 	gboolean is_empty;
 	gboolean drag_hover;
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]