[nautilus/wip/corey/selection-performance: 18/26] files-view: Introduce more linear clipboard code




commit 38762b3cafa993fbbea183bbebe78b80563f6d17
Author: Corey Berla <corey berla me>
Date:   Tue Sep 20 11:21:45 2022 -0700

    files-view: Introduce more linear clipboard code

 src/nautilus-files-view.c | 82 ++++++++++++++++++++++++++++++++++++++++++++---
 src/nautilus-list-base.c  | 25 +++++++++++++++
 2 files changed, 103 insertions(+), 4 deletions(-)
---
diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c
index c2e1feeec..7b815f0a5 100644
--- a/src/nautilus-files-view.c
+++ b/src/nautilus-files-view.c
@@ -2729,8 +2729,58 @@ handle_clipboard_data (NautilusFilesView *view,
 }
 
 static void
-paste_files (NautilusFilesView *view)
+paste_value_received_callback (GObject      *source_object,
+                               GAsyncResult *result,
+                               gpointer      user_data)
 {
+    GdkClipboard *clipboard;
+    const GValue *value;
+    PasteCallbackData *data = user_data;
+    g_autoptr (GError) error = NULL;
+
+    clipboard = GDK_CLIPBOARD (source_object);
+
+    value = gdk_clipboard_read_value_finish (clipboard, result, &error);
+
+    if (G_VALUE_HOLDS (value, NAUTILUS_TYPE_CLIPBOARD))
+    {
+        NautilusClipboard *clip = g_value_get_boxed (value);
+        if (data->action == 0)
+        {
+            data->action = nautilus_clipboard_is_cut (clip) ? GDK_ACTION_MOVE : GDK_ACTION_COPY;
+        }
+        handle_clipboard_data (data->view, clip, data->dest_uri, data->action);
+    }
+
+    paste_callback_data_free (data);
+}
+
+static void
+paste_files (NautilusFilesView *view,
+             PasteCallbackData *data)
+{
+    GdkClipboard *clipboard;
+    GdkContentFormats *formats;
+    NautilusFilesViewPrivate *priv = nautilus_files_view_get_instance_private (view);
+
+    clipboard = gtk_widget_get_clipboard (GTK_WIDGET (view));
+    formats = gdk_clipboard_get_formats (clipboard);
+
+    if (priv->clipboard_cancellable == NULL)
+    {
+        priv->clipboard_cancellable = g_cancellable_new ();
+    }
+
+    if (data == NULL)
+    {
+        data = paste_callback_data_new (view, NULL, 0);
+        data->view = view;
+    }
+
+    if (gdk_content_formats_contain_gtype (formats, NAUTILUS_TYPE_CLIPBOARD))
+    {
+        gdk_clipboard_read_value_async (clipboard, NAUTILUS_TYPE_CLIPBOARD, 0, priv->clipboard_cancellable, 
paste_value_received_callback, data);
+    }
 }
 
 static void
@@ -2742,7 +2792,7 @@ action_paste_files (GSimpleAction *action,
 
     view = NAUTILUS_FILES_VIEW (user_data);
 
-    paste_files (view);
+    paste_files (view, NULL);
 }
 
 static void
@@ -2763,7 +2813,7 @@ action_paste_files_accel (GSimpleAction *action,
     }
     else
     {
-        paste_files (view);
+        paste_files (view, NULL);
     }
 }
 
@@ -2772,8 +2822,13 @@ action_create_links (GSimpleAction *action,
                      GVariant      *state,
                      gpointer       user_data)
 {
+    PasteCallbackData *data;
+    NautilusFilesView *view = user_data;
     g_assert (NAUTILUS_IS_FILES_VIEW (user_data));
 
+    data = paste_callback_data_new (view, NULL, GDK_ACTION_LINK);
+
+    paste_files (view, data);
 }
 
 static void
@@ -6061,6 +6116,9 @@ action_paste_files_into (GSimpleAction *action,
     selection = nautilus_view_get_selection (NAUTILUS_VIEW (view));
     if (selection != NULL)
     {
+        PasteCallbackData *data;
+        data = paste_callback_data_new (view, nautilus_file_get_activation_uri (selection->data), 0);
+        paste_files (view, data);
     }
 }
 
