[nautilus/wip/antoniof/gtk4-restore-clipboard: 100/102] files-view: Factor out clipboard reading common code




commit a0b4da617b76452667c028954062fac6106f2d23
Author: António Fernandes <antoniof gnome org>
Date:   Tue Jan 4 21:08:17 2022 +0000

    files-view: Factor out clipboard reading common code
    
    Refactoring with multiple goals:
      - Cut down on verbose repeated patterns.
      - Use GTask to keep the source object alive in our stead.
      - Introduce a convenient async API which can be used by subclasses.
      - Use more autocleanups.

 src/nautilus-files-view.c | 236 ++++++++++++++++++----------------------------
 src/nautilus-files-view.h |   8 ++
 2 files changed, 100 insertions(+), 144 deletions(-)
---
diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c
index 580c415d1..7e4f1d19f 100644
--- a/src/nautilus-files-view.c
+++ b/src/nautilus-files-view.c
@@ -270,6 +270,8 @@ typedef struct
     /* Non exported menu, only for caching */
     GMenuModel *scripts_menu;
 
+    GCancellable *clipboard_cancellable;
+
     GCancellable *starred_cancellable;
     NautilusTagManager *tag_manager;
 
@@ -356,6 +358,64 @@ G_DEFINE_TYPE_WITH_CODE (NautilusFilesView,
                          G_IMPLEMENT_INTERFACE (NAUTILUS_TYPE_VIEW, nautilus_files_view_iface_init)
                          G_ADD_PRIVATE (NautilusFilesView));
 
+/* Clipboard async helpers. */
+static void
+clipboard_read_value_callback (GObject      *source_object,
+                               GAsyncResult *result,
+                               gpointer      user_data)
+{
+    GdkClipboard *clipboard = GDK_CLIPBOARD (source_object);
+    g_autoptr (GTask) task = user_data;
+    g_autoptr (GError) error = NULL;
+    const GValue *value;
+
+    value = gdk_clipboard_read_value_finish (clipboard, result, &error);
+
+    if (error != NULL)
+    {
+        g_task_return_error (task, g_steal_pointer (&error));
+    }
+    else
+    {
+        g_warn_if_fail (G_VALUE_HOLDS (value, NAUTILUS_TYPE_CLIPBOARD));
+
+        g_task_return_pointer (task, g_value_get_boxed (value), NULL);
+    }
+}
+
+void
+nautilus_files_view_get_clipboard_async (NautilusFilesView   *self,
+                                         GAsyncReadyCallback  callback,
+                                         gpointer             callback_data)
+{
+    NautilusFilesViewPrivate *priv = nautilus_files_view_get_instance_private (self);
+    GTask *task;
+
+    if (priv->clipboard_cancellable == NULL)
+    {
+        priv->clipboard_cancellable = g_cancellable_new ();
+    }
+
+    task = g_task_new (self,
+                       priv->clipboard_cancellable,
+                       callback,
+                       callback_data);
+    gdk_clipboard_read_value_async (gtk_widget_get_clipboard (GTK_WIDGET (self)),
+                                    NAUTILUS_TYPE_CLIPBOARD,
+                                    G_PRIORITY_DEFAULT,
+                                    priv->clipboard_cancellable,
+                                    clipboard_read_value_callback,
+                                    task);
+}
+
+NautilusClipboard *
+nautilus_files_view_get_clipboard_finish (NautilusFilesView  *self,
+                                          GAsyncResult       *result,
+                                          GError            **error)
+{
+    return g_task_propagate_pointer (G_TASK (result), error);
+}
+
 /*
  * Floating Bar code
  */
@@ -2649,54 +2709,24 @@ paste_clipboard_received_callback (GObject      *source_object,
                                    GAsyncResult *res,
                                    gpointer      user_data)
 {
-    GdkClipboard *clipboard = GDK_CLIPBOARD (source_object);
-    NautilusFilesView *view;
-    NautilusFilesViewPrivate *priv;
-    const GValue *value;
+    NautilusFilesView *view = NAUTILUS_FILES_VIEW (source_object);
     NautilusClipboard *clip;
-    char *view_uri;
+    g_autofree char *view_uri = NULL;
 
-    view = NAUTILUS_FILES_VIEW (user_data);
-    priv = nautilus_files_view_get_instance_private (view);
-
-    value = gdk_clipboard_read_value_finish (clipboard, res, NULL);
-    if (!G_VALUE_HOLDS (value, NAUTILUS_TYPE_CLIPBOARD))
-    {
-        g_object_unref (view);
-        return;
-    }
-    clip = g_value_get_boxed (value);
-
-    view_uri = nautilus_files_view_get_backing_uri (view);
-
-    if (priv->slot != NULL)
+    clip = nautilus_files_view_get_clipboard_finish (view, res, NULL);
+    if (clip != NULL)
     {
+        view_uri = nautilus_files_view_get_backing_uri (view);
         paste_clipboard_data (view, clip, view_uri);
     }
-
-    g_free (view_uri);
-
-    g_object_unref (view);
 }
 
 static void
 paste_files (NautilusFilesView *view)
 {
-    GdkClipboard *clipboard;
-
-    clipboard = gtk_widget_get_clipboard (GTK_WIDGET (view));
-
-    /* Performing an async request of clipboard contents, corresponding unref
-     * is in the callback.
-     */
-    g_object_ref (view);
-
-    gdk_clipboard_read_value_async (clipboard,
-                                    NAUTILUS_TYPE_CLIPBOARD,
-                                    G_PRIORITY_DEFAULT,
-                                    NULL,
-                                    paste_clipboard_received_callback,
-                                    view);
+    nautilus_files_view_get_clipboard_async (view,
+                                             paste_clipboard_received_callback,
+                                             NULL);
 }
 
 static void
