[gnome-desktop] Add ASYNC methods for thumbnail creation



commit eb5d2b9b49270ccdd977b96392ade22521a8f53a
Author: Sergio Costas <raster rastersoft com>
Date:   Thu Jan 27 00:19:32 2022 +0100

    Add ASYNC methods for thumbnail creation
    
    This MR adds async versions for the following methods:
    
     gnome_desktop_thumbnail_factory_generate_thumbnail
     gnome_desktop_thumbnail_factory_save_thumbnail
     gnome_desktop_thumbnail_factory_create_failed_thumbnail
    
    This is useful to avoid blocking the main loop while creating
    the thumbnails (which is an operation that can last too much
    time), and allows to do it in Javascript, where is not possible
    to create a thread in a GTask.
    
    Fix https://gitlab.gnome.org/GNOME/gnome-desktop/-/issues/205

 libgnome-desktop/gnome-desktop-thumbnail.c | 242 +++++++++++++++++++++++++++++
 libgnome-desktop/gnome-desktop-thumbnail.h |  33 ++++
 meson.build                                |   4 +-
 3 files changed, 277 insertions(+), 2 deletions(-)
---
diff --git a/libgnome-desktop/gnome-desktop-thumbnail.c b/libgnome-desktop/gnome-desktop-thumbnail.c
index 3d1c9b4a..011f112e 100644
--- a/libgnome-desktop/gnome-desktop-thumbnail.c
+++ b/libgnome-desktop/gnome-desktop-thumbnail.c
@@ -1132,6 +1132,100 @@ gnome_desktop_thumbnail_factory_generate_thumbnail (GnomeDesktopThumbnailFactory
   return pixbuf;
 }
 