@@ -7080,15 +7138,23 @@ update_actions_clipboard_contents_received (GObject      *source_object,
                                             GAsyncResult *res,
                                             gpointer      user_data)
 {
+    NautilusFilesView *view = NAUTILUS_FILES_VIEW (user_data);
     NautilusFilesViewPrivate *priv = nautilus_files_view_get_instance_private (view);
-    NautilusClipboard *clip;
+    NautilusClipboard *clip = NULL;
     gboolean can_link_from_copied_files;
     gboolean settings_show_create_link;
     gboolean is_read_only;
     gboolean selection_contains_recent;
     gboolean selection_contains_starred;
     GAction *action;
+    const GValue *value;
 
+    value = gdk_clipboard_read_value_finish (GDK_CLIPBOARD (source_object), res, NULL);
+
+    if (value != NULL && G_VALUE_HOLDS (value, NAUTILUS_TYPE_CLIPBOARD))
+    {
+        clip = g_value_get_boxed (value);
+    }
 
     if (priv->in_destruction ||
         !priv->active)
@@ -7150,6 +7216,14 @@ update_actions_state_for_clipboard_targets (NautilusFilesView *view)
 
     g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
                                  is_data_copied && g_action_get_enabled (action));
+
+    if (gdk_content_formats_contain_gtype (formats, NAUTILUS_TYPE_CLIPBOARD))
+    {
+        gdk_clipboard_read_value_async (clipboard, NAUTILUS_TYPE_CLIPBOARD, 0,
+                                        priv->clipboard_cancellable,
+                                        update_actions_clipboard_contents_received,
+                                        view);
+    }
 }
 
 static void
diff --git a/src/nautilus-list-base.c b/src/nautilus-list-base.c
index 58948a2ab..014e88a8a 100644
--- a/src/nautilus-list-base.c
+++ b/src/nautilus-list-base.c
@@ -1328,10 +1328,14 @@ on_clipboard_contents_received (GObject      *source_object,
                                 GAsyncResult *res,
                                 gpointer      user_data)
 {
+    NautilusFilesView *files_view = NAUTILUS_FILES_VIEW (user_data);
     NautilusListBase *self = NAUTILUS_LIST_BASE (files_view);
     NautilusListBasePrivate *priv = nautilus_list_base_get_instance_private (self);
     NautilusClipboard *clip;
     NautilusViewItem *item;
+    const GValue *value;
+
+    value = gdk_clipboard_read_value_finish (GDK_CLIPBOARD (source_object), res, NULL);
 
     for (GList *l = priv->cut_files; l != NULL; l = l->next)
     {
@@ -1343,6 +1347,15 @@ on_clipboard_contents_received (GObject      *source_object,
     }
     g_clear_list (&priv->cut_files, g_object_unref);
 
+    if (value != NULL && G_VALUE_HOLDS (value, NAUTILUS_TYPE_CLIPBOARD))
+    {
+        clip = g_value_get_boxed (value);
+    }
+    else
+    {
+        return;
+    }
+
     if (clip != NULL && nautilus_clipboard_is_cut (clip))
     {
         priv->cut_files = g_list_copy_deep (nautilus_clipboard_peek_files (clip),
@@ -1363,6 +1376,18 @@ on_clipboard_contents_received (GObject      *source_object,
 static void
 update_clipboard_status (NautilusFilesView *view)
 {
+    GdkClipboard *clipboard;
+    GdkContentFormats *formats;
+
+    clipboard = gtk_widget_get_clipboard (GTK_WIDGET (view));
+    formats = gdk_clipboard_get_formats (clipboard);
+
+    if (gdk_content_formats_contain_gtype (formats, NAUTILUS_TYPE_CLIPBOARD))
+    {
+        gdk_clipboard_read_value_async (clipboard, NAUTILUS_TYPE_CLIPBOARD, 0, NULL,
+                                        on_clipboard_contents_received,
+                                        view);
+    }
 }
 
 static void


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