From 946027e708955e56ed083e7671fb3982647afafc Mon Sep 17 00:00:00 2001 From: Benedikt Meurer <benny@xfce.org> Date: Sun, 12 Feb 2006 16:33:34 +0000 Subject: [PATCH] 2006-02-12 Benedikt Meurer <benny@xfce.org> * thunar/thunar-file-monitor.{c,h}, thunar/Makefile.am: Add new class ThunarFileMonitor, which allows other objects stay informed about changes to ThunarFile's without having to connect signal handlers to every ThunarFile. Bug #1447. * thunar/thunar-file.c: Emit ThunarFileMonitor signals as appropriate. Bug #1447. * thunar/thunar-folder.c, thunar/thunar-list-model.c: Use the newly added ThunarFileMonitor to monitor files for changes and deletion without having to connect and disconnect signal handlers to each and every file. Bug #1447. (Old svn revision: 19848) --- ChangeLog | 13 +++ thunar/Makefile.am | 2 + thunar/thunar-file-monitor.c | 204 +++++++++++++++++++++++++++++++++++ thunar/thunar-file-monitor.h | 46 ++++++++ thunar/thunar-file.c | 20 +++- thunar/thunar-folder.c | 111 +++++++------------ thunar/thunar-list-model.c | 52 ++++----- 7 files changed, 344 insertions(+), 104 deletions(-) create mode 100644 thunar/thunar-file-monitor.c create mode 100644 thunar/thunar-file-monitor.h diff --git a/ChangeLog b/ChangeLog index b15d75352..040a0d9b1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2006-02-12 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-file-monitor.{c,h}, thunar/Makefile.am: Add new class + ThunarFileMonitor, which allows other objects stay informed about + changes to ThunarFile's without having to connect signal handlers to + every ThunarFile. Bug #1447. + * thunar/thunar-file.c: Emit ThunarFileMonitor signals as appropriate. + Bug #1447. + * thunar/thunar-folder.c, thunar/thunar-list-model.c: Use the newly + added ThunarFileMonitor to monitor files for changes and deletion + without having to connect and disconnect signal handlers to each and + every file. Bug #1447. + 2006-02-12 Benedikt Meurer <benny@xfce.org> * thunar/thunar-throbber-fallback.png: Import better throbber fallback diff --git a/thunar/Makefile.am b/thunar/Makefile.am index 115eb4725..c01d61dba 100644 --- a/thunar/Makefile.am +++ b/thunar/Makefile.am @@ -51,6 +51,8 @@ Thunar_SOURCES = \ thunar-enum-types.h \ thunar-file.c \ thunar-file.h \ + thunar-file-monitor.c \ + thunar-file-monitor.h \ thunar-folder.c \ thunar-folder.h \ thunar-gdk-extensions.c \ diff --git a/thunar/thunar-file-monitor.c b/thunar/thunar-file-monitor.c new file mode 100644 index 000000000..8733bc613 --- /dev/null +++ b/thunar/thunar-file-monitor.c @@ -0,0 +1,204 @@ +/* $Id$ */ +/*- + * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <thunar/thunar-file-monitor.h> + + + +/* Signal identifiers */ +enum +{ + FILE_CHANGED, + FILE_DESTROYED, + LAST_SIGNAL, +}; + + + +static void thunar_file_monitor_class_init (ThunarFileMonitorClass *klass); + + + +struct _ThunarFileMonitorClass +{ + GObjectClass __parent__; +}; + +struct _ThunarFileMonitor +{ + GObject __parent__; +}; + + + +static ThunarFileMonitor *file_monitor_default; +static guint file_monitor_signals[LAST_SIGNAL]; + + + +GType +thunar_file_monitor_get_type (void) +{ + static GType type = G_TYPE_INVALID; + + if (G_UNLIKELY (type == G_TYPE_INVALID)) + { + static const GTypeInfo info = + { + sizeof (ThunarFileMonitorClass), + NULL, + NULL, + (GClassInitFunc) thunar_file_monitor_class_init, + NULL, + NULL, + sizeof (ThunarFileMonitor), + 0, + NULL, + NULL, + }; + + type = g_type_register_static (G_TYPE_OBJECT, I_("ThunarFileMonitor"), &info, 0); + } + + return type; +} + + + +static void +thunar_file_monitor_class_init (ThunarFileMonitorClass *klass) +{ + /** + * ThunarFileMonitor::file-changed: + * @file_monitor : the default #ThunarFileMonitor. + * @file : the #ThunarFile that changed. + * + * This signal is emitted on @file_monitor whenever any of the currently + * existing #ThunarFile instances changes. @file identifies the instance + * that changed. + **/ + file_monitor_signals[FILE_CHANGED] = + g_signal_new (I_("file-changed"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_NO_HOOKS, + 0, NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, THUNAR_TYPE_FILE); + + /** + * ThunarFileMonitor::file-destroyed: + * @file_monitor : the default #ThunarFileMonitor. + * @file : the #ThunarFile that is about to be destroyed. + * + * This signal is emitted on @file_monitor whenever any of the currently + * existing #ThunarFile instances is about to be destroyed. @file identifies + * the instance that is about to be destroyed. + * + * Note that this signal is only emitted if @file is explicitly destroyed, + * i.e. because Thunar noticed that it was removed from disk, it is not + * emitted when the last reference on @file is released. + **/ + file_monitor_signals[FILE_DESTROYED] = + g_signal_new (I_("file-destroyed"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_NO_HOOKS, + 0, NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, THUNAR_TYPE_FILE); +} + + + +/** + * thunar_file_monitor_get_default: + * + * Returns a reference to the default #ThunarFileMonitor + * instance. The #ThunarFileMonitor default instance can + * be used to monitor the lifecycle of all currently existing + * #ThunarFile instances. The ::file-changed and ::file-destroyed + * signals will be emitted whenever any of the currently + * existing #ThunarFile<!---->s is changed or destroyed. + * + * The caller is responsible to free the returned instance + * using g_object_unref() when no longer needed. + * + * Return value: the default #ThunarFileMonitor instance. + **/ +ThunarFileMonitor* +thunar_file_monitor_get_default (void) +{ + if (G_UNLIKELY (file_monitor_default == NULL)) + { + /* allocate the default monitor */ + file_monitor_default = g_object_new (THUNAR_TYPE_FILE_MONITOR, NULL); + g_object_add_weak_pointer (G_OBJECT (file_monitor_default), + (gpointer) &file_monitor_default); + } + else + { + /* take a reference for the caller */ + g_object_ref (G_OBJECT (file_monitor_default)); + } + + return file_monitor_default; +} + + + +/** + * thunar_file_monitor_file_changed: + * @file : a #ThunarFile. + * + * Emits the ::file-changed signal on the default + * #ThunarFileMonitor (if any). This method should + * only be used by #ThunarFile. + **/ +void +thunar_file_monitor_file_changed (ThunarFile *file) +{ + g_return_if_fail (THUNAR_IS_FILE (file)); + + if (G_LIKELY (file_monitor_default != NULL)) + g_signal_emit (G_OBJECT (file_monitor_default), file_monitor_signals[FILE_CHANGED], 0, file); +} + + + +/** + * thunar_file_monitor_file_destroyed. + * @file : a #ThunarFile. + * + * Emits the ::file-destroyed signal on the default + * #ThunarFileMonitor (if any). This method should + * only be used by #ThunarFile. + **/ +void +thunar_file_monitor_file_destroyed (ThunarFile *file) +{ + g_return_if_fail (THUNAR_IS_FILE (file)); + + if (G_LIKELY (file_monitor_default != NULL)) + g_signal_emit (G_OBJECT (file_monitor_default), file_monitor_signals[FILE_DESTROYED], 0, file); +} + + diff --git a/thunar/thunar-file-monitor.h b/thunar/thunar-file-monitor.h new file mode 100644 index 000000000..3ee4dd7ca --- /dev/null +++ b/thunar/thunar-file-monitor.h @@ -0,0 +1,46 @@ +/* $Id$ */ +/*- + * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __THUNAR_FILE_MONITOR_H__ +#define __THUNAR_FILE_MONITOR_H__ + +#include <thunar/thunar-file.h> + +G_BEGIN_DECLS; + +typedef struct _ThunarFileMonitorClass ThunarFileMonitorClass; +typedef struct _ThunarFileMonitor ThunarFileMonitor; + +#define THUNAR_TYPE_FILE_MONITOR (thunar_file_monitor_get_type ()) +#define THUNAR_FILE_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_FILE_MONITOR, ThunarFileMonitor)) +#define THUNAR_FILE_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_FILE_MONITOR, ThunarFileMonitorClass)) +#define THUNAR_IS_FILE_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_FILE_MONITOR)) +#define THUNAR_IS_FILE_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_FILE_MONITOR)) +#define THUNAR_FILE_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_FILE_MONITOR, ThunarFileMonitorClass)) + +GType thunar_file_monitor_get_type (void) G_GNUC_CONST; + +ThunarFileMonitor *thunar_file_monitor_get_default (void); + +void thunar_file_monitor_file_changed (ThunarFile *file); +void thunar_file_monitor_file_destroyed (ThunarFile *file); + +G_END_DECLS; + +#endif /* !__THUNAR_FILE_MONITOR_H__ */ diff --git a/thunar/thunar-file.c b/thunar/thunar-file.c index dcc9d1afa..acd9d0789 100644 --- a/thunar/thunar-file.c +++ b/thunar/thunar-file.c @@ -44,6 +44,7 @@ #include <thunar/thunar-application.h> #include <thunar/thunar-chooser-dialog.h> #include <thunar/thunar-file.h> +#include <thunar/thunar-file-monitor.h> #include <thunar/thunar-gobject-extensions.h> @@ -457,6 +458,9 @@ thunar_file_info_changed (ThunarxFileInfo *file_info) /* notify about changes of the display-name property */ g_object_notify (G_OBJECT (file_info), "display-name"); + + /* tell the file monitor that this file changed */ + thunar_file_monitor_file_changed (THUNAR_FILE (file_info)); } @@ -1787,7 +1791,21 @@ thunar_file_destroy (ThunarFile *file) g_return_if_fail (THUNAR_IS_FILE (file)); if (G_LIKELY ((file->flags & THUNAR_FILE_IN_DESTRUCTION) == 0)) - g_object_run_dispose (G_OBJECT (file)); + { + /* take an additional reference on the file, as the file-destroyed + * invocation may already release the last reference. + */ + g_object_ref (G_OBJECT (file)); + + /* tell the file monitor that this file was destroyed */ + thunar_file_monitor_file_destroyed (file); + + /* run the dispose handler */ + g_object_run_dispose (G_OBJECT (file)); + + /* release our reference */ + g_object_unref (G_OBJECT (file)); + } } diff --git a/thunar/thunar-folder.c b/thunar/thunar-folder.c index 512b8b4a3..39508e2aa 100644 --- a/thunar/thunar-folder.c +++ b/thunar/thunar-folder.c @@ -21,6 +21,7 @@ #include <config.h> #endif +#include <thunar/thunar-file-monitor.h> #include <thunar/thunar-folder.h> #include <thunar/thunar-gobject-extensions.h> @@ -63,7 +64,8 @@ static void thunar_folder_corresponding_file_destroy (ThunarFile ThunarFolder *folder); static void thunar_folder_corresponding_file_renamed (ThunarFile *file, ThunarFolder *folder); -static void thunar_folder_file_destroy (ThunarFile *file, +static void thunar_folder_file_destroyed (ThunarFileMonitor *file_monitor, + ThunarFile *file, ThunarFolder *folder); static void thunar_folder_monitor (ThunarVfsMonitor *monitor, ThunarVfsMonitorHandle *handle, @@ -97,8 +99,7 @@ struct _ThunarFolder GList *previous_files; GList *files; - GClosure *file_destroy_closure; - gint file_destroy_id; + ThunarFileMonitor *file_monitor; ThunarVfsMonitor *monitor; ThunarVfsMonitorHandle *handle; @@ -220,13 +221,9 @@ thunar_folder_class_init (ThunarFolderClass *klass) static void thunar_folder_init (ThunarFolder *folder) { - /* lookup the id for the "destroy" signal of ThunarFile's */ - folder->file_destroy_id = g_signal_lookup ("destroy", THUNAR_TYPE_FILE); - - /* generate the closure to connect to the "destroy" signal of all files */ - folder->file_destroy_closure = g_cclosure_new (G_CALLBACK (thunar_folder_file_destroy), folder, NULL); - g_closure_ref (folder->file_destroy_closure); - g_closure_sink (folder->file_destroy_closure); + /* connect to the ThunarFileMonitor instance */ + folder->file_monitor = thunar_file_monitor_get_default (); + g_signal_connect (G_OBJECT (folder->file_monitor), "file-destroyed", G_CALLBACK (thunar_folder_file_destroyed), folder); /* connect to the file alteration monitor */ folder->monitor = thunar_vfs_monitor_get_default (); @@ -238,7 +235,10 @@ static void thunar_folder_finalize (GObject *object) { ThunarFolder *folder = THUNAR_FOLDER (object); - GList *lp; + + /* disconnect from the ThunarFileMonitor instance */ + g_signal_handlers_disconnect_by_func (G_OBJECT (folder->file_monitor), thunar_folder_file_destroyed, folder); + g_object_unref (G_OBJECT (folder->file_monitor)); /* disconnect from the file alteration monitor */ if (G_LIKELY (folder->handle != NULL)) @@ -262,25 +262,11 @@ thunar_folder_finalize (GObject *object) g_object_unref (G_OBJECT (folder->corresponding_file)); } - /* drop all previous files (if any) */ - if (G_UNLIKELY (folder->previous_files != NULL)) - { - /* actually drop the list of previous files */ - g_list_foreach (folder->previous_files, (GFunc) g_object_unref, NULL); - g_list_free (folder->previous_files); - } + /* release references to the previous files */ + thunar_file_list_free (folder->previous_files); /* release references to the current files */ - for (lp = folder->files; lp != NULL; lp = lp->next) - { - g_signal_handlers_disconnect_matched (G_OBJECT (lp->data), G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_CLOSURE, - folder->file_destroy_id, 0, folder->file_destroy_closure, NULL, NULL); - g_object_unref (G_OBJECT (lp->data)); - } - g_list_free (folder->files); - - /* drop the "destroy" closure */ - g_closure_unref (folder->file_destroy_closure); + thunar_file_list_free (folder->files); (*G_OBJECT_CLASS (thunar_folder_parent_class)->finalize) (object); } @@ -365,10 +351,6 @@ thunar_folder_infos_ready (ThunarVfsJob *job, /* yep, that's a new file then */ nfiles = g_list_prepend (nfiles, file); } - - /* connect the "destroy" signal */ - g_signal_connect_closure_by_id (G_OBJECT (file), folder->file_destroy_id, - 0, folder->file_destroy_closure, TRUE); } } else @@ -387,10 +369,6 @@ thunar_folder_infos_ready (ThunarVfsJob *job, /* ...and replace it with the file */ lp->data = file; - - /* connect the "destroy" signal */ - g_signal_connect_closure_by_id (G_OBJECT (file), folder->file_destroy_id, - 0, folder->file_destroy_closure, TRUE); } } @@ -427,8 +405,7 @@ thunar_folder_finished (ThunarVfsJob *job, g_signal_emit (G_OBJECT (folder), folder_signals[FILES_REMOVED], 0, folder->previous_files); /* actually drop the list of previous files */ - g_list_foreach (folder->previous_files, (GFunc) g_object_unref, NULL); - g_list_free (folder->previous_files); + thunar_file_list_free (folder->previous_files); folder->previous_files = NULL; } @@ -469,37 +446,38 @@ thunar_folder_corresponding_file_renamed (ThunarFile *file, g_return_if_fail (THUNAR_IS_FOLDER (folder)); g_return_if_fail (folder->corresponding_file == file); - /* re-register the VFS monitor handle if already connected */ - if (G_LIKELY (folder->handle != NULL)) - { - thunar_vfs_monitor_remove (folder->monitor, folder->handle); - folder->handle = thunar_vfs_monitor_add_directory (folder->monitor, thunar_file_get_path (file), - thunar_folder_monitor, folder); - } + /* reload the folder contents as all paths need to be updated */ + thunar_folder_reload (folder); } static void -thunar_folder_file_destroy (ThunarFile *file, - ThunarFolder *folder) +thunar_folder_file_destroyed (ThunarFileMonitor *file_monitor, + ThunarFile *file, + ThunarFolder *folder) { - GList files; + GList files; + GList *lp; g_return_if_fail (THUNAR_IS_FILE (file)); g_return_if_fail (THUNAR_IS_FOLDER (folder)); - g_return_if_fail (g_list_find (folder->files, file) != NULL); + g_return_if_fail (THUNAR_IS_FILE_MONITOR (file_monitor)); - /* disconnect from the file */ - g_signal_handlers_disconnect_matched (G_OBJECT (file), G_SIGNAL_MATCH_CLOSURE, 0, 0, folder->file_destroy_closure, NULL, NULL); - folder->files = g_list_remove (folder->files, file); + /* check if we have that file */ + lp = g_list_find (folder->files, file); + if (G_LIKELY (lp != NULL)) + { + /* remove the file from our list */ + folder->files = g_list_delete_link (folder->files, lp); - /* tell everybody that the file is gone */ - files.data = file; files.next = files.prev = NULL; - g_signal_emit (G_OBJECT (folder), folder_signals[FILES_REMOVED], 0, &files); + /* tell everybody that the file is gone */ + files.data = file; files.next = files.prev = NULL; + g_signal_emit (G_OBJECT (folder), folder_signals[FILES_REMOVED], 0, &files); - /* drop our reference to the file */ - g_object_unref (G_OBJECT (file)); + /* drop our reference to the file */ + g_object_unref (G_OBJECT (file)); + } } @@ -540,7 +518,6 @@ thunar_folder_monitor (ThunarVfsMonitor *monitor, return; /* prepend it to our internal list */ - g_signal_connect_closure_by_id (G_OBJECT (file), folder->file_destroy_id, 0, folder->file_destroy_closure, TRUE); folder->files = g_list_prepend (folder->files, file); /* tell others about the new file */ @@ -691,8 +668,6 @@ thunar_folder_get_loading (const ThunarFolder *folder) void thunar_folder_reload (ThunarFolder *folder) { - GList *lp; - g_return_if_fail (THUNAR_IS_FOLDER (folder)); /* check if we are currently connect to a job */ @@ -710,20 +685,8 @@ thunar_folder_reload (ThunarFolder *folder) folder->handle = NULL; } - /* drop all previous files (if any) */ - if (G_UNLIKELY (folder->previous_files != NULL)) - { - /* actually drop the list of previous files */ - g_list_foreach (folder->previous_files, (GFunc) g_object_unref, NULL); - g_list_free (folder->previous_files); - } - - /* disconnect signals from the current files */ - for (lp = folder->files; lp != NULL; lp = lp->next) - { - g_signal_handlers_disconnect_matched (G_OBJECT (lp->data), G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_CLOSURE, - folder->file_destroy_id, 0, folder->file_destroy_closure, NULL, NULL); - } + /* drop all previous files */ + thunar_file_list_free (folder->previous_files); /* remember the current files as previous files */ folder->previous_files = folder->files; diff --git a/thunar/thunar-list-model.c b/thunar/thunar-list-model.c index fe11ea44f..c00ec7ac4 100644 --- a/thunar/thunar-list-model.c +++ b/thunar/thunar-list-model.c @@ -28,6 +28,7 @@ #include <string.h> #endif +#include <thunar/thunar-file-monitor.h> #include <thunar/thunar-gobject-extensions.h> #include <thunar/thunar-list-model.h> @@ -136,7 +137,8 @@ static gboolean thunar_list_model_remove (ThunarListMod GtkTreeIter *iter, gboolean silently); static void thunar_list_model_sort (ThunarListModel *store); -static void thunar_list_model_file_changed (ThunarFile *file, +static void thunar_list_model_file_changed (ThunarFileMonitor *file_monitor, + ThunarFile *file, ThunarListModel *store); static void thunar_list_model_folder_destroy (ThunarFolder *folder, ThunarListModel *store); @@ -189,13 +191,13 @@ struct _ThunarListModel ThunarFolder *folder; gboolean show_hidden; - ThunarVfsVolumeManager *volume_manager; - - /* ids and closures for the "changed" signal of - * ThunarFile's used to speed up signal registrations. + /* Use the shared ThunarFileMonitor instance, so we + * do not need to connect "changed" handler to every + * file in the model. */ - GClosure *file_changed_closure; - gint file_changed_id; + ThunarFileMonitor *file_monitor; + + ThunarVfsVolumeManager *volume_manager; /* ids for the "row-inserted" and "row-deleted" signals * of GtkTreeModel to speed up folder changing. @@ -415,9 +417,6 @@ thunar_list_model_init (ThunarListModel *store) store->volume_manager = thunar_vfs_volume_manager_get_default (); - store->file_changed_closure = g_cclosure_new_object (G_CALLBACK (thunar_list_model_file_changed), G_OBJECT (store)); - store->file_changed_id = g_signal_lookup ("changed", THUNAR_TYPE_FILE); - store->row_inserted_id = g_signal_lookup ("row-inserted", GTK_TYPE_TREE_MODEL); store->row_deleted_id = g_signal_lookup ("row-deleted", GTK_TYPE_TREE_MODEL); @@ -425,9 +424,11 @@ thunar_list_model_init (ThunarListModel *store) store->sort_sign = 1; store->sort_func = sort_by_name; - /* take over ownership of the "changed" closure */ - g_closure_ref (store->file_changed_closure); - g_closure_sink (store->file_changed_closure); + /* connect to the shared ThunarFileMonitor, so we don't need to + * connect "changed" to every single ThunarFile we own. + */ + store->file_monitor = thunar_file_monitor_get_default (); + g_signal_connect (G_OBJECT (store->file_monitor), "file-changed", G_CALLBACK (thunar_list_model_file_changed), store); } @@ -456,8 +457,9 @@ thunar_list_model_finalize (GObject *object) /* disconnect from the volume manager */ g_object_unref (G_OBJECT (store->volume_manager)); - /* get rid of the "changed" closure */ - g_closure_unref (store->file_changed_closure); + /* disconnect from the file monitor */ + g_signal_handlers_disconnect_by_func (G_OBJECT (store->file_monitor), thunar_list_model_file_changed, store); + g_object_unref (G_OBJECT (store->file_monitor)); (*G_OBJECT_CLASS (thunar_list_model_parent_class)->finalize) (object); } @@ -1034,8 +1036,6 @@ thunar_list_model_remove (ThunarListModel *store, path = thunar_list_model_get_path (GTK_TREE_MODEL (store), iter); /* delete data associated with this row */ - g_signal_handlers_disconnect_matched (G_OBJECT (row->file), G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_CLOSURE, - store->file_changed_id, 0, store->file_changed_closure, NULL, NULL); g_object_unref (row->file); /* remove the link from the list */ @@ -1131,8 +1131,9 @@ thunar_list_model_sort (ThunarListModel *store) static void -thunar_list_model_file_changed (ThunarFile *file, - ThunarListModel *store) +thunar_list_model_file_changed (ThunarFileMonitor *file_monitor, + ThunarFile *file, + ThunarListModel *store) { GtkTreePath *path; GtkTreeIter iter; @@ -1141,10 +1142,13 @@ thunar_list_model_file_changed (ThunarFile *file, g_return_if_fail (THUNAR_IS_FILE (file)); g_return_if_fail (THUNAR_IS_LIST_MODEL (store)); + g_return_if_fail (THUNAR_IS_FILE_MONITOR (file_monitor)); + /* check if we have a row for that file */ for (n = 0, row = store->rows; row != NULL; ++n, row = row->next) if (G_UNLIKELY (row->file == file)) { + /* generate the iterator for this row */ iter.stamp = store->stamp; iter.user_data = row; @@ -1158,8 +1162,6 @@ thunar_list_model_file_changed (ThunarFile *file, return; } - - g_assert_not_reached (); } @@ -1224,8 +1226,6 @@ thunar_list_model_files_added (ThunarFolder *folder, { row = g_chunk_new (Row, store->row_chunk); row->file = file; - g_signal_connect_closure_by_id (G_OBJECT (file), store->file_changed_id, - 0, store->file_changed_closure, TRUE); /* find the position to insert the file to */ if (G_UNLIKELY (store->rows == NULL || thunar_list_model_cmp (store, file, store->rows->file) < 0)) @@ -1548,8 +1548,6 @@ thunar_list_model_set_folder (ThunarListModel *store, row = store->rows; /* delete data associated with this row */ - g_signal_handlers_disconnect_matched (G_OBJECT (row->file), G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_CLOSURE, - store->file_changed_id, 0, store->file_changed_closure, NULL, NULL); g_object_unref (G_OBJECT (row->file)); /* remove the row from the list */ @@ -1611,8 +1609,6 @@ thunar_list_model_set_folder (ThunarListModel *store, { row = g_chunk_new (Row, store->row_chunk); row->file = file; - g_signal_connect_closure_by_id (G_OBJECT (file), store->file_changed_id, - 0, store->file_changed_closure, TRUE); row->next = store->rows; store->rows = row; @@ -1753,8 +1749,6 @@ thunar_list_model_set_show_hidden (ThunarListModel *store, row = g_chunk_new (Row, store->row_chunk); row->file = file; - g_signal_connect_closure_by_id (G_OBJECT (file), store->file_changed_id, - 0, store->file_changed_closure, TRUE); if (G_UNLIKELY (store->rows == NULL || thunar_list_model_cmp (store, file, store->rows->file) < 0)) { -- GitLab