diff --git a/ChangeLog b/ChangeLog index ab00f47ef32758fefb8f43ec4fcd391e1cda114e..b3718c0aa49d14d20cc907a516acbb7609a0e1df 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2006-02-10 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-text-renderer.c(thunar_text_renderer_set_widget): Use + the base text direction specified by Gtk+. Also, do not interpret + line separators in file names. + * thunar-vfs/thunar-vfs-listdir-job.c, + thunar-vfs/thunar-vfs-marshal.list: Add boolean return value to the + ThunarVfsListdirJob::infos-ready signal, and allow handlers to take + over ownership of the infos list to avoid having to allocate a new + list (which reduces both performance overhead and the negative effects + on the data cache). Handlers must take care when using this feature, + documentation has been updated to explain the details. + * thunar/thunar-folder.c: Take over ownership of the list provided by + "infos-ready" and just replace the ThunarVfsInfo's with ThunarFile's + for the initial load case. For the reload case, there's no real gain + in taking over ownership, so we keep the existing behaviour there. + 2006-02-09 Benedikt Meurer <benny@xfce.org> * thunarx/thunarx-provider-factory.c: Initialize the factory on demand. diff --git a/thunar-vfs/thunar-vfs-listdir-job.c b/thunar-vfs/thunar-vfs-listdir-job.c index 9657531732aad5f7cd1f722434483149fe4d2afe..f55984488d3c8ec8b632a11ea8867979ae71b98b 100644 --- a/thunar-vfs/thunar-vfs-listdir-job.c +++ b/thunar-vfs/thunar-vfs-listdir-job.c @@ -31,6 +31,7 @@ #include <thunar-vfs/thunar-vfs-info.h> #include <thunar-vfs/thunar-vfs-listdir-job.h> +#include <thunar-vfs/thunar-vfs-marshal.h> #include <thunar-vfs/thunar-vfs-scandir.h> #include <thunar-vfs/thunar-vfs-alias.h> @@ -132,13 +133,30 @@ thunar_vfs_listdir_job_class_init (ThunarVfsJobClass *klass) * This signal is emitted whenever there's a new bunch of * #ThunarVfsInfo<!---->s ready. This signal is garantied * to be never emitted with an @infos parameter of %NULL. + * + * To allow some further optimizations on the handler-side, + * the handler is allowed to take over ownership of the @infos + * list, i.e. it can reuse the @infos list and just replace + * the data elements with it's own objects based on the + * #ThunarVfsInfo<!--->s contained within the @infos list (and + * of course properly unreffing the previously contained infos). + * If a handler takes over ownership of @infos it must return + * %TRUE here, and no further handlers will be run. Else, if + * the handler doesn't want to take over ownership of @infos, + * it must return %FALSE, and other handlers will be run. Use + * this feature with care, and only if you can be sure that + * you are the only handler connected to this signal for a + * given job! + * + * Return value: %TRUE if the handler took over ownership of + * @infos, else %FALSE. **/ listdir_signals[INFOS_READY] = g_signal_new (I_("infos-ready"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_NO_HOOKS, 0, NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); + G_TYPE_FROM_CLASS (klass), G_SIGNAL_NO_HOOKS, + 0, g_signal_accumulator_true_handled, NULL, + _thunar_vfs_marshal_BOOLEAN__POINTER, + G_TYPE_BOOLEAN, 1, G_TYPE_POINTER); } @@ -172,6 +190,7 @@ static void thunar_vfs_listdir_job_execute (ThunarVfsJob *job) { GThreadPool *pool; + gboolean handled = FALSE; GError *error = NULL; GList *list = NULL; GList *lp; @@ -276,11 +295,15 @@ thunar_vfs_listdir_job_execute (ThunarVfsJob *job) } else if (G_LIKELY (list != NULL)) { - thunar_vfs_job_emit (job, listdir_signals[INFOS_READY], 0, list); + /* emit the "infos-ready" signal with the given list */ + thunar_vfs_job_emit (job, listdir_signals[INFOS_READY], 0, list, &handled); + + /* check if one of the handlers took over ownership of the list, if + * not, we still own it and we are responsible to release it. + */ + if (G_UNLIKELY (!handled)) + thunar_vfs_info_list_free (list); } - - /* cleanup */ - thunar_vfs_info_list_free (list); } diff --git a/thunar-vfs/thunar-vfs-marshal.list b/thunar-vfs/thunar-vfs-marshal.list index e4c52859b0c73a34195d5294e5a02ff1c1c817f8..c716f5d728f806e487098862e1bfb5a0d4c00248 100644 --- a/thunar-vfs/thunar-vfs-marshal.list +++ b/thunar-vfs/thunar-vfs-marshal.list @@ -1 +1,2 @@ +BOOLEAN:POINTER FLAGS:STRING,FLAGS diff --git a/thunar/thunar-folder.c b/thunar/thunar-folder.c index bfbbedc07c02f5b50b080de5960a688aa591ef77..512b8b4a39e23fe804efebccf0fa2a15967c1f2b 100644 --- a/thunar/thunar-folder.c +++ b/thunar/thunar-folder.c @@ -44,33 +44,33 @@ enum -static void thunar_folder_class_init (ThunarFolderClass *klass); -static void thunar_folder_init (ThunarFolder *folder); -static void thunar_folder_finalize (GObject *object); -static void thunar_folder_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void thunar_folder_error (ThunarVfsJob *job, - GError *error, - ThunarFolder *folder); -static void thunar_folder_infos_ready (ThunarVfsJob *job, - GList *infos, - ThunarFolder *folder); -static void thunar_folder_finished (ThunarVfsJob *job, - ThunarFolder *folder); -static void thunar_folder_corresponding_file_destroy (ThunarFile *file, - ThunarFolder *folder); -static void thunar_folder_corresponding_file_renamed (ThunarFile *file, - ThunarFolder *folder); -static void thunar_folder_file_destroy (ThunarFile *file, - ThunarFolder *folder); -static void thunar_folder_monitor (ThunarVfsMonitor *monitor, - ThunarVfsMonitorHandle *handle, - ThunarVfsMonitorEvent event, - ThunarVfsPath *handle_path, - ThunarVfsPath *event_path, - gpointer user_data); +static void thunar_folder_class_init (ThunarFolderClass *klass); +static void thunar_folder_init (ThunarFolder *folder); +static void thunar_folder_finalize (GObject *object); +static void thunar_folder_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void thunar_folder_error (ThunarVfsJob *job, + GError *error, + ThunarFolder *folder); +static gboolean thunar_folder_infos_ready (ThunarVfsJob *job, + GList *infos, + ThunarFolder *folder); +static void thunar_folder_finished (ThunarVfsJob *job, + ThunarFolder *folder); +static void thunar_folder_corresponding_file_destroy (ThunarFile *file, + ThunarFolder *folder); +static void thunar_folder_corresponding_file_renamed (ThunarFile *file, + ThunarFolder *folder); +static void thunar_folder_file_destroy (ThunarFile *file, + ThunarFolder *folder); +static void thunar_folder_monitor (ThunarVfsMonitor *monitor, + ThunarVfsMonitorHandle *handle, + ThunarVfsMonitorEvent event, + ThunarVfsPath *handle_path, + ThunarVfsPath *event_path, + gpointer user_data); @@ -324,24 +324,27 @@ thunar_folder_error (ThunarVfsJob *job, -static void +static gboolean thunar_folder_infos_ready (ThunarVfsJob *job, GList *infos, ThunarFolder *folder) { ThunarFile *file; - GList *nfiles = NULL; + GList *nfiles; GList *fp; GList *lp; - g_return_if_fail (THUNAR_IS_FOLDER (folder)); - g_return_if_fail (THUNAR_VFS_IS_JOB (job)); - g_return_if_fail (folder->handle == NULL); - g_return_if_fail (folder->job == job); + g_return_val_if_fail (THUNAR_IS_FOLDER (folder), FALSE); + g_return_val_if_fail (THUNAR_VFS_IS_JOB (job), FALSE); + g_return_val_if_fail (folder->handle == NULL, FALSE); + g_return_val_if_fail (folder->job == job, FALSE); /* check if we have any previous files */ if (G_UNLIKELY (folder->previous_files != NULL)) { + /* start with a fresh list of new files */ + nfiles = NULL; + /* for every new info, check if we already have it on the previous list */ for (lp = infos; lp != NULL; lp = lp->next) { @@ -370,14 +373,20 @@ thunar_folder_infos_ready (ThunarVfsJob *job, } else { + /* take over ownership of the infos list */ + nfiles = infos; + /* add the new files to our temporary list of new files */ for (lp = infos; lp != NULL; lp = lp->next) { - /* get the file corresponding to the info */ + /* get the file corresponding to the info... */ file = thunar_file_get_for_info (lp->data); - /* add the file to the temporary list of new files */ - nfiles = g_list_prepend (nfiles, file); + /* ...release the info at the list position... */ + thunar_vfs_info_unref (lp->data); + + /* ...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, @@ -394,6 +403,9 @@ thunar_folder_infos_ready (ThunarVfsJob *job, /* tell the consumers that we have new files */ g_signal_emit (G_OBJECT (folder), folder_signals[FILES_ADDED], 0, nfiles); } + + /* return TRUE if we took over ownership of the infos list */ + return (nfiles == infos); } diff --git a/thunar/thunar-text-renderer.c b/thunar/thunar-text-renderer.c index 577f50404357fa072169d54fdb8e3712516ac13a..388bb90927696b221b1ff00fa435913743bd1532 100644 --- a/thunar/thunar-text-renderer.c +++ b/thunar/thunar-text-renderer.c @@ -675,6 +675,12 @@ thunar_text_renderer_set_widget (ThunarTextRenderer *text_renderer, context = gtk_widget_get_pango_context (widget); text_renderer->layout = pango_layout_new (context); + /* disable automatic text direction, but use the direction specified by Gtk+ */ + pango_layout_set_auto_dir (text_renderer->layout, FALSE); + + /* we don't want to interpret line separators in file names */ + pango_layout_set_single_paragraph_mode (text_renderer->layout, TRUE); + /* calculate the average character dimensions */ metrics = pango_context_get_metrics (context, widget->style->font_desc, pango_context_get_language (context)); text_renderer->char_width = PANGO_PIXELS (pango_font_metrics_get_approximate_char_width (metrics));