[Xfce4-commits] <thunar:master> Refactor ThunarThumbnailer and implement unqueue.

Jannis Pohlmann noreply at xfce.org
Mon Feb 14 14:10:01 CET 2011


Updating branch refs/heads/master
         to f19df728cf8798152b175dd61467ea1633663660 (commit)
       from cc468f4b3f33c298c33942ee0ce64000a920c8ed (commit)

commit f19df728cf8798152b175dd61467ea1633663660
Author: Jannis Pohlmann <jannis at xfce.org>
Date:   Mon Feb 7 02:41:23 2011 +0100

    Refactor ThunarThumbnailer and implement unqueue.
    
    This commit also drops ThunarThumbnailer in ThunarIconFactory and adds
    it to ThunarPropertiesDialog. There will be one ThunarThumbnailer for
    each ThunarStandardView soon in order to bring back normal thumbnail
    generation.

 thunar/thunar-icon-factory.c      |   55 ++----
 thunar/thunar-properties-dialog.c |  109 ++++++---
 thunar/thunar-thumbnailer.c       |  457 +++++++++----------------------------
 thunar/thunar-thumbnailer.h       |   45 ++--
 4 files changed, 223 insertions(+), 443 deletions(-)

diff --git a/thunar/thunar-icon-factory.c b/thunar/thunar-icon-factory.c
index 576329a..4f2ec42 100644
--- a/thunar/thunar-icon-factory.c
+++ b/thunar/thunar-icon-factory.c
@@ -1,25 +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-2010 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
- *
- * The basic idea for the icon factory implementation was borrowed from
- * Nautilus initially, but the implementation is very different from
- * what Nautilus does.
+ * 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
@@ -38,7 +35,6 @@
 #include <thunar/thunar-preferences.h>
 #include <thunar/thunar-private.h>
 #include <thunar/thunar-thumbnail-frame.h>
-#include <thunar/thunar-thumbnailer.h>
 
 
 
@@ -106,8 +102,6 @@ struct _ThunarIconFactory
 {
   GObject __parent__;
 
-  ThunarThumbnailer *thumbnailer;
-
   ThunarPreferences *preferences;
 
   GdkPixbuf         *recently[MAX_RECENTLY];  /* ring buffer */
@@ -209,9 +203,6 @@ thunar_icon_factory_init (ThunarIconFactory *factory)
 
   /* allocate the hash table for the icon cache */
   factory->icon_cache = g_hash_table_new_full (thunar_icon_key_hash, thunar_icon_key_equal, g_free, g_object_unref);
-
-  /* create a new thumbnailer */
-  factory->thumbnailer = thunar_thumbnailer_new ();
 }
 
 
@@ -250,9 +241,6 @@ thunar_icon_factory_finalize (GObject *object)
   /* clear the icon cache hash table */
   g_hash_table_destroy (factory->icon_cache);
 
-  /* release the thumbnailer */
-  g_object_unref (G_OBJECT (factory->thumbnailer));
-
   /* remove the "changed" emission hook from the GtkIconTheme class */
   g_signal_remove_emission_hook (g_signal_lookup ("changed", GTK_TYPE_ICON_THEME), factory->changed_hook_id);
 
