[Xfce4-commits] <thunar:master> Use a timeout/idle to request thumbnails in ThunarStandardView.
Jannis Pohlmann
noreply at xfce.org
Mon Feb 14 14:10:02 CET 2011
Updating branch refs/heads/master
to 834e6455488ccfb505127ba175e5366e1c652691 (commit)
from f19df728cf8798152b175dd61467ea1633663660 (commit)
commit 834e6455488ccfb505127ba175e5366e1c652691
Author: Jannis Pohlmann <jannis at xfce.org>
Date: Mon Feb 7 15:12:29 2011 +0100
Use a timeout/idle to request thumbnails in ThunarStandardView.
This is the second part of redesigning how thumbnails are requested in
Thunar. Each ThunarStandardView now has a ThunerThumbnailer object.
On scroll and resize events and whenever a new directory has finished
loading, ThunarStandardView now schedules a timeout or idle handler
(depending on the situation) to request thumbnails for all visible items
of the view.
This timeout/idle handler is rescheduled whenever the user starts
or continues scrolling or resizing. This avoids sending requests while
the user is scrolling and its important to not have D-Bus interfere with
the Thunar main loop. We now have a much more responsive thumbnailing
and scrolling experience!
Requests are also dropped by each view when a directory is closed/left.
This means that we no longer generate thumbnails the user is not
interested in any more.
This commit also uses the proper D-Bus method for cancelling thumbnail
requests (it's called "Dequeue", not "Unqueue").
The properties dialog is updated to match changes in the
ThunarThumbnailer API.
thunar/thunar-properties-dialog.c | 60 ++++----
thunar/thunar-standard-view.c | 258 ++++++++++++++++++++++++++++++++++--
thunar/thunar-thumbnailer-dbus.xml | 2 +-
thunar/thunar-thumbnailer.c | 191 ++++-----------------------
thunar/thunar-thumbnailer.h | 14 +-
5 files changed, 307 insertions(+), 218 deletions(-)
diff --git a/thunar/thunar-properties-dialog.c b/thunar/thunar-properties-dialog.c
index 2633950..f52c20b 100644
--- a/thunar/thunar-properties-dialog.c
+++ b/thunar/thunar-properties-dialog.c
@@ -108,34 +108,34 @@ struct _ThunarPropertiesDialogClass
struct _ThunarPropertiesDialog
{
- ThunarAbstractDialog __parent__;
-
- ThunarxProviderFactory *provider_factory;
- GList *provider_pages;
-
- ThunarPreferences *preferences;
-
- ThunarFile *file;
-
- ThunarThumbnailer *thumbnailer;
- ThunarThumbnailerRequest thumbnail_request;
-
- GtkWidget *notebook;
- GtkWidget *icon_button;
- GtkWidget *icon_image;
- GtkWidget *name_entry;
- GtkWidget *kind_ebox;
- GtkWidget *kind_label;
- GtkWidget *openwith_chooser;
- GtkWidget *link_label;
- GtkWidget *origin_label;
- GtkWidget *deleted_label;
- GtkWidget *modified_label;
- GtkWidget *accessed_label;
- GtkWidget *freespace_label;
- GtkWidget *volume_image;
- GtkWidget *volume_label;
- GtkWidget *permissions_chooser;
+ ThunarAbstractDialog __parent__;
+
+ ThunarxProviderFactory *provider_factory;
+ GList *provider_pages;
+
+ ThunarPreferences *preferences;
+
+ ThunarFile *file;
+
+ ThunarThumbnailer *thumbnailer;
+ guint thumbnail_request;
+
+ GtkWidget *notebook;
+ GtkWidget *icon_button;
+ GtkWidget *icon_image;
+ GtkWidget *name_entry;
+ GtkWidget *kind_ebox;
+ GtkWidget *kind_label;
+ GtkWidget *openwith_chooser;
+ GtkWidget *link_label;
+ GtkWidget *origin_label;
+ GtkWidget *deleted_label;
+ GtkWidget *modified_label;
+ GtkWidget *accessed_label;
+ GtkWidget *freespace_label;
+ GtkWidget *volume_image;
+ GtkWidget *volume_label;
+ GtkWidget *permissions_chooser;
};
@@ -526,7 +526,7 @@ thunar_properties_dialog_finalize (GObject *object)
/* cancel any pending thumbnailer requests */
if (dialog->thumbnail_request > 0)
{
- thunar_thumbnailer_unqueue (dialog->thumbnailer, dialog->thumbnail_request);
+ thunar_thumbnailer_dequeue (dialog->thumbnailer, dialog->thumbnail_request);
dialog->thumbnail_request = 0;
}
@@ -835,7 +835,7 @@ thunar_properties_dialog_update (ThunarPropertiesDialog *dialog)
/* cancel any pending thumbnail requests */
if (dialog->thumbnail_request > 0)
{
- thunar_thumbnailer_unqueue (dialog->thumbnailer, dialog->thumbnail_request);
+ thunar_thumbnailer_dequeue (dialog->thumbnailer, dialog->thumbnail_request);
dialog->thumbnail_request = 0;
}
diff --git a/thunar/thunar-standard-view.c b/thunar/thunar-standard-view.c
index f671f05..6686052 100644
--- a/thunar/thunar-standard-view.c
+++ b/thunar/thunar-standard-view.c
@@ -1,21 +1,22 @@
-/* $Id$ */
+/* vi:set et ai sw=2 sts=2 ts=2: */
/*-
* Copyright (c) 2005-2006 Benedikt Meurer <benny at xfce.org>
- * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
+ * Copyright (c) 2009-2011 Jannis Pohlmann <jannis at 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 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.
+ * 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
+ * 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
@@ -49,6 +50,7 @@
#include <thunar/thunar-standard-view-ui.h>
#include <thunar/thunar-templates-action.h>
#include <thunar/thunar-text-renderer.h>
+#include <thunar/thunar-thumbnailer.h>
#if defined(GDK_WINDOWING_X11)
#include <gdk/gdkx.h>
@@ -260,6 +262,14 @@ static gboolean thunar_standard_view_drag_scroll_timer (gpo
static void thunar_standard_view_drag_scroll_timer_destroy (gpointer user_data);
static gboolean thunar_standard_view_drag_timer (gpointer user_data);
static void thunar_standard_view_drag_timer_destroy (gpointer user_data);
+static void thunar_standard_view_cancel_thumbnailing (ThunarStandardView *standard_view);
+static void thunar_standard_view_schedule_thumbnail_timeout (ThunarStandardView *standard_view);
+static void thunar_standard_view_schedule_thumbnail_idle (ThunarStandardView *standard_view);
+static gboolean thunar_standard_view_request_thumbnails (ThunarStandardView *standard_view);
+static void thunar_standard_view_scrolled (GtkAdjustment *adjustment,
+ ThunarStandardView *standard_view);
+static void thunar_standard_view_size_allocate (ThunarStandardView *standard_view,
+ GtkAllocation *allocation);
@@ -326,6 +336,12 @@ struct _ThunarStandardViewPrivate
/* selected_files support */
GList *selected_files;
+ /* support for generating thumbnails */
+ ThunarThumbnailer *thumbnailer;
+ guint thumbnail_request;
+ guint thumbnail_source_id;
+ gboolean thumbnailing_scheduled;
+
/* Tree path for restoring the selection after selecting and
* deleting an item */
GtkTreePath *selection_before_delete;
@@ -531,6 +547,10 @@ thunar_standard_view_init (ThunarStandardView *standard_view)
/* grab a reference on the provider factory */
standard_view->priv->provider_factory = thunarx_provider_factory_get_default ();
+ /* create a thumbnailer */
+ standard_view->priv->thumbnailer = thunar_thumbnailer_new ();
+ standard_view->priv->thumbnailing_scheduled = FALSE;
+
/* initialize the scrolled window */
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (standard_view),
GTK_POLICY_AUTOMATIC,
@@ -596,6 +616,10 @@ thunar_standard_view_init (ThunarStandardView *standard_view)
* files in our model changes.
*/
g_signal_connect_swapped (G_OBJECT (standard_view->model), "notify::num-files", G_CALLBACK (thunar_standard_view_update_statusbar_text), standard_view);
+
+ /* connect to size allocation signals for generating thumbnail requests */
+ g_signal_connect_after (G_OBJECT (standard_view), "size-allocate",
+ G_CALLBACK (thunar_standard_view_size_allocate), NULL);
}
@@ -607,6 +631,7 @@ thunar_standard_view_constructor (GType type,
{
ThunarStandardView *standard_view;
ThunarZoomLevel zoom_level;
+ GtkAdjustment *adjustment;
ThunarColumn sort_column;
GtkSortType sort_order;
GtkWidget *view;
@@ -667,6 +692,14 @@ thunar_standard_view_constructor (GType type,
g_signal_connect (G_OBJECT (view), "drag-data-delete", G_CALLBACK (thunar_standard_view_drag_data_delete), object);
g_signal_connect (G_OBJECT (view), "drag-end", G_CALLBACK (thunar_standard_view_drag_end), object);
+ /* connect to scroll events for generating thumbnail requests */
+ adjustment = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (standard_view));
+ g_signal_connect (adjustment, "value-changed",
+ G_CALLBACK (thunar_standard_view_scrolled), object);
+ adjustment = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (standard_view));
+ g_signal_connect (adjustment, "value-changed",
+ G_CALLBACK (thunar_standard_view_scrolled), object);
+
/* done, we have a working object */
return object;
}
@@ -678,6 +711,9 @@ thunar_standard_view_dispose (GObject *object)
{
ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (object);
+ /* cancel pending thumbnail sources and requests */
+ thunar_standard_view_cancel_thumbnailing (standard_view);
+
/* unregister the "loading" binding */
if (G_UNLIKELY (standard_view->loading_binding != NULL))
exo_binding_unbind (standard_view->loading_binding);
@@ -709,6 +745,9 @@ thunar_standard_view_finalize (GObject *object)
_thunar_assert (standard_view->ui_manager == NULL);
_thunar_assert (standard_view->clipboard == NULL);
+ /* release the thumbnailer */
+ g_object_unref (standard_view->priv->thumbnailer);
+
/* release the scroll_to_file reference (if any) */
if (G_UNLIKELY (standard_view->priv->scroll_to_file != NULL))
g_object_unref (G_OBJECT (standard_view->priv->scroll_to_file));
@@ -1128,6 +1167,9 @@ thunar_standard_view_set_current_directory (ThunarNavigator *navigator,
_thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view));
_thunar_return_if_fail (current_directory == NULL || THUNAR_IS_FILE (current_directory));
+ /* cancel any pending thumbnail sources and requests */
+ thunar_standard_view_cancel_thumbnailing (standard_view);
+
/* disconnect any previous "loading" binding */
if (G_LIKELY (standard_view->loading_binding != NULL))
exo_binding_unbind (standard_view->loading_binding);
@@ -1189,6 +1231,9 @@ thunar_standard_view_set_current_directory (ThunarNavigator *navigator,
/* update the "Restore" action */
gtk_action_set_visible (standard_view->priv->action_restore, trashed);
+ /* schedule a thumbnail timeout */
+ thunar_standard_view_schedule_thumbnail_timeout (standard_view);
+
/* notify all listeners about the new/old current directory */
g_object_notify (G_OBJECT (standard_view), "current-directory");
}
@@ -1266,6 +1311,17 @@ thunar_standard_view_set_loading (ThunarStandardView *standard_view,
thunar_file_list_free (selected_files);
}
+ /* check if we're done loading and a thumbnail timeout or idle was requested */
+ if (!loading && standard_view->priv->thumbnailing_scheduled)
+ {
+ /* we've just finished loading. it will probably the user some time to
+ * understand the contents of the folder before he will start interacting
+ * with the view. so here we can safely schedule an idle function instead
+ * of a timeout */
+ thunar_standard_view_schedule_thumbnail_idle (standard_view);
+ standard_view->priv->thumbnailing_scheduled = FALSE;
+ }
+
/* notify listeners */
g_object_freeze_notify (G_OBJECT (standard_view));
g_object_notify (G_OBJECT (standard_view), "loading");
@@ -3240,6 +3296,182 @@ thunar_standard_view_drag_timer_destroy (gpointer user_data)
+static void
+thunar_standard_view_cancel_thumbnailing (ThunarStandardView *standard_view)
+{
+ _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view));
+
+ /* check if we have a pending thumbnail timeout/idle handler */
+ if (standard_view->priv->thumbnail_source_id > 0)
+ {
+ /* cancel this handler */
+ g_source_remove (standard_view->priv->thumbnail_source_id);
+ standard_view->priv->thumbnail_source_id = 0;
+ }
+
+ /* check if we have a pending thumbnail request */
+ if (standard_view->priv->thumbnail_request > 0)
+ {
+ /* cancel the request */
+ thunar_thumbnailer_dequeue (standard_view->priv->thumbnailer,
+ standard_view->priv->thumbnail_request);
+ standard_view->priv->thumbnail_request = 0;
+ }
+}
+
+
+
+static void
+thunar_standard_view_schedule_thumbnail_timeout (ThunarStandardView *standard_view)
+{
+ _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view));
+
+ /* delay creating the idle until the view has finished loading.
+ * this is done because we only can tell the visible range reliably after
+ * all items have been added and we've perhaps scrolled to the file remember
+ * the last time */
+ if (thunar_view_get_loading (THUNAR_VIEW (standard_view)))
+ {
+ standard_view->priv->thumbnailing_scheduled = TRUE;
+ return;
+ }
+
+ /* cancel any pending thumbnail sources and requests */
+ thunar_standard_view_cancel_thumbnailing (standard_view);
+
+ /* schedule the timeout handler */
+ standard_view->priv->thumbnail_source_id =
+ g_timeout_add (250, (GSourceFunc) thunar_standard_view_request_thumbnails,
+ standard_view);
+}
+
+
+
+static void
+thunar_standard_view_schedule_thumbnail_idle (ThunarStandardView *standard_view)
+{
+ _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view));
+
+ /* delay creating the idle until the view has finished loading.
+ * this is done because we only can tell the visible range reliably after
+ * all items have been added, layouting has finished and we've perhaps
+ * scrolled to the file remembered the last time */
+ if (thunar_view_get_loading (THUNAR_VIEW (standard_view)))
+ {
+ standard_view->priv->thumbnailing_scheduled = TRUE;
+ return;
+ }
+
+ /* cancel any pending thumbnail sources or requests */
+ thunar_standard_view_cancel_thumbnailing (standard_view);
+
+ /* schedule the timeout or idle handler */
+ standard_view->priv->thumbnail_source_id =
+ g_idle_add ((GSourceFunc) thunar_standard_view_request_thumbnails, standard_view);
+}
+
+
+
+static gboolean
+thunar_standard_view_request_thumbnails (ThunarStandardView *standard_view)
+{
+ GtkTreePath *start_path;
+ GtkTreePath *end_path;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ ThunarFile *file;
+ gboolean valid_iter;
+ GList *visible_files = NULL;
+
+ _thunar_return_val_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view), FALSE);
+
+ /* reschedule the source if we're still loading the folder */
+ if (thunar_view_get_loading (THUNAR_VIEW (standard_view)))
+ {
+ g_debug ("weird, this should never happen");
+ return TRUE;
+ }
+
+ /* compute visible item range */
+ if ((*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->get_visible_range) (standard_view,
+ &start_path,
+ &end_path))
+ {
+ /* iterate over the range to collect all files */
+ valid_iter = gtk_tree_model_get_iter (GTK_TREE_MODEL (standard_view->model),
+ &iter, start_path);
+
+ while (valid_iter)
+ {
+ /* prepend the file to the visible items list */
+ file = thunar_list_model_get_file (standard_view->model, &iter);
+ visible_files = g_list_prepend (visible_files, file);
+
+ /* check if we've reached the end of the visible range */
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (standard_view->model), &iter);
+ if (gtk_tree_path_compare (path, end_path) != 0)
+ {
+ /* try to compute the next visible item */
+ valid_iter =
+ gtk_tree_model_iter_next (GTK_TREE_MODEL (standard_view->model), &iter);
+ }
+ else
+ {
+ /* we have reached the end, terminate the loop */
+ valid_iter = FALSE;
+ }
+
+ /* release the tree path */
+ gtk_tree_path_free (path);
+ }
+
+ /* queue a thumbnail request */
+ thunar_thumbnailer_queue_files (standard_view->priv->thumbnailer, visible_files,
+ &standard_view->priv->thumbnail_request);
+
+ /* release the file list */
+ g_list_foreach (visible_files, (GFunc) g_object_unref, NULL);
+ g_list_free (visible_files);
+
+ /* release the start and end path */
+ gtk_tree_path_free (start_path);
+ gtk_tree_path_free (end_path);
+ }
+
+ return FALSE;
+}
+
+
+
+static void
+thunar_standard_view_scrolled (GtkAdjustment *adjustment,
+ ThunarStandardView *standard_view)
+{
+ _thunar_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
+ _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view));
+
+ /* ignore adjustment changes when the view is still loading */
+ if (thunar_view_get_loading (THUNAR_VIEW (standard_view)))
+ return;
+
+ /* reschedule a thumbnail request timeout */
+ thunar_standard_view_schedule_thumbnail_timeout (standard_view);
+}
+
+
+
+static void
+thunar_standard_view_size_allocate (ThunarStandardView *standard_view,
+ GtkAllocation *allocation)
+{
+ _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view));
+
+ /* reschedule a thumbnail request timeout */
+ thunar_standard_view_schedule_thumbnail_timeout (standard_view);
+}
+
+
+
/**
* thunar_standard_view_context_menu:
* @standard_view : a #ThunarStandardView instance.
diff --git a/thunar/thunar-thumbnailer-dbus.xml b/thunar/thunar-thumbnailer-dbus.xml
index e6b39f7..d0d2ada 100644
--- a/thunar/thunar-thumbnailer-dbus.xml
+++ b/thunar/thunar-thumbnailer-dbus.xml
@@ -11,7 +11,7 @@
<arg type="u" name="handle" direction="out" />
</method>
- <method name="Unqueue">
+ <method name="Dequeue">
<annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
<arg type="u" name="handle" direction="in" />
</method>
diff --git a/thunar/thunar-thumbnailer.c b/thunar/thunar-thumbnailer.c
index 337bb8a..296f256 100644
--- a/thunar/thunar-thumbnailer.c
+++ b/thunar/thunar-thumbnailer.c
@@ -49,36 +49,19 @@
*
* When a request call is sent out, an internal request ID is created and
* associated with the corresponding DBusGProxyCall via the request_call_mapping hash
- * table. It also remembers the URIs for the internal request ID in the
- * request_uris_mapping hash table.
+ * table.
*
* The D-Bus reply handler then checks if there was an delivery error or
* not. If the request method was sent successfully, the handle returned by the
* D-Bus thumbnailer is associated bidirectionally with the internal request ID via
- * the request_handle_mapping and handle_request_mappings. If the request could
- * not be sent at all, the URIs array is dropped from request_uris_mapping. In
- * both cases, the association of the internal request ID with the DBusGProxyCall
- * is removed from request_call_mapping.
+ * the request_handle_mapping and handle_request_mappings. In both cases, the
+ * association of the internal request ID with the DBusGProxyCall is removed from
+ * request_call_mapping.
*
- * These hash tables play a major role in the Started, Finished, Error and Ready
+ * These hash tables play a major role in the Finished, Error and Ready
* signal handlers.
*
*
- * Started
- * =======
- *
- * When a Started signal is emitted by the D-Bus thumbnailer, ThunarThumbnailer
- * receives the handle and looks up the corresponding internal request ID. If
- * it exists (which it should), it schedules an idle function to handle the
- * signal in the application's main loop.
- *
- * The idle function then looks up the URIs array for the request ID from the
- * request_uris_mapping. For each of these URIs the corresponding ThunarFile
- * is looked up from the file cache (which represents files currently being
- * used somewhere in the UI), and if the ThunarFile exists in the cache it's
- * thumb state is set to _LOADING (unless it's already marked as _READY).
- *
- *
* Ready / Error
* =============
*
@@ -92,7 +75,7 @@
*
* The Finished signal handler looks up the internal request ID based on
* the D-Bus thumbnailer handle. It then drops all corresponding information
- * from handle_request_mapping, request_handle_mapping and request_uris_mapping.
+ * from handle_request_mapping and request_handle_mapping.
*/
@@ -133,15 +116,11 @@ static void thunar_thumbnailer_thumbnailer_ready (DBusGPr
guint32 handle,
const gchar **uris,
ThunarThumbnailer *thumbnailer);
-static void thunar_thumbnailer_thumbnailer_started (DBusGProxy *proxy,
- guint handle,
- ThunarThumbnailer *thumbnailer);
static guint thunar_thumbnailer_queue_async (ThunarThumbnailer *thumbnailer,
gchar **uris,
const gchar **mime_hints);
static gboolean thunar_thumbnailer_error_idle (gpointer user_data);
static gboolean thunar_thumbnailer_ready_idle (gpointer user_data);
-static gboolean thunar_thumbnailer_started_idle (gpointer user_data);
static void thunar_thumbnailer_call_free (ThunarThumbnailerCall *call);
static void thunar_thumbnailer_idle_free (gpointer data);
#endif
@@ -170,9 +149,6 @@ struct _ThunarThumbnailer
/* hash table to map ThunarThumbnailer requests to DBusGProxyCalls */
GHashTable *request_call_mapping;
- /* hash table to map ThunarThumbnailer requests to URI arrays */
- GHashTable *request_uris_mapping;
-
GMutex *lock;
/* cached arrays of URI schemes and MIME types for which thumbnails
@@ -181,7 +157,7 @@ struct _ThunarThumbnailer
gchar **supported_types;
/* last ThunarThumbnailer request ID */
- ThunarThumbnailerRequest last_request;
+ guint last_request;
/* IDs of idle functions */
GList *idles;
@@ -263,9 +239,6 @@ thunar_thumbnailer_init (ThunarThumbnailer *thumbnailer)
g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
thumbnailer->request_call_mapping =
g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
- thumbnailer->request_uris_mapping =
- g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
- (GDestroyNotify) g_strfreev);
}
/* release the D-Bus connection if we have one */
@@ -309,16 +282,15 @@ thunar_thumbnailer_finalize (GObject *object)
g_hash_table_unref (thumbnailer->request_call_mapping);
#if 0
- /* unqueue all pending requests */
+ /* dequeue all pending requests */
list = g_hash_table_get_keys (thumbnailer->handle_request_mapping);
for (lp = list; lp != NULL; lp = lp->next)
- thunar_thumbnailer_unqueue_internal (thumbnailer, GPOINTER_TO_UINT (lp->data));
+ thunar_thumbnailer_dequeue_internal (thumbnailer, GPOINTER_TO_UINT (lp->data));
g_list_free (list);
#endif
g_hash_table_unref (thumbnailer->handle_request_mapping);
g_hash_table_unref (thumbnailer->request_handle_mapping);
- g_hash_table_unref (thumbnailer->request_uris_mapping);
/* disconnect from the thumbnailer proxy */
g_signal_handlers_disconnect_matched (thumbnailer->thumbnailer_proxy,
@@ -398,9 +370,6 @@ thunar_thumbnailer_init_thumbnailer_proxy (ThunarThumbnailer *thumbnailer,
dbus_g_proxy_connect_signal (thumbnailer->thumbnailer_proxy, "Ready",
G_CALLBACK (thunar_thumbnailer_thumbnailer_ready),
thumbnailer, NULL);
- dbus_g_proxy_connect_signal (thumbnailer->thumbnailer_proxy, "Started",
- G_CALLBACK (thunar_thumbnailer_thumbnailer_started),
- thumbnailer, NULL);
}
@@ -528,7 +497,6 @@ thunar_thumbnailer_thumbnailer_finished (DBusGProxy *proxy,
/* the request is finished, drop all the information about it */
g_hash_table_remove (thumbnailer->handle_request_mapping, request);
g_hash_table_remove (thumbnailer->request_handle_mapping, request);
- g_hash_table_remove (thumbnailer->request_uris_mapping, request);
}
}
@@ -569,44 +537,6 @@ thunar_thumbnailer_thumbnailer_ready (DBusGProxy *proxy,
static void
-thunar_thumbnailer_thumbnailer_started (DBusGProxy *proxy,
- guint handle,
- ThunarThumbnailer *thumbnailer)
-{
- ThunarThumbnailerIdle *idle;
- gpointer request;
-
- _thunar_return_if_fail (DBUS_IS_G_PROXY (proxy));
- _thunar_return_if_fail (THUNAR_IS_THUMBNAILER (thumbnailer));
-
- /* look up the request for this D-Bus service handle */
- request = g_hash_table_lookup (thumbnailer->handle_request_mapping,
- GUINT_TO_POINTER (handle));
-
- /* check if we have a request for this handle */
- if (request != NULL)
- {
- /* allocate a new idle struct */
- idle = g_slice_new0 (ThunarThumbnailerIdle);
- idle->type = THUNAR_THUMBNAILER_IDLE_STARTED;
- idle->thumbnailer = g_object_ref (thumbnailer);
-
- /* remember the request because we need it in the idle function */
- idle->data.request = request;
-
- /* remember the idle struct because we might have to remove it in finalize() */
- thumbnailer->idles = g_list_prepend (thumbnailer->idles, idle);
-
- /* call the started idle function when we have the time */
- idle->id = g_idle_add_full (G_PRIORITY_LOW,
- thunar_thumbnailer_started_idle, idle,
- thunar_thumbnailer_idle_free);
- }
-}
-
-
-
-static void
thunar_thumbnailer_queue_async_reply (DBusGProxy *proxy,
guint handle,
GError *error,
@@ -614,9 +544,6 @@ thunar_thumbnailer_queue_async_reply (DBusGProxy *proxy,
{
ThunarThumbnailerCall *call = user_data;
ThunarThumbnailer *thumbnailer = THUNAR_THUMBNAILER (call->thumbnailer);
-#ifndef NDEBUG
- gchar **uris;
-#endif
_thunar_return_if_fail (DBUS_IS_G_PROXY (proxy));
_thunar_return_if_fail (call != NULL);
@@ -624,20 +551,7 @@ thunar_thumbnailer_queue_async_reply (DBusGProxy *proxy,
g_mutex_lock (thumbnailer->lock);
- if (error != NULL)
- {
-#ifndef NDEBUG
- /* get the URIs array for this request */
- uris = g_hash_table_lookup (thumbnailer->request_uris_mapping, call->request);
-
- /* the array should always exist, otherwise there's a bug in the program */
- _thunar_assert (uris != NULL);
-#endif
-
- /* the request is "finished", forget about its URIs */
- g_hash_table_remove (thumbnailer->request_uris_mapping, call->request);
- }
- else
+ if (error == NULL)
{
/* remember that this request and D-Bus handle belong together */
g_hash_table_insert (thumbnailer->request_handle_mapping,
@@ -686,9 +600,6 @@ thunar_thumbnailer_queue_async (ThunarThumbnailer *thumbnailer,
thumbnailer_call->request = request;
thumbnailer_call->thumbnailer = g_object_ref (thumbnailer);
- /* remember the URIs for this request */
- g_hash_table_insert (thumbnailer->request_uris_mapping, request, uris);
-
/* queue thumbnails for the given URIs asynchronously */
call = thunar_thumbnailer_proxy_queue_async (thumbnailer->thumbnailer_proxy,
(const gchar **)uris, mime_hints,
@@ -783,54 +694,6 @@ thunar_thumbnailer_ready_idle (gpointer user_data)
-static gboolean
-thunar_thumbnailer_started_idle (gpointer user_data)
-{
- ThunarThumbnailerIdle *idle = user_data;
- const gchar **uris;
- ThunarFile *file;
- GFile *gfile;
- guint n;
-
- _thunar_return_val_if_fail (idle != NULL, FALSE);
- _thunar_return_val_if_fail (idle->type == THUNAR_THUMBNAILER_IDLE_STARTED, FALSE);
-
- g_mutex_lock (idle->thumbnailer->lock);
-
- /* look up the URIs that belong to this request */
- uris = g_hash_table_lookup (idle->thumbnailer->request_uris_mapping,
- idle->data.request);
-
- /* iterate over all URIs if there are any */
- for (n = 0; uris != NULL && uris[n] != NULL; ++n)
- {
- /* look up the corresponding ThunarFile from the cache */
- gfile = g_file_new_for_uri (uris[n]);
- file = thunar_file_cache_lookup (gfile);
- g_object_unref (gfile);
-
- /* check if we have a file in the cache */
- if (file != NULL)
- {
- /* set the thumbnail state to loading unless we already have a thumbnail.
- * This is to prevent race conditions with the other idle functions */
- if (thunar_file_get_thumb_state (file) != THUNAR_FILE_THUMB_STATE_READY)
- thunar_file_set_thumb_state (file, THUNAR_FILE_THUMB_STATE_LOADING);
- }
- }
-
-
- /* remove the idle struct */
- idle->thumbnailer->idles = g_list_remove (idle->thumbnailer->idles, idle);
-
- g_mutex_unlock (idle->thumbnailer->lock);
-
- /* remove the idle source, which also destroys the idle struct */
- return FALSE;
-}
-
-
-
static void
thunar_thumbnailer_call_free (ThunarThumbnailerCall *call)
{
@@ -889,9 +752,9 @@ thunar_thumbnailer_new (void)
gboolean
-thunar_thumbnailer_queue_file (ThunarThumbnailer *thumbnailer,
- ThunarFile *file,
- ThunarThumbnailerRequest *request)
+thunar_thumbnailer_queue_file (ThunarThumbnailer *thumbnailer,
+ ThunarFile *file,
+ guint *request)
{
GList files;
@@ -910,9 +773,9 @@ thunar_thumbnailer_queue_file (ThunarThumbnailer *thumbnailer,
gboolean
-thunar_thumbnailer_queue_files (ThunarThumbnailer *thumbnailer,
- GList *files,
- ThunarThumbnailerRequest *request)
+thunar_thumbnailer_queue_files (ThunarThumbnailer *thumbnailer,
+ GList *files,
+ guint *request)
{
const gchar **mime_hints;
gboolean success = FALSE;
@@ -963,6 +826,9 @@ thunar_thumbnailer_queue_files (ThunarThumbnailer *thumbnailer,
/* fill URI and MIME hint arrays with items from the wait queue */
for (lp = g_list_last (supported_files), n = 0; lp != NULL; lp = lp->prev, ++n)
{
+ /* set the thumbnail state to loading */
+ thunar_file_set_thumb_state (lp->data, THUNAR_FILE_THUMB_STATE_LOADING);
+
/* save URI and MIME hint in the arrays */
uris[n] = thunar_file_dup_uri (lp->data);
mime_hints[n] = thunar_file_get_content_type (lp->data);
@@ -976,15 +842,9 @@ thunar_thumbnailer_queue_files (ThunarThumbnailer *thumbnailer,
/* queue a thumbnail request for the URIs from the wait queue */
if (request != NULL)
- {
- *request = thunar_thumbnailer_queue_async (thumbnailer, uris,
- (const gchar **)mime_hints);
- }
+ *request = thunar_thumbnailer_queue_async (thumbnailer, uris, mime_hints);
else
- {
- thunar_thumbnailer_queue_async (thumbnailer, uris,
- (const gchar **)mime_hints);
- }
+ thunar_thumbnailer_queue_async (thumbnailer, uris, mime_hints);
g_mutex_unlock (thumbnailer->lock);
@@ -1004,8 +864,8 @@ thunar_thumbnailer_queue_files (ThunarThumbnailer *thumbnailer,
void
-thunar_thumbnailer_unqueue (ThunarThumbnailer *thumbnailer,
- ThunarThumbnailerRequest request)
+thunar_thumbnailer_dequeue (ThunarThumbnailer *thumbnailer,
+ guint request)
{
#ifdef HAVE_DBUS
gpointer request_ptr;
@@ -1028,14 +888,13 @@ thunar_thumbnailer_unqueue (ThunarThumbnailer *thumbnailer,
handle = g_hash_table_lookup (thumbnailer->request_handle_mapping, request_ptr);
if (GPOINTER_TO_UINT (handle) > 0)
{
- /* unqueue the request */
- thunar_thumbnailer_proxy_unqueue (thumbnailer->thumbnailer_proxy,
+ /* Dequeue the request */
+ thunar_thumbnailer_proxy_dequeue (thumbnailer->thumbnailer_proxy,
GPOINTER_TO_UINT (handle), NULL);
/* drop all the request information */
g_hash_table_remove (thumbnailer->handle_request_mapping, handle);
g_hash_table_remove (thumbnailer->request_handle_mapping, request_ptr);
- g_hash_table_remove (thumbnailer->request_uris_mapping, request_ptr);
}
}
diff --git a/thunar/thunar-thumbnailer.h b/thunar/thunar-thumbnailer.h
index c9744b9..81caf83 100644
--- a/thunar/thunar-thumbnailer.h
+++ b/thunar/thunar-thumbnailer.h
@@ -23,9 +23,7 @@
#include <thunar/thunar-file.h>
-G_BEGIN_DECLS;
-
-typedef guint ThunarThumbnailerRequest;
+G_BEGIN_DECLS
typedef struct _ThunarThumbnailerClass ThunarThumbnailerClass;
typedef struct _ThunarThumbnailer ThunarThumbnailer;
@@ -43,13 +41,13 @@ ThunarThumbnailer *thunar_thumbnailer_new (void) G_GNUC_MALLOC;
gboolean thunar_thumbnailer_queue_file (ThunarThumbnailer *thumbnailer,
ThunarFile *file,
- ThunarThumbnailerRequest *request);
+ guint *request);
gboolean thunar_thumbnailer_queue_files (ThunarThumbnailer *thumbnailer,
GList *files,
- ThunarThumbnailerRequest *request);
-void thunar_thumbnailer_unqueue (ThunarThumbnailer *thumbnailer,
- ThunarThumbnailerRequest request);
+ guint *request);
+void thunar_thumbnailer_dequeue (ThunarThumbnailer *thumbnailer,
+ guint request);
-G_END_DECLS;
+G_END_DECLS
#endif /* !__THUNAR_THUMBNAILER_H__ */
More information about the Xfce4-commits
mailing list