From 759da4d9cbd7fe5b2a4cacfd1910078520e73306 Mon Sep 17 00:00:00 2001 From: Benedikt Meurer <benny@xfce.org> Date: Sat, 27 Aug 2005 17:34:23 +0000 Subject: [PATCH] 2005-08-27 Benedikt Meurer <benny@xfce.org> * thunar-vfs/thunar-vfs-trash.c: Use ThunarVfsMonitor instead of polling the trash files/ directories manually. (Old svn revision: 17134) --- ChangeLog | 5 + thunar-vfs/thunar-vfs-trash.c | 236 +++++++++++++++------------------- 2 files changed, 110 insertions(+), 131 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1570b5636..b8513213d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-08-27 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-trash.c: Use ThunarVfsMonitor instead of + polling the trash files/ directories manually. + 2005-08-27 Benedikt Meurer <benny@xfce.org> * thunar-vfs/thunar-vfs-mime-legacy.c: Add support for MIME-type diff --git a/thunar-vfs/thunar-vfs-trash.c b/thunar-vfs/thunar-vfs-trash.c index 5b073d97c..83070d890 100644 --- a/thunar-vfs/thunar-vfs-trash.c +++ b/thunar-vfs/thunar-vfs-trash.c @@ -46,16 +46,10 @@ #include <exo/exo.h> +#include <thunar-vfs/thunar-vfs-monitor.h> #include <thunar-vfs/thunar-vfs-trash.h> #include <thunar-vfs/thunar-vfs-alias.h> -/* we use g_stat() if possible */ -#if GLIB_CHECK_VERSION(2,6,0) -#include <glib/gstdio.h> -#else -#define g_stat(path, buffer) (stat ((path), (buffer))) -#endif - static ThunarVfsTrashInfo *thunar_vfs_trash_info_new (const gchar *path, @@ -160,7 +154,7 @@ const gchar* thunar_vfs_trash_info_get_path (const ThunarVfsTrashInfo *info) { g_return_val_if_fail (info != NULL, NULL); - return ((gchar *) info) + sizeof (*info); + return ((const gchar *) info) + sizeof (*info); } @@ -177,17 +171,12 @@ const gchar* thunar_vfs_trash_info_get_deletion_date (const ThunarVfsTrashInfo *info) { g_return_val_if_fail (info != NULL, NULL); - return ((gchar *) info) + info->deletion_date_offset; + return ((const gchar *) info) + info->deletion_date_offset; } -/* interval in which trashes will be checked */ -#define THUNAR_VFS_TRASH_INTERVAL (5 * 1000) - - - enum { THUNAR_VFS_TRASH_PROP_0, @@ -196,17 +185,19 @@ enum -static void thunar_vfs_trash_class_init (ThunarVfsTrashClass *klass); -static void thunar_vfs_trash_init (ThunarVfsTrash *trash); -static void thunar_vfs_trash_finalize (GObject *object); -static void thunar_vfs_trash_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void thunar_vfs_trash_update (ThunarVfsTrash *trash); -static gboolean thunar_vfs_trash_update_timer (gpointer user_data); -static void thunar_vfs_trash_update_timer_destroy (gpointer user_data); -static ThunarVfsTrash *thunar_vfs_trash_new_internal (gchar *directory); +static void thunar_vfs_trash_class_init (ThunarVfsTrashClass *klass); +static void thunar_vfs_trash_init (ThunarVfsTrash *trash); +static void thunar_vfs_trash_finalize (GObject *object); +static void thunar_vfs_trash_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void thunar_vfs_trash_monitor (ThunarVfsMonitor *monitor, + ThunarVfsMonitorHandle *handle, + ThunarVfsMonitorEvent event, + ThunarVfsURI *handle_uri, + ThunarVfsURI *event_uri, + gpointer user_data); @@ -219,13 +210,13 @@ struct _ThunarVfsTrash { GtkObject __parent__; - gint id; - GList *files; - gchar *directory; - gchar *files_directory; + gint id; + GList *files; + ThunarVfsURI *base_directory; + ThunarVfsURI *files_directory; - time_t update_last_ctime; - gint update_timer_id; + ThunarVfsMonitor *monitor; + ThunarVfsMonitorHandle *handle; }; @@ -262,8 +253,7 @@ thunar_vfs_trash_class_init (ThunarVfsTrashClass *klass) static void thunar_vfs_trash_init (ThunarVfsTrash *trash) { - trash->update_last_ctime = (time_t) -1; - trash->update_timer_id = -1; + trash->monitor = thunar_vfs_monitor_get_default (); } @@ -272,24 +262,22 @@ static void thunar_vfs_trash_finalize (GObject *object) { ThunarVfsTrash *trash = THUNAR_VFS_TRASH (object); - GList *lp; - /* stop the update timer */ - if (G_LIKELY (trash->update_timer_id >= 0)) - g_source_remove (trash->update_timer_id); + /* detach from the VFS monitor */ + thunar_vfs_monitor_remove (trash->monitor, trash->handle); + g_object_unref (G_OBJECT (trash->monitor)); /* free the list of files */ - for (lp = trash->files; lp != NULL; lp = lp->next) - g_free ((gchar *) lp->data); + g_list_foreach (trash->files, (GFunc) g_free, NULL); g_list_free (trash->files); /* free the files directory path */ - g_free (trash->files_directory); + thunar_vfs_uri_unref (trash->files_directory); /* free the base directory path */ - g_free (trash->directory); + thunar_vfs_uri_unref (trash->base_directory); - G_OBJECT_CLASS (thunar_vfs_trash_parent_class)->finalize (object); + (*G_OBJECT_CLASS (thunar_vfs_trash_parent_class)->finalize) (object); } @@ -317,97 +305,64 @@ thunar_vfs_trash_get_property (GObject *object, static void -thunar_vfs_trash_update (ThunarVfsTrash *trash) -{ - const gchar *name; - struct stat sb; - gboolean emit = FALSE; - time_t ctime = (time_t) -1; - GList *new_files = NULL; - GList *lp; - GDir *dp; - - /* stat the files/ subdirectory */ - if (g_stat (trash->files_directory, &sb) == 0) - ctime = sb.st_ctime; - - /* update only if the ctimes differ */ - if (G_LIKELY (ctime == trash->update_last_ctime)) - return; - else - trash->update_last_ctime = ctime; +thunar_vfs_trash_monitor (ThunarVfsMonitor *monitor, + ThunarVfsMonitorHandle *handle, + ThunarVfsMonitorEvent event, + ThunarVfsURI *handle_uri, + ThunarVfsURI *event_uri, + gpointer user_data) +{ + ThunarVfsTrash *trash = THUNAR_VFS_TRASH (user_data); + const gchar *name; + GList *lp; - dp = g_dir_open (trash->files_directory, 0, NULL); - if (G_LIKELY (dp != NULL)) + /* check if the event affects the files directory or a file below it */ + if (thunar_vfs_uri_equal (trash->files_directory, event_uri)) { - for (;;) + if (event == THUNAR_VFS_MONITOR_EVENT_DELETED && trash->files != NULL) { - /* read the next entry */ - name = g_dir_read_name (dp); - if (name == NULL) - break; + /* clear the list of files */ + g_list_foreach (trash->files, (GFunc) g_free, NULL); + g_list_free (trash->files); + trash->files = NULL; - /* ignore '.' and '..' entries */ - if (name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'))) - continue; + /* tell everybody */ + g_object_notify (G_OBJECT (trash), "files"); + } + } + else + { + /* determine the basename of the affected file */ + name = thunar_vfs_uri_get_name (event_uri); - /* check if we already know about that file */ + /* check if the file was added or removed */ + if (event == THUNAR_VFS_MONITOR_EVENT_CREATED) + { + /* check if we already know that file */ for (lp = trash->files; lp != NULL; lp = lp->next) - if (exo_str_is_equal (lp->data, name)) + if (G_UNLIKELY (strcmp (lp->data, name) == 0)) break; - if (lp != NULL) - { - trash->files = g_list_remove_link (trash->files, lp); - new_files = g_list_concat (lp, new_files); - } - else + /* add the file if we don't know about it yet */ + if (G_LIKELY (lp == NULL)) { - new_files = g_list_prepend (new_files, g_strdup (name)); - emit = TRUE; + trash->files = g_list_prepend (trash->files, g_strdup (name)); + g_object_notify (G_OBJECT (trash), "files"); } } - - g_dir_close (dp); - } - - /* check if we have leftover files (deleted files) */ - if (trash->files != NULL) - { - for (lp = trash->files; lp != NULL; lp = lp->next) - g_free ((gchar *) lp->data); - g_list_free (trash->files); - trash->files = NULL; - emit = TRUE; + else if (event == THUNAR_VFS_MONITOR_EVENT_DELETED) + { + /* check if we know about the file */ + for (lp = trash->files; lp != NULL; lp = lp->next) + if (G_UNLIKELY (strcmp (lp->data, name) == 0)) + { + g_free (lp->data); + trash->files = g_list_delete_link (trash->files, lp); + g_object_notify (G_OBJECT (trash), "files"); + break; + } + } } - - /* activate the new files list */ - trash->files = new_files; - - /* emit notification (if necessary) */ - if (G_UNLIKELY (emit)) - g_object_notify (G_OBJECT (trash), "files"); -} - - - -static gboolean -thunar_vfs_trash_update_timer (gpointer user_data) -{ - GDK_THREADS_ENTER (); - thunar_vfs_trash_update (THUNAR_VFS_TRASH (user_data)); - GDK_THREADS_LEAVE (); - return TRUE; -} - - - -static void -thunar_vfs_trash_update_timer_destroy (gpointer user_data) -{ - GDK_THREADS_ENTER (); - THUNAR_VFS_TRASH (user_data)->update_timer_id = -1; - GDK_THREADS_LEAVE (); } @@ -416,22 +371,40 @@ static ThunarVfsTrash* thunar_vfs_trash_new_internal (gchar *directory) { ThunarVfsTrash *trash; + const gchar *name; + GDir *dp; g_return_val_if_fail (directory != NULL, NULL); g_return_val_if_fail (g_path_is_absolute (directory), NULL); /* allocate the trash object (directory string is taken!) */ trash = g_object_new (THUNAR_VFS_TYPE_TRASH, NULL); - trash->directory = directory; - trash->files_directory = g_build_filename (directory, "files", NULL); + trash->base_directory = thunar_vfs_uri_new_for_path (directory); + trash->files_directory = thunar_vfs_uri_relative (trash->base_directory, "files"); - /* force an update to read the current trash contents */ - thunar_vfs_trash_update (trash); + /* load the files from the trash files/ directory */ + dp = g_dir_open (thunar_vfs_uri_get_path (trash->files_directory), 0, NULL); + if (G_LIKELY (dp != NULL)) + { + for (;;) + { + /* read the next entry */ + name = g_dir_read_name (dp); + if (name == NULL) + break; + + /* ignore '.' and '..' entries */ + if (name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'))) + continue; + + trash->files = g_list_prepend (trash->files, g_strdup (name)); + } + g_dir_close (dp); + } - /* schedule a timer to regularly check the trash contents */ - trash->update_timer_id = g_timeout_add_full (G_PRIORITY_LOW, THUNAR_VFS_TRASH_INTERVAL, - thunar_vfs_trash_update_timer, trash, - thunar_vfs_trash_update_timer_destroy); + /* register with the VFS monitor */ + trash->handle = thunar_vfs_monitor_add_directory (trash->monitor, trash->files_directory, + thunar_vfs_trash_monitor, trash); /* drop the floating reference */ g_object_ref (G_OBJECT (trash)); @@ -554,7 +527,8 @@ thunar_vfs_trash_get_info_path (ThunarVfsTrash *trash, g_return_val_if_fail (THUNAR_VFS_IS_TRASH (trash), NULL); g_return_val_if_fail (file != NULL && strchr (file, '/') == NULL, NULL); - return g_strconcat (trash->directory, G_DIR_SEPARATOR_S, "info", G_DIR_SEPARATOR_S, file, ".trashinfo", NULL); + return g_strconcat (thunar_vfs_uri_get_path (trash->base_directory), G_DIR_SEPARATOR_S, + "info", G_DIR_SEPARATOR_S, file, ".trashinfo", NULL); } @@ -576,7 +550,7 @@ thunar_vfs_trash_get_path (ThunarVfsTrash *trash, g_return_val_if_fail (THUNAR_VFS_IS_TRASH (trash), NULL); g_return_val_if_fail (file != NULL, NULL); - return g_build_filename (trash->files_directory, file, NULL); + return g_build_filename (thunar_vfs_uri_get_path (trash->files_directory), file, NULL); } -- GitLab