+typedef struct {
+  char *uri;
+  char *mime_type;
+  GdkPixbuf *thumbnail;
+  time_t time;
+} ThumbnailFactoryAsyncData;
+
+static void
+thumbnail_factory_async_data_free (ThumbnailFactoryAsyncData *thumbnail_factory_data)
+{
+  g_free (thumbnail_factory_data->uri);
+  g_free (thumbnail_factory_data->mime_type);
+  if (thumbnail_factory_data->thumbnail)
+    g_object_unref (thumbnail_factory_data->thumbnail);
+  g_slice_free (ThumbnailFactoryAsyncData, thumbnail_factory_data);
+}
+
+static void
+thumbnail_factory_thread (GTask         *task,
+                          gpointer       source_object,
+                          gpointer       task_data,
+                          GCancellable  *cancellable)
+{
+  GnomeDesktopThumbnailFactory *self = source_object;
+  ThumbnailFactoryAsyncData *thumbnail_factory_data = task_data;
+  GdkPixbuf *thumbnail;
+
+  thumbnail = gnome_desktop_thumbnail_factory_generate_thumbnail (self,
+                                                                  thumbnail_factory_data->uri,
+                                                                  thumbnail_factory_data->mime_type);
+  if (thumbnail)
+    g_task_return_pointer (task, thumbnail, g_object_unref);
+  else
+    g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to generate the thumbnail.");
+}
+
+/**
+ * gnome_desktop_thumbnail_factory_generate_thumbnail_async:
+ * @factory: a #GnomeDesktopThumbnailFactory
+ * @uri: the URI of a file
+ * @mime_type: the MIME type of the file
+ * @cancellable: a Cancellable object
+ * @callback: a function that will be called when the task has ended
+ * @user_data: user data
+ *
+ * Asynchronous version of gnome_desktop_thumbnail_factory_generate_thumbnail()
+ *
+ * Since 42.0
+ *
+ **/
+
+void
+gnome_desktop_thumbnail_factory_generate_thumbnail_async (GnomeDesktopThumbnailFactory *factory,
+                                                          const char                   *uri,
+                                                          const char                   *mime_type,
+                                                          GCancellable                 *cancellable,
+                                                          GAsyncReadyCallback           callback,
+                                                          gpointer                      user_data)
+{
+  ThumbnailFactoryAsyncData *thumbnail_factory_data;
+  GTask *task;
+
+  thumbnail_factory_data = g_slice_new (ThumbnailFactoryAsyncData);
+  thumbnail_factory_data->uri = g_strdup (uri);
+  thumbnail_factory_data->mime_type = g_strdup (mime_type);
+  thumbnail_factory_data->thumbnail = NULL;
+  task = g_task_new (factory, cancellable, callback, user_data);
+  g_task_set_task_data (task, thumbnail_factory_data, (GDestroyNotify) thumbnail_factory_async_data_free);
+  g_task_run_in_thread (task, thumbnail_factory_thread);
+  g_object_unref (task);
+}
+
+/**
+ * gnome_desktop_thumbnail_factory_generate_thumbnail_finish:
+ * @factory: a #GnomeDesktopThumbnailFactory
+ * @result: the result of the operation
+ * @error: a pointer where a GError object is returned if the task failed
+ *
+ * Return value: (transfer full): thumbnail pixbuf if thumbnailing succeeded, %NULL otherwise.
+ *
+ * Since 42.0
+ *
+ **/
+
+GdkPixbuf *
+gnome_desktop_thumbnail_factory_generate_thumbnail_finish (GnomeDesktopThumbnailFactory *factory,
+                                                           GAsyncResult                 *result,
+                                                           GError                      **error)
+{
+  g_return_val_if_fail (g_task_is_valid (result, factory), NULL);
+
+  return g_task_propagate_pointer (G_TASK (result), error);
+}
+
 static gboolean
 save_thumbnail (GdkPixbuf  *pixbuf,
                 char       *path,
@@ -1247,6 +1341,82 @@ gnome_desktop_thumbnail_factory_save_thumbnail (GnomeDesktopThumbnailFactory *fa
   g_free (path);
 }
 
+static void
+thumbnail_factory_save_thread (GTask         *task,
+                               gpointer       source_object,
+                               gpointer       task_data,
+                               GCancellable  *cancellable)
+{
+  GnomeDesktopThumbnailFactory *self = source_object;
+  ThumbnailFactoryAsyncData *thumbnail_factory_data = task_data;
+
+  gnome_desktop_thumbnail_factory_save_thumbnail (self,
+                                                  thumbnail_factory_data->thumbnail,
+                                                  thumbnail_factory_data->uri,
+                                                  thumbnail_factory_data->time);
+  g_task_return_boolean (task, FALSE);
+}
+
+/**
+ * gnome_desktop_thumbnail_factory_save_thumbnail_async:
+ * @factory: a #GnomeDesktopThumbnailFactory
+ * @thumbnail: the thumbnail as a pixbuf
+ * @uri: the uri of a file
+ * @original_mtime: the modification time of the original file
+ * @cancellable: a Cancellable object
+ * @callback: a function that will be called when the task has ended
+ * @user_data: user data
+ *
+ * Asynchronous version of gnome_desktop_thumbnail_factory_save_thumbnail()
+ *
+ * Since 42.0
+ *
+ **/
+
+void
+gnome_desktop_thumbnail_factory_save_thumbnail_async (GnomeDesktopThumbnailFactory *factory,
+                                                      GdkPixbuf                    *thumbnail,
+                                                      const char                   *uri,
+                                                      time_t                        original_mtime,
+                                                      GCancellable                 *cancellable,
+                                                      GAsyncReadyCallback           callback,
+                                                      gpointer                      user_data)
+{
+  ThumbnailFactoryAsyncData *thumbnail_factory_data;
+  GTask *task;
+
+  thumbnail_factory_data = g_slice_new (ThumbnailFactoryAsyncData);
+  thumbnail_factory_data->uri = g_strdup (uri);
+  thumbnail_factory_data->mime_type = NULL;
+  thumbnail_factory_data->thumbnail = g_object_ref(thumbnail);
+  thumbnail_factory_data->time = original_mtime;
+  task = g_task_new (factory, cancellable, callback, user_data);
+  g_task_set_task_data (task, thumbnail_factory_data, (GDestroyNotify) thumbnail_factory_async_data_free);
+  g_task_run_in_thread (task, thumbnail_factory_save_thread);
+  g_object_unref (task);
+}
+
+/**
+ * gnome_desktop_thumbnail_factory_save_thumbnail_finish:
+ * @factory: a #GnomeDesktopThumbnailFactory
+ * @result: the result of the operation
+ * @error: a pointer where a GError object is returned if the task failed
+ *
+ * Since 42.0
+ *
+ **/
+
+void
+gnome_desktop_thumbnail_factory_save_thumbnail_finish (GnomeDesktopThumbnailFactory *factory,
+                                                       GAsyncResult                 *result,
+                                                       GError                      **error)
+{
+  g_return_if_fail (g_task_is_valid (result, factory));
+
+  g_task_propagate_boolean (G_TASK (result), error);
+}
+
+
 /**
  * gnome_desktop_thumbnail_factory_create_failed_thumbnail:
  * @factory: a #GnomeDesktopThumbnailFactory
@@ -1275,6 +1445,78 @@ gnome_desktop_thumbnail_factory_create_failed_thumbnail (GnomeDesktopThumbnailFa
   g_object_unref (pixbuf);
 }
 
+static void
+thumbnail_factory_create_failed_thread (GTask         *task,
+                                        gpointer       source_object,
+                                        gpointer       task_data,
+                                        GCancellable  *cancellable)
+{
+  GnomeDesktopThumbnailFactory *self = source_object;
+  ThumbnailFactoryAsyncData *thumbnail_factory_data = task_data;
+
+  gnome_desktop_thumbnail_factory_create_failed_thumbnail (self,
+                                                           thumbnail_factory_data->uri,
+                                                           thumbnail_factory_data->time);
+  g_task_return_boolean (task, FALSE);
+}
+
+/**
+ * gnome_desktop_thumbnail_factory_create_failed_thumbnail_async:
+ * @factory: a #GnomeDesktopThumbnailFactory
+ * @uri: the uri of a file
+ * @original_mtime: the modification time of the original file
+ * @cancellable: a Cancellable object
+ * @callback: a function that will be called when the task has ended
+ * @user_data: user data
+ *
+ * Asynchronous version of gnome_desktop_thumbnail_factory_create_failed_thumbnail()
+ *
+ * Since 42.0
+ *
+ **/
+
+void
+gnome_desktop_thumbnail_factory_create_failed_thumbnail_async (GnomeDesktopThumbnailFactory *factory,
+                                                               const char                   *uri,
+                                                               time_t                        original_mtime,
+                                                               GCancellable                 *cancellable,
+                                                               GAsyncReadyCallback           callback,
+                                                               gpointer                      user_data)
+{
+  ThumbnailFactoryAsyncData *thumbnail_factory_data;
+  GTask *task;
+
+  thumbnail_factory_data = g_slice_new (ThumbnailFactoryAsyncData);
+  thumbnail_factory_data->uri = g_strdup (uri);
+  thumbnail_factory_data->mime_type = NULL;
+  thumbnail_factory_data->thumbnail = NULL;
+  thumbnail_factory_data->time = original_mtime;
+  task = g_task_new (factory, cancellable, callback, user_data);
+  g_task_set_task_data (task, thumbnail_factory_data, (GDestroyNotify) thumbnail_factory_async_data_free);
+  g_task_run_in_thread (task, thumbnail_factory_create_failed_thread);
+  g_object_unref (task);
+}
+
+/**
+ * gnome_desktop_thumbnail_factory_create_failed_thumbnail_finish:
+ * @factory: a #GnomeDesktopThumbnailFactory
+ * @result: the result of the operation
+ * @error: a pointer where a GError object is returned if the task failed
+ *
+ * Since 42.0
+ *
+ **/
+
+void
+gnome_desktop_thumbnail_factory_create_failed_thumbnail_finish (GnomeDesktopThumbnailFactory *factory,
+                                                                GAsyncResult                 *result,
+                                                                GError                      **error)
+{
+  g_return_if_fail (g_task_is_valid (result, factory));
+
+  g_task_propagate_boolean (G_TASK (result), error);
+}
+
 /**
  * gnome_desktop_thumbnail_path_for_uri:
  * @uri: an uri
diff --git a/libgnome-desktop/gnome-desktop-thumbnail.h b/libgnome-desktop/gnome-desktop-thumbnail.h
index cd2e8099..1735658b 100644
--- a/libgnome-desktop/gnome-desktop-thumbnail.h
+++ b/libgnome-desktop/gnome-desktop-thumbnail.h
@@ -91,6 +91,39 @@ void                   gnome_desktop_thumbnail_factory_create_failed_thumbnail (
                                                                                const char            *uri,
                                                                                time_t                 mtime);
 
+void                   gnome_desktop_thumbnail_factory_generate_thumbnail_async 
(GnomeDesktopThumbnailFactory *factory,
+                                                                                 const char                  
 *uri,
+                                                                                 const char                  
 *mime_type,
+                                                                                 GCancellable                
 *cancellable,
+                                                                                 GAsyncReadyCallback         
  callback,
+                                                                                 gpointer                    
  user_data);
+
+GdkPixbuf *            gnome_desktop_thumbnail_factory_generate_thumbnail_finish 
(GnomeDesktopThumbnailFactory *factory,
+                                                                                  GAsyncResult               
  *result,
+                                                                                  GError                     
 **error);
+
+void                   gnome_desktop_thumbnail_factory_save_thumbnail_async (GnomeDesktopThumbnailFactory 
*factory,
+                                                                             GdkPixbuf                    
*thumbnail,
+                                                                             const char                   
*uri,
+                                                                             time_t                        
original_mtime,
+                                                                             GCancellable                 
*cancellable,
+                                                                             GAsyncReadyCallback           
callback,
+                                                                             gpointer                      
user_data);
+
+void                   gnome_desktop_thumbnail_factory_save_thumbnail_finish (GnomeDesktopThumbnailFactory 
*factory,
+                                                                              GAsyncResult                 
*result,
+                                                                              GError                      
**error);
+
+void                   gnome_desktop_thumbnail_factory_create_failed_thumbnail_async 
(GnomeDesktopThumbnailFactory *factory,
+                                                                                      const char             
      *uri,
+                                                                                      time_t                 
       original_mtime,
+                                                                                      GCancellable           
      *cancellable,
+                                                                                      GAsyncReadyCallback    
       callback,
+                                                                                      gpointer               
       user_data);
+
+void                   gnome_desktop_thumbnail_factory_create_failed_thumbnail_finish 
(GnomeDesktopThumbnailFactory *factory,
+                                                                                       GAsyncResult          
       *result,
+                                                                                       GError                
      **error);
 
 /* Thumbnailing utils: */
 gboolean   gnome_desktop_thumbnail_is_valid          (GdkPixbuf          *pixbuf,
diff --git a/meson.build b/meson.build
index 16830f43..d951b966 100644
--- a/meson.build
+++ b/meson.build
@@ -17,11 +17,11 @@ project('gnome-desktop', 'c',
 # to 0. When bumping the second version, set the third one to zero.
 #
 # A lot easier than libtool, right?
-libversion = '1.0.1'
+libversion = '1.1.0'
 soversion = libversion.split('.')[0]
 
 # Compatibility versions for libgnome-desktop-3
-compat_libversion = '19.2.0'
+compat_libversion = '19.3.0'
 compat_soversion = compat_libversion.split('.')[0]
 
 gdk_pixbuf_req = '>= 2.36.5'


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]