@@ -2738,34 +2768,16 @@ create_links_clipboard_received_callback (GObject      *source_object,
                                           GAsyncResult *res,
                                           gpointer      user_data)
 {
-    GdkClipboard *clipboard = GDK_CLIPBOARD (source_object);
-    NautilusFilesView *view;
-    NautilusFilesViewPrivate *priv;
-    const GValue *value;
+    NautilusFilesView *view = NAUTILUS_FILES_VIEW (source_object);
     NautilusClipboard *clip;
-    char *view_uri;
+    g_autofree char *view_uri = NULL;
 
-    view = NAUTILUS_FILES_VIEW (user_data);
-    priv = nautilus_files_view_get_instance_private (view);
-
-    value = gdk_clipboard_read_value_finish (clipboard, res, NULL);
-    if (!G_VALUE_HOLDS (value, NAUTILUS_TYPE_CLIPBOARD))
-    {
-        g_object_unref (view);
-        return;
-    }
-    clip = g_value_get_boxed (value);
-
-    view_uri = nautilus_files_view_get_backing_uri (view);
-
-    if (priv->slot != NULL)
+    clip = nautilus_files_view_get_clipboard_finish (view, res, NULL);
+    if (clip != NULL)
     {
+        view_uri = nautilus_files_view_get_backing_uri (view);
         handle_clipboard_data (view, clip, view_uri, GDK_ACTION_LINK);
     }
-
-    g_free (view_uri);
-
-    g_object_unref (view);
 }
 
 static void
@@ -2773,19 +2785,11 @@ action_create_links (GSimpleAction *action,
                      GVariant      *state,
                      gpointer       user_data)
 {
-    NautilusFilesView *view;
-
     g_assert (NAUTILUS_IS_FILES_VIEW (user_data));
 
-    view = NAUTILUS_FILES_VIEW (user_data);
-
-    g_object_ref (view);
-    gdk_clipboard_read_value_async (gtk_widget_get_clipboard (GTK_WIDGET (view)),
-                                    NAUTILUS_TYPE_CLIPBOARD,
-                                    G_PRIORITY_DEFAULT,
-                                    NULL,
-                                    create_links_clipboard_received_callback,
-                                    view);
+    nautilus_files_view_get_clipboard_async (NAUTILUS_FILES_VIEW (user_data),
+                                             create_links_clipboard_received_callback,
+                                             NULL);
 }
 
 static void
@@ -3282,6 +3286,7 @@ nautilus_files_view_dispose (GObject *object)
 
     clipboard = gdk_display_get_clipboard (gdk_display_get_default ());
     g_signal_handlers_disconnect_by_func (clipboard, on_clipboard_owner_changed, view);
+    g_cancellable_cancel (priv->clipboard_cancellable);
 
     nautilus_file_unref (priv->directory_as_file);
     priv->directory_as_file = NULL;
@@ -3319,6 +3324,8 @@ nautilus_files_view_finalize (GObject *object)
     g_hash_table_destroy (priv->non_ready_files);
     g_hash_table_destroy (priv->pending_reveal);
 
+    g_clear_object (&priv->clipboard_cancellable);
+
     g_cancellable_cancel (priv->starred_cancellable);
     g_clear_object (&priv->starred_cancellable);
     g_clear_object (&priv->tag_manager);
@@ -6034,72 +6041,32 @@ action_move_to (GSimpleAction *action,
     copy_or_move_selection (view, TRUE);
 }
 