@@ -804,7 +792,6 @@ thunar_icon_factory_load_file_icon (ThunarIconFactory  *factory,
                                     ThunarFileIconState icon_state,
                                     gint                icon_size)
 {
-  ThunarFileThumbState thumb_state;
   GInputStream        *stream;
   GtkIconInfo         *icon_info;
   const gchar         *thumbnail_path;
@@ -830,20 +817,6 @@ thunar_icon_factory_load_file_icon (ThunarIconFactory  *factory,
   /* check if thumbnails are enabled and we can display a thumbnail for the item */
   if (G_LIKELY (factory->show_thumbnails && thunar_file_is_regular (file)))
     {
-      /* this is how thumbnails for files are loaded: first, we check the thumbnail
-       * state. If that is unknown, we request a thumbnail to be generated in the
-       * background. At the same time we already try to load the thumbnail, in case
-       * it's already there. when the thumbnail is ready, we just load it */
-
-      /* determine the thumbnail state of the file */
-      thumb_state = thunar_file_get_thumb_state (file);
-
-      if (thumb_state == THUNAR_FILE_THUMB_STATE_UNKNOWN)
-        {
-          /* we don't know the state yet so request a new thumbnail in the background */
-          thunar_thumbnailer_queue_file (factory->thumbnailer, file);
-        }
-
       /* determine the preview icon first */
       gicon = thunar_file_get_preview_icon (file);
 
diff --git a/thunar/thunar-properties-dialog.c b/thunar/thunar-properties-dialog.c
index 9e5a39d..2633950 100644
--- a/thunar/thunar-properties-dialog.c
+++ b/thunar/thunar-properties-dialog.c
@@ -1,21 +1,22 @@
-/* $Id$ */
+/* vi:set et ai sw=2 sts=2 ts=2: */
 /*-
  * Copyright (c) 2005-2007 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
@@ -52,6 +53,7 @@
 #include <thunar/thunar-private.h>
 #include <thunar/thunar-properties-dialog.h>
 #include <thunar/thunar-size-label.h>
+#include <thunar/thunar-thumbnailer.h>
 
 
 
@@ -106,31 +108,34 @@ struct _ThunarPropertiesDialogClass
 
 struct _ThunarPropertiesDialog
 {
-  ThunarAbstractDialog    __parent__;
-
-  ThunarxProviderFactory *provider_factory;
-  GList                  *provider_pages;
-
-  ThunarPreferences      *preferences;
-
-  ThunarFile             *file;
-
-  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;
+  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;
 };
 
 
@@ -209,6 +214,10 @@ thunar_properties_dialog_init (ThunarPropertiesDialog *dialog)
   g_signal_connect_swapped (G_OBJECT (dialog->preferences), "notify::misc-date-style",
                             G_CALLBACK (thunar_properties_dialog_reload), dialog);
 
+  /* create a new thumbnailer */
+  dialog->thumbnailer = thunar_thumbnailer_new ();
+  dialog->thumbnail_request = 0;
+
   dialog->provider_factory = thunarx_provider_factory_get_default ();
 
   gtk_dialog_add_buttons (GTK_DIALOG (dialog),
@@ -514,6 +523,16 @@ thunar_properties_dialog_finalize (GObject *object)
   g_signal_handlers_disconnect_by_func (dialog->preferences, thunar_properties_dialog_reload, dialog);
   g_object_unref (dialog->preferences);
 
+  /* cancel any pending thumbnailer requests */
+  if (dialog->thumbnail_request > 0)
+    {
+      thunar_thumbnailer_unqueue (dialog->thumbnailer, dialog->thumbnail_request);
+      dialog->thumbnail_request = 0;
+    }
+
+  /* release the thumbnailer */
+  g_object_unref (dialog->thumbnailer);
+
   /* release the provider property pages */
   g_list_foreach (dialog->provider_pages, (GFunc) g_object_unref, NULL);
   g_list_free (dialog->provider_pages);
@@ -813,6 +832,20 @@ thunar_properties_dialog_update (ThunarPropertiesDialog *dialog)
   _thunar_return_if_fail (THUNAR_IS_PROPERTIES_DIALOG (dialog));
   _thunar_return_if_fail (THUNAR_IS_FILE (dialog->file));
 
+  /* cancel any pending thumbnail requests */
+  if (dialog->thumbnail_request > 0)
+    {
+      thunar_thumbnailer_unqueue (dialog->thumbnailer, dialog->thumbnail_request);
+      dialog->thumbnail_request = 0;
+    }
+
+  if (dialog->file != NULL)
+    {
+      /* queue a new thumbnail request */
+      thunar_thumbnailer_queue_file (dialog->thumbnailer, dialog->file, 
+                                     &dialog->thumbnail_request);
+    }
+
   icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (dialog)));
   icon_factory = thunar_icon_factory_get_for_icon_theme (icon_theme);
 
diff --git a/thunar/thunar-thumbnailer.c b/thunar/thunar-thumbnailer.c
index 8146d29..337bb8a 100644
--- a/thunar/thunar-thumbnailer.c
+++ b/thunar/thunar-thumbnailer.c
@@ -1,6 +1,6 @@
 /* vi:set et ai sw=2 sts=2 ts=2: */
 /*-
- * 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
@@ -47,27 +47,7 @@
  * Please note that all D-Bus calls are performed asynchronously. 
  *
  *
- * Queue
- * =====
- *
- * ThunarThumbnailer maintains a wait queue to group individual thumbnail requests.
- * The wait queue is processed at most every 100ms. This is done to reduce the
- * overall D-Bus noise when dealing with a lot of requests. The more thumbnails are 
- * requested in a 100ms time slot, the less D-Bus methods are sent.
- *
- * Let N be the number of requests made for individual files in a 100ms slot. 
- * Compared to sending out one requests per file (which generates 4*N D-Bus messages,
- * 1 Queue, 1 Started, 1 Ready/Error and 1 Finished for each of the N files), the wait 
- * queue technique only causes 3+N D-Bus messages to be sent (1 Queue, 1 Started, 
- * N Ready/Error and 1 Finished). This can be further improved on the service side
- * if the D-Bus thumbnailer groups Ready/Error messages (which of course has drawbacks
- * with regards to the overall thumbnailing responsiveness).
- *
- * Before a URI is added to the wait queue, it is checked whether it isn't already
- * 1) in the wait queue, 2) part of a pending or active request or 3) part of a
- * finished request which has an idle function pending.
- *
- * When a request call is finally sent out, an internal request ID is created and 
+ * 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. 
@@ -156,7 +136,7 @@ static void                   thunar_thumbnailer_thumbnailer_ready      (DBusGPr
 static void                   thunar_thumbnailer_thumbnailer_started    (DBusGProxy            *proxy,
                                                                          guint                  handle,
                                                                          ThunarThumbnailer     *thumbnailer);
-static gpointer               thunar_thumbnailer_queue_async            (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);
@@ -164,9 +144,6 @@ static gboolean               thunar_thumbnailer_ready_idle             (gpointe
 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);
-static ThunarThumbnailerItem *thunar_thumbnailer_item_new               (GFile                 *file,
-                                                                         const gchar           *mime_hint);
-static void                   thunar_thumbnailer_item_free              (gpointer               data);
 #endif
 
 
@@ -184,10 +161,6 @@ struct _ThunarThumbnailer
   /* proxies to communicate with D-Bus services */
   DBusGProxy *thumbnailer_proxy;
 
-  /* wait queue used to delay (and thereby group) thumbnail requests */
-  GList      *wait_queue;
-  guint       wait_queue_idle_id;
-
   /* hash table to map D-Bus service handles to ThunarThumbnailer requests */
   GHashTable *handle_request_mapping;
 
@@ -208,7 +181,7 @@ struct _ThunarThumbnailer
   gchar     **supported_types;
 
   /* last ThunarThumbnailer request ID */
-  gpointer    last_request;
+  ThunarThumbnailerRequest last_request;
 
   /* IDs of idle functions */
   GList      *idles;
@@ -244,9 +217,6 @@ struct _ThunarThumbnailerItem
 
 
 
-#ifdef HAVE_DBUS
-static DBusGProxy *thunar_thumbnailer_proxy;
-#endif
 
 
 
@@ -274,9 +244,8 @@ thunar_thumbnailer_init (ThunarThumbnailer *thumbnailer)
   thumbnailer->lock = g_mutex_new ();
   thumbnailer->supported_schemes = NULL;
   thumbnailer->supported_types = NULL;
-  thumbnailer->last_request = GUINT_TO_POINTER (0);
+  thumbnailer->last_request = 0;
   thumbnailer->idles = NULL;
-  thumbnailer->wait_queue_idle_id = 0;
 
   /* try to connect to D-Bus */
   connection = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
@@ -319,14 +288,6 @@ thunar_thumbnailer_finalize (GObject *object)
   /* acquire the thumbnailer lock */
   g_mutex_lock (thumbnailer->lock);
 
-  /* clear the request queue */
-  g_list_foreach (thumbnailer->wait_queue, (GFunc) thunar_thumbnailer_item_free, NULL);
-  g_list_free (thumbnailer->wait_queue);
-
-  /* remove the request queue processing idle handler */
-  if (thumbnailer->wait_queue_idle_id > 0)
-    g_source_remove (thumbnailer->wait_queue_idle_id);
-
   /* abort all pending idle functions */
   for (lp = thumbnailer->idles; lp != NULL; lp = lp->next)
     {
@@ -396,51 +357,37 @@ thunar_thumbnailer_init_thumbnailer_proxy (ThunarThumbnailer *thumbnailer,
       return;
     }
 
-  /* create the thumbnailer proxy shared by all ThunarThumbnailers on demand */
-  if (thunar_thumbnailer_proxy == NULL)
-    {
-      /* create the shared thumbnailer proxy */
-      thunar_thumbnailer_proxy = 
-        dbus_g_proxy_new_for_name (connection, 
-                                   "org.freedesktop.thumbnails.Thumbnailer1",
-                                   "/org/freedesktop/thumbnails/Thumbnailer1",
-                                   "org.freedesktop.thumbnails.Thumbnailer1");
-
-      /* make sure to set it to NULL when the last reference is dropped */
-      g_object_add_weak_pointer (G_OBJECT (thunar_thumbnailer_proxy),
-                                 (gpointer) &thunar_thumbnailer_proxy);
-
-      thumbnailer->thumbnailer_proxy = thunar_thumbnailer_proxy;
-
-      /* TODO this should actually be VOID:UINT,BOXED,INT,STRING */
-      dbus_g_object_register_marshaller (_thunar_marshal_VOID__UINT_BOXED_UINT_STRING,
-                                         G_TYPE_NONE,
-                                         G_TYPE_UINT, 
-                                         G_TYPE_STRV, 
-                                         G_TYPE_UINT, 
-                                         G_TYPE_STRING,
-                                         G_TYPE_INVALID);
-
-      dbus_g_object_register_marshaller ((GClosureMarshal) _thunar_marshal_VOID__UINT_BOXED,
-                                         G_TYPE_NONE,
-                                         G_TYPE_UINT,
-                                         G_TYPE_STRV,
-                                         G_TYPE_INVALID);
-
-      dbus_g_proxy_add_signal (thumbnailer->thumbnailer_proxy, "Error", 
-                               G_TYPE_UINT, G_TYPE_STRV, G_TYPE_UINT, G_TYPE_STRING, 
-                               G_TYPE_INVALID);
-      dbus_g_proxy_add_signal (thumbnailer->thumbnailer_proxy, "Finished", 
-                               G_TYPE_UINT, G_TYPE_INVALID);
-      dbus_g_proxy_add_signal (thumbnailer->thumbnailer_proxy, "Ready", 
-                               G_TYPE_UINT, G_TYPE_STRV, G_TYPE_INVALID);
-      dbus_g_proxy_add_signal (thumbnailer->thumbnailer_proxy, "Started", 
-                               G_TYPE_UINT, G_TYPE_INVALID);
-    }
-  else
-    {
-      thumbnailer->thumbnailer_proxy = g_object_ref (thunar_thumbnailer_proxy);
-    }
+  /* create the thumbnailer proxy */
+  thumbnailer->thumbnailer_proxy = 
+    dbus_g_proxy_new_for_name (connection, 
+                               "org.freedesktop.thumbnails.Thumbnailer1",
+                               "/org/freedesktop/thumbnails/Thumbnailer1",
+                               "org.freedesktop.thumbnails.Thumbnailer1");
+
+  /* TODO this should actually be VOID:UINT,BOXED,INT,STRING */
+  dbus_g_object_register_marshaller (_thunar_marshal_VOID__UINT_BOXED_UINT_STRING,
+                                     G_TYPE_NONE,
+                                     G_TYPE_UINT, 
+                                     G_TYPE_STRV, 
+                                     G_TYPE_UINT, 
+                                     G_TYPE_STRING,
+                                     G_TYPE_INVALID);
+
+  dbus_g_object_register_marshaller ((GClosureMarshal) _thunar_marshal_VOID__UINT_BOXED,
+                                     G_TYPE_NONE,
+                                     G_TYPE_UINT,
+                                     G_TYPE_STRV,
+                                     G_TYPE_INVALID);
+
+  dbus_g_proxy_add_signal (thumbnailer->thumbnailer_proxy, "Error", 
+                           G_TYPE_UINT, G_TYPE_STRV, G_TYPE_UINT, G_TYPE_STRING, 
+                           G_TYPE_INVALID);
+  dbus_g_proxy_add_signal (thumbnailer->thumbnailer_proxy, "Finished", 
+                           G_TYPE_UINT, G_TYPE_INVALID);
+  dbus_g_proxy_add_signal (thumbnailer->thumbnailer_proxy, "Ready", 
+                           G_TYPE_UINT, G_TYPE_STRV, G_TYPE_INVALID);
+  dbus_g_proxy_add_signal (thumbnailer->thumbnailer_proxy, "Started", 
+                           G_TYPE_UINT, G_TYPE_INVALID);
 
   dbus_g_proxy_connect_signal (thumbnailer->thumbnailer_proxy, "Error",
                                G_CALLBACK (thunar_thumbnailer_thumbnailer_error), 
@@ -576,7 +523,7 @@ thunar_thumbnailer_thumbnailer_finished (DBusGProxy        *proxy,
                                  GUINT_TO_POINTER (handle));
 
   /* check if we have a request for this handle */
-  if (request != NULL)
+  if (GPOINTER_TO_UINT (request) > 0)
     {
       /* the request is finished, drop all the information about it */
       g_hash_table_remove (thumbnailer->handle_request_mapping, request);
@@ -709,7 +656,7 @@ thunar_thumbnailer_queue_async_reply (DBusGProxy *proxy,
 
 
 
-static gpointer
+static guint
 thunar_thumbnailer_queue_async (ThunarThumbnailer *thumbnailer,
                                 gchar            **uris,
                                 const gchar      **mime_hints)
@@ -725,14 +672,14 @@ thunar_thumbnailer_queue_async (ThunarThumbnailer *thumbnailer,
   _thunar_return_val_if_fail (DBUS_IS_G_PROXY (thumbnailer->thumbnailer_proxy), 0);
 
   /* compute the next request ID, making sure it's never 0 */
-  request_no = GPOINTER_TO_UINT (thumbnailer->last_request) + 1;
+  request_no = thumbnailer->last_request + 1;
   request_no = MAX (request_no, 1);
   
   /* remember the ID for the next request */
-  thumbnailer->last_request = GUINT_TO_POINTER (request_no);
+  thumbnailer->last_request = request_no;
 
-  /* use the new request ID for this request */
-  request = thumbnailer->last_request;
+  /* use the newly generated ID for this request */
+  request = GUINT_TO_POINTER (request_no);
 
   /* allocate a new call struct for the async D-Bus call */
   thumbnailer_call = g_slice_new0 (ThunarThumbnailerCall);
@@ -753,7 +700,7 @@ thunar_thumbnailer_queue_async (ThunarThumbnailer *thumbnailer,
   g_hash_table_insert (thumbnailer->request_call_mapping, request, call);
 
   /* return the request ID used for this request */
-  return request;
+  return request_no;
 }
 
 
@@ -884,176 +831,6 @@ thunar_thumbnailer_started_idle (gpointer user_data)
 
 
 
-static gboolean
-thunar_thumbnailer_file_is_in_wait_queue (ThunarThumbnailer *thumbnailer,
-                                          ThunarFile        *file)
-{
-  ThunarThumbnailerItem *item;
-  gboolean               in_wait_queue = FALSE;
-  GList                 *lp;
-
-  g_mutex_lock (thumbnailer->lock);
-
-  for (lp = thumbnailer->wait_queue; !in_wait_queue && lp != NULL; lp = lp->next)
-    {
-      item = lp->data;
-
-      if (g_file_equal (item->file, thunar_file_get_file (file)))
-        in_wait_queue = TRUE;
-    }
-
-  g_mutex_unlock (thumbnailer->lock);
-
-  return in_wait_queue;
-}
-
-
-
-static gboolean
-thunar_thumbnailer_process_wait_queue (ThunarThumbnailer *thumbnailer)
-{
-  ThunarThumbnailerItem *item;
-  gpointer               request;
-  GList                 *lp;
-  gchar                **mime_hints;
-  gchar                **uris;
-  guint                  n_items;
-  guint                  n;
-
-  _thunar_return_val_if_fail (THUNAR_IS_THUMBNAILER (thumbnailer), FALSE);
-
-  g_mutex_lock (thumbnailer->lock);
-
-  /* determine how many URIs are in the wait queue */
-  n_items = g_list_length (thumbnailer->wait_queue);
-
-  /* allocate arrays for URIs and mime hints */
-  uris = g_new0 (gchar *, n_items + 1);
-  mime_hints = g_new0 (gchar *, n_items + 1);
-
-  /* fill URI and MIME hint arrays with items from the wait queue */
-  for (lp = g_list_last (thumbnailer->wait_queue), n = 0; lp != NULL; lp = lp->prev, ++n)
-    {
-      /* fetch the next item from the queue */
-      item = lp->data;
-
-      /* save URI and MIME hint in the arrays */
-      uris[n] = g_file_get_uri (item->file);
-      mime_hints[n] = item->mime_hint;
-
-      /* destroy the GFile and the queue item. The MIME hints are free'd later */
-      g_object_unref (item->file);
-      g_slice_free (ThunarThumbnailerItem, item);
-    }
-
-  /* NULL-terminate both arrays */
-  uris[n] = NULL;
-  mime_hints[n] = NULL;
-
-  /* queue a thumbnail request for the URIs from the wait queue */
-  request = thunar_thumbnailer_queue_async (thumbnailer, uris, 
-                                            (const gchar **)mime_hints);
-
-  /* free mime hints array */
-  g_strfreev (mime_hints);
-
-  /* clear the wait queue */
-  g_list_free (thumbnailer->wait_queue);
-  thumbnailer->wait_queue = NULL;
-
-  /* reset the wait queue idle ID */
-  thumbnailer->wait_queue_idle_id = 0;
-
-  g_mutex_unlock (thumbnailer->lock);
-
-  return FALSE;
-}
-
-
-
-static gboolean
-thunar_thumbnailer_file_is_queued (ThunarThumbnailer *thumbnailer,
-                                   ThunarFile        *file)
-{
-  gboolean is_queued = FALSE;
-  GList   *values;
-  GList   *lp;
-  gchar  **uris;
-  gchar   *uri;
-  guint    n;
-
-  /* get a list with all URI arrays of already queued requests */
-  values = g_hash_table_get_values (thumbnailer->request_uris_mapping);
-
-  /* if we have none, the file cannot be queued ... or can it? ;) */
-  if (values == NULL)
-    return FALSE;
-
-  /* determine the URI for this file */
-  uri = thunar_file_dup_uri (file);
-
-  /* iterate over all URI arrays */
-  for (lp = values; !is_queued && lp != NULL; lp = lp->next)
-    {
-      uris = lp->data;
-
-      /* check if the file is included in the URI array of the current request */
-      for (n = 0; !is_queued && uris != NULL && uris[n] != NULL; ++n)
-        if (g_utf8_collate (uri, uris[n]) == 0)
-          is_queued = TRUE;
-    }
-
-  /* free the file URI */
-  g_free (uri);
-
-  /* free the URI array list */
-  g_list_free (values);
-
-  return is_queued;
-}
-
-
-
-static gboolean
-thunar_thumbnailer_file_is_ready (ThunarThumbnailer *thumbnailer,
-                                  ThunarFile        *file)
-{
-  ThunarThumbnailerIdle *idle;
-  gboolean               is_ready = FALSE;
-  GList                 *lp;
-  gchar                 *uri;
-  guint                  n;
-
-  /* determine the URI or this file */
-  uri = thunar_file_dup_uri (file);
-
-  /* iterate over all idle structs */
-  for (lp = thumbnailer->idles; !is_ready && lp != NULL; lp = lp->next)
-    {
-      /* skip invalid idles */
-      if (lp->data != NULL)
-        continue;
-
-      idle = lp->data;
-
-      /* skip non-ready idles and idles without any URIs */
-      if (idle->type != THUNAR_THUMBNAILER_IDLE_READY || idle->data.uris == NULL)
-        continue;
-
-      /* check if the file is included in this ready idle */
-      for (n = 0; !is_ready && idle->data.uris[n] != NULL; ++n)
-        if (g_utf8_collate (uri, idle->data.uris[n]) == 0)
-          is_ready = TRUE;
-    }
-
-  /* free the file URI */
-  g_free (uri);
-
-  return is_ready;
-}
-
-
-
 static void
 thunar_thumbnailer_call_free (ThunarThumbnailerCall *call)
 {
@@ -1088,35 +865,6 @@ thunar_thumbnailer_idle_free (gpointer data)
   /* free the struct */
   g_slice_free (ThunarThumbnailerIdle, idle);
 }
-
-
-
-static ThunarThumbnailerItem *
-thunar_thumbnailer_item_new (GFile       *file,
-                             const gchar *mime_hint)
-{
-  ThunarThumbnailerItem *item;
-
-  _thunar_return_val_if_fail (G_IS_FILE (file), NULL);
-  _thunar_return_val_if_fail (mime_hint != NULL && mime_hint != '\0', NULL);
-
-  item = g_slice_new0 (ThunarThumbnailerItem);
-  item->file = g_object_ref (file);
-  item->mime_hint = g_strdup (mime_hint);
-
-  return item;
-}
-
-
-static void
-thunar_thumbnailer_item_free (gpointer data)
-{
-  ThunarThumbnailerItem *item = data;
-
-  g_object_unref (item->file);
-  g_free (item->mime_hint);
-  g_slice_free (ThunarThumbnailerItem, item);
-}
 #endif /* HAVE_DBUS */
 
 
@@ -1141,8 +889,9 @@ thunar_thumbnailer_new (void)
 
 
 gboolean
-thunar_thumbnailer_queue_file (ThunarThumbnailer *thumbnailer,
-                               ThunarFile        *file)
+thunar_thumbnailer_queue_file (ThunarThumbnailer        *thumbnailer,
+                               ThunarFile               *file,
+                               ThunarThumbnailerRequest *request)
 {
   GList files;
 
@@ -1155,22 +904,24 @@ thunar_thumbnailer_queue_file (ThunarThumbnailer *thumbnailer,
   files.prev = NULL;
 
   /* queue a thumbnail request for the file */
-  return thunar_thumbnailer_queue_files (thumbnailer, &files);
+  return thunar_thumbnailer_queue_files (thumbnailer, &files, request);
 }
 
 
 
 gboolean
-thunar_thumbnailer_queue_files (ThunarThumbnailer *thumbnailer,
-                                GList             *files)
+thunar_thumbnailer_queue_files (ThunarThumbnailer        *thumbnailer,
+                                GList                    *files,
+                                ThunarThumbnailerRequest *request)
 {
+  const gchar **mime_hints;
+  gboolean      success = FALSE;
 #ifdef HAVE_DBUS
-  ThunarThumbnailerItem *item;
-#endif
-  gboolean               success = FALSE;
-#ifdef HAVE_DBUS
-  GList                 *lp;
-  GList                 *supported_files = NULL;
+  gchar       **uris;
+  GList        *lp;
+  GList        *supported_files = NULL;
+  guint         n;
+  guint         n_items;
 #endif
 
   _thunar_return_val_if_fail (THUNAR_IS_THUMBNAILER (thumbnailer), FALSE);
@@ -1194,44 +945,52 @@ thunar_thumbnailer_queue_files (ThunarThumbnailer *thumbnailer,
    * about to be queued (wait queue), nor already queued, nor already 
    * processed (and awaiting to be refreshed) */
   for (lp = g_list_last (files); lp != NULL; lp = lp->prev)
-    if (thunar_thumbnailer_file_is_supported (thumbnailer, lp->data))
-      {
-        if (!thunar_thumbnailer_file_is_in_wait_queue (thumbnailer, lp->data)
-            && !thunar_thumbnailer_file_is_queued (thumbnailer, lp->data)
-            && !thunar_thumbnailer_file_is_ready (thumbnailer, lp->data))
-          {
-            supported_files = g_list_prepend (supported_files, lp->data);
-          }
-      }
-
-  /* check if we have any supported files */
-  if (supported_files != NULL)
     {
-      for (lp = supported_files; lp != NULL; lp = lp->next)
-        {
-          g_mutex_lock (thumbnailer->lock);
+      if (thunar_thumbnailer_file_is_supported (thumbnailer, lp->data))
+        supported_files = g_list_prepend (supported_files, lp->data);
+    }
 
-          /* allocate a thumbnailer item for the wait queue */
-          item = thunar_thumbnailer_item_new (thunar_file_get_file (lp->data),
-                                              thunar_file_get_content_type (lp->data));
+  /* determine how many URIs are in the wait queue */
+  n_items = g_list_length (supported_files);
 
-          /* add the item to the wait queue */
-          thumbnailer->wait_queue = g_list_prepend (thumbnailer->wait_queue, item);
+  /* check if we have any supported files */
+  if (n_items > 0)
+    {
+      /* allocate arrays for URIs and mime hints */
+      uris = g_new0 (gchar *, n_items + 1);
+      mime_hints = g_new0 (const gchar *, n_items + 1);
 
-          g_mutex_unlock (thumbnailer->lock);
+      /* 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)
+        {
+          /* 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);
         }
 
+      /* NULL-terminate both arrays */
+      uris[n] = NULL;
+      mime_hints[n] = NULL;
+
       g_mutex_lock (thumbnailer->lock);
 
-      if (thumbnailer->wait_queue_idle_id == 0)
+      /* 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);
+        }
+      else
         {
-          thumbnailer->wait_queue_idle_id = 
-            g_timeout_add (100, (GSourceFunc) thunar_thumbnailer_process_wait_queue, 
-                           thumbnailer);
+          thunar_thumbnailer_queue_async (thumbnailer, uris,
+                                          (const gchar **)mime_hints);
         }
 
       g_mutex_unlock (thumbnailer->lock);
-      
+
+      /* free mime hints array */
+      g_free (mime_hints);
+
       /* free the list of supported files */
       g_list_free (supported_files);
 
@@ -1244,35 +1003,43 @@ thunar_thumbnailer_queue_files (ThunarThumbnailer *thumbnailer,
 }
 
 
-#if 0 
-static void
-thunar_thumbnailer_unqueue (ThunarThumbnailer *thumbnailer,
-                            gpointer           request)
+void
+thunar_thumbnailer_unqueue (ThunarThumbnailer       *thumbnailer,
+                            ThunarThumbnailerRequest request)
 {
 #ifdef HAVE_DBUS
+  gpointer request_ptr;
   gpointer handle;
 #endif
 
   _thunar_return_if_fail (THUNAR_IS_THUMBNAILER (thumbnailer));
 
 #ifdef HAVE_DBUS
+  /* convert the number to a pointer */
+  request_ptr = GUINT_TO_POINTER (request);
+
   /* acquire the thumbnailer lock */
   g_mutex_lock (thumbnailer->lock);
 
+  /* check if we have a valid thumbnailer proxy */
   if (thumbnailer->thumbnailer_proxy != NULL)
     {
-      handle = g_hash_table_lookup (thumbnailer->request_handle_mapping, request);
-
-      thunar_thumbnailer_proxy_unqueue (thumbnailer->thumbnailer_proxy, 
-                                        GPOINTER_TO_UINT (handle), NULL);
-
-      g_hash_table_remove (thumbnailer->handle_request_mapping, handle);
-      g_hash_table_remove (thumbnailer->request_handle_mapping, request);
-      g_hash_table_remove (thumbnailer->request_uris_mapping, request);
+      /* check if there is a pending tumbler request handle for this request */
+      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, 
+                                            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);
+        }
     }
 
   /* release the thumbnailer lock */
   g_mutex_unlock (thumbnailer->lock);
 #endif
 }
-#endif
diff --git a/thunar/thunar-thumbnailer.h b/thunar/thunar-thumbnailer.h
index 83fa4ce..c9744b9 100644
--- a/thunar/thunar-thumbnailer.h
+++ b/thunar/thunar-thumbnailer.h
@@ -1,20 +1,21 @@
-/* $Id$ */
+/* vi:set et ai sw=2 sts=2 ts=2: */
 /*-
- * 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.
  */
 
 #ifndef __THUNAR_THUMBNAILER_H__
@@ -24,6 +25,8 @@
 
 G_BEGIN_DECLS;
 
+typedef guint ThunarThumbnailerRequest;
+
 typedef struct _ThunarThumbnailerClass ThunarThumbnailerClass;
 typedef struct _ThunarThumbnailer      ThunarThumbnailer;
 
@@ -34,14 +37,18 @@ typedef struct _ThunarThumbnailer      ThunarThumbnailer;
 #define THUNAR_IS_THUMBNAILER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_THUMBNAILER))
 #define THUNAR_THUMBNAILER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_THUMBNAILER, ThunarThumbnailerClass))
 
-GType              thunar_thumbnailer_get_type          (void) G_GNUC_CONST;
+GType              thunar_thumbnailer_get_type        (void) G_GNUC_CONST;
 
-ThunarThumbnailer *thunar_thumbnailer_new               (void) G_GNUC_MALLOC;
+ThunarThumbnailer *thunar_thumbnailer_new             (void) G_GNUC_MALLOC;
 
-gboolean           thunar_thumbnailer_queue_file        (ThunarThumbnailer *generator,
-                                                         ThunarFile        *file);
-gboolean           thunar_thumbnailer_queue_files       (ThunarThumbnailer *generator,
-                                                         GList             *files);
+gboolean           thunar_thumbnailer_queue_file      (ThunarThumbnailer        *thumbnailer,
+                                                       ThunarFile               *file,
+                                                       ThunarThumbnailerRequest *request);
+gboolean           thunar_thumbnailer_queue_files     (ThunarThumbnailer        *thumbnailer,
+                                                       GList                    *files,
+                                                       ThunarThumbnailerRequest *request);
+void               thunar_thumbnailer_unqueue         (ThunarThumbnailer        *thumbnailer,
+                                                       ThunarThumbnailerRequest  request);
 
 G_END_DECLS;
 



More information about the Xfce4-commits mailing list