-typedef struct
-{
-    NautilusFilesView *view;
-    NautilusFile *target;
-} PasteIntoData;
-
 static void
 paste_into_clipboard_received_callback (GObject      *source_object,
                                         GAsyncResult *res,
                                         gpointer      user_data)
 {
-    GdkClipboard *clipboard = GDK_CLIPBOARD (source_object);
-    NautilusFilesViewPrivate *priv;
-    PasteIntoData *data;
-    NautilusFilesView *view;
-    const GValue *value;
+    NautilusFilesView *view = NAUTILUS_FILES_VIEW (source_object);
     NautilusClipboard *clip;
-    char *directory_uri;
+    g_autofree char *directory_uri = user_data;
 
-    data = (PasteIntoData *) user_data;
-
-    view = NAUTILUS_FILES_VIEW (data->view);
-    priv = nautilus_files_view_get_instance_private (view);
-
-    value = gdk_clipboard_read_value_finish (clipboard, res, NULL);
-    if (!G_VALUE_HOLDS (value, NAUTILUS_TYPE_CLIPBOARD))
+    clip = nautilus_files_view_get_clipboard_finish (view, res, NULL);
+    if (clip != NULL)
     {
-        g_object_unref (view);
-        return;
-    }
-    clip = g_value_get_boxed (value);
-
-    if (priv->slot != NULL)
-    {
-        directory_uri = nautilus_file_get_activation_uri (data->target);
-
         paste_clipboard_data (view, clip, directory_uri);
-
-        g_free (directory_uri);
     }
-
-    g_object_unref (view);
-    nautilus_file_unref (data->target);
-    g_free (data);
 }
 
 static void
 paste_into (NautilusFilesView *view,
             NautilusFile      *target)
 {
-    PasteIntoData *data;
-
     g_assert (NAUTILUS_IS_FILES_VIEW (view));
     g_assert (NAUTILUS_IS_FILE (target));
 
-    data = g_new (PasteIntoData, 1);
-
-    data->view = g_object_ref (view);
-    data->target = nautilus_file_ref (target);
-
-    gdk_clipboard_read_value_async (gtk_widget_get_clipboard (GTK_WIDGET (view)),
-                                    NAUTILUS_TYPE_CLIPBOARD,
-                                    G_PRIORITY_DEFAULT,
-                                    NULL,
-                                    paste_into_clipboard_received_callback,
-                                    data);
+    nautilus_files_view_get_clipboard_async (view,
+                                             paste_into_clipboard_received_callback,
+                                             nautilus_file_get_activation_uri (target));
 }
 
 static void
@@ -7123,10 +7090,8 @@ update_actions_clipboard_contents_received (GObject      *source_object,
                                             GAsyncResult *res,
                                             gpointer      user_data)
 {
-    GdkClipboard *clipboard = GDK_CLIPBOARD (source_object);
-    NautilusFilesViewPrivate *priv;
-    NautilusFilesView *view;
-    const GValue *value;
+    NautilusFilesView *view = NAUTILUS_FILES_VIEW (source_object);
+    NautilusFilesViewPrivate *priv = nautilus_files_view_get_instance_private (view);
     NautilusClipboard *clip;
     gboolean can_link_from_copied_files;
     gboolean settings_show_create_link;
@@ -7135,22 +7100,12 @@ update_actions_clipboard_contents_received (GObject      *source_object,
     gboolean selection_contains_starred;
     GAction *action;
 
-    view = NAUTILUS_FILES_VIEW (user_data);
-    priv = nautilus_files_view_get_instance_private (view);
-
-    value = gdk_clipboard_read_value_finish (clipboard, res, NULL);
-    if (!G_VALUE_HOLDS (value, NAUTILUS_TYPE_CLIPBOARD))
-    {
-        g_object_unref (view);
-        return;
-    }
-    clip = g_value_get_boxed (value);
+    clip = nautilus_files_view_get_clipboard_finish (view, res, NULL);
 
     if (priv->in_destruction ||
         !priv->active)
     {
         /* We've been destroyed or became inactive since call */
-        g_object_unref (view);
         return;
     }
 
@@ -7168,8 +7123,6 @@ update_actions_clipboard_contents_received (GObject      *source_object,
     g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
                                  can_link_from_copied_files &&
                                  settings_show_create_link);
-
-    g_object_unref (view);
 }
 
 static void
@@ -7764,14 +7717,9 @@ real_update_actions_state (NautilusFilesView *view)
     /* Actions that are related to the clipboard need request, request the data
      * and update them once we have the data */
     update_actions_state_for_clipboard_targets (view);
-
-    g_object_ref (view);     /* Need to keep the object alive until we get the reply */
-    gdk_clipboard_read_value_async (gtk_widget_get_clipboard (GTK_WIDGET (view)),
-                                    NAUTILUS_TYPE_CLIPBOARD,
-                                    G_PRIORITY_DEFAULT,
-                                    NULL,
-                                    update_actions_clipboard_contents_received,
-                                    view);
+    nautilus_files_view_get_clipboard_async (view,
+                                             update_actions_clipboard_contents_received,
+                                             NULL);
 
     action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
                                          "select-all");
diff --git a/src/nautilus-files-view.h b/src/nautilus-files-view.h
index 9bbd61962..e9b6841c9 100644
--- a/src/nautilus-files-view.h
+++ b/src/nautilus-files-view.h
@@ -293,6 +293,14 @@ void              nautilus_files_view_new_file_with_initial_contents (NautilusFi
                                                                       const char         *initial_contents,
                                                                       int                 length);
 
+/* clipboard reading */
+void               nautilus_files_view_get_clipboard_async  (NautilusFilesView   *self,
+                                                             GAsyncReadyCallback  callback,
+                                                             gpointer             callback_data);
+NautilusClipboard *nautilus_files_view_get_clipboard_finish (NautilusFilesView  *self,
+                                                             GAsyncResult       *result,
+                                                             GError            **error);
+
 /* selection handling */
 void              nautilus_files_view_activate_selection         (NautilusFilesView      *view);
 void              nautilus_files_view_preview_selection_event    (NautilusFilesView      *view,


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