[nautilus] window-slot-dnd: Reenable pathbar and tabs as drop targets



commit 938d4f8d353a878f47383e94ec335f1fc374d70d
Author: Corey Berla <corey berla me>
Date:   Thu Jun 16 08:11:56 2022 -0700

    window-slot-dnd: Reenable pathbar and tabs as drop targets
    
    Keep existing code with modifications for GtkDropTarget.
    Eventually there should be further cleanup but this works for now.

 src/nautilus-dnd.h             |   4 +-
 src/nautilus-notebook.c        |   4 +-
 src/nautilus-pathbar.c         |   2 -
 src/nautilus-window-slot-dnd.c | 303 +++++++----------------------------------
 src/nautilus-window-slot-dnd.h |   2 -
 5 files changed, 50 insertions(+), 265 deletions(-)
---
diff --git a/src/nautilus-dnd.h b/src/nautilus-dnd.h
index 069256cfb..2c45a0ec1 100644
--- a/src/nautilus-dnd.h
+++ b/src/nautilus-dnd.h
@@ -27,10 +27,10 @@
 #include <gtk/gtk.h>
 #include "nautilus-file.h"
 
-#if 0 && NAUTILUS_DND_NEEDS_GTK4_REIMPLEMENTATION
-
 #define HOVER_TIMEOUT 500
 
+#if 0 && NAUTILUS_DND_NEEDS_GTK4_REIMPLEMENTATION
+
 /* Drag & Drop target names. */
 #define NAUTILUS_ICON_DND_GNOME_ICON_LIST_TYPE "x-special/gnome-icon-list"
 #define NAUTILUS_ICON_DND_URI_LIST_TYPE                "text/uri-list"
diff --git a/src/nautilus-notebook.c b/src/nautilus-notebook.c
index 504ea5caa..9713b545b 100644
--- a/src/nautilus-notebook.c
+++ b/src/nautilus-notebook.c
@@ -289,9 +289,7 @@ build_tab_label (GtkNotebook        *notebook,
     gtk_widget_show (close_button);
 
     g_object_set_data (G_OBJECT (tab_label), "nautilus-notebook-tab", GINT_TO_POINTER (1));
-#if 0 && NAUTILUS_DND_NEEDS_GTK4_REIMPLEMENTATION
-    nautilus_drag_slot_proxy_init (box, NULL, slot);
-#endif
+    nautilus_drag_slot_proxy_init (tab_label, NULL, slot);
 
     g_object_set_data (G_OBJECT (tab_label), "label", label);
     g_object_set_data (G_OBJECT (tab_label), "spinner", spinner);
diff --git a/src/nautilus-pathbar.c b/src/nautilus-pathbar.c
index 1b5671b09..f43ccaf5f 100644
--- a/src/nautilus-pathbar.c
+++ b/src/nautilus-pathbar.c
@@ -1118,9 +1118,7 @@ make_button_data (NautilusPathBar *self,
     g_signal_connect (controller, "pressed",
                       G_CALLBACK (on_click_gesture_pressed), button_data);
 
-#if 0 && NAUTILUS_DND_NEEDS_GTK4_REIMPLEMENTATION
     nautilus_drag_slot_proxy_init (button_data->button, button_data->file, NULL);
-#endif
 
     g_object_unref (path);
 
diff --git a/src/nautilus-window-slot-dnd.c b/src/nautilus-window-slot-dnd.c
index ccec73b60..3d929a3f3 100644
--- a/src/nautilus-window-slot-dnd.c
+++ b/src/nautilus-window-slot-dnd.c
@@ -23,7 +23,6 @@
  *      Ettore Perazzoli <ettore gnu org>
  */
 
-#if 0 && NAUTILUS_DND_NEEDS_GTK4_REIMPLEMENTATION
 #include <config.h>
 
 #include "nautilus-notebook.h"
@@ -33,19 +32,6 @@
 
 typedef struct
 {
-    gboolean have_data;
-    gboolean have_valid_data;
-
-    gboolean drop_occurred;
-
-    unsigned int info;
-    union
-    {
-        GList *selection_list;
-        GList *uri_list;
-        GtkSelectionData *selection_data;
-    } data;
-
     NautilusFile *target_file;
     NautilusWindowSlot *target_slot;
     GtkWidget *widget;
@@ -120,8 +106,7 @@ slot_proxy_switch_location_timer (gpointer user_data)
 }
 
 static void
-slot_proxy_check_switch_location_timer (NautilusDragSlotProxyInfo *drag_info,
-                                        GtkWidget                 *widget)
+slot_proxy_check_switch_location_timer (NautilusDragSlotProxyInfo *drag_info)
 {
     if (drag_info->switch_location_timer)
     {
@@ -143,50 +128,33 @@ slot_proxy_remove_switch_location_timer (NautilusDragSlotProxyInfo *drag_info)
     }
 }
 
-static gboolean
-slot_proxy_drag_motion (GtkWidget      *widget,
-                        GdkDragContext *context,
-                        int             x,
-                        int             y,
-                        unsigned int    time,
-                        gpointer        user_data)
+static GdkDragAction
+slot_proxy_drag_motion (GtkDropTarget *target,
+                        gdouble        x,
+                        gdouble        y,
+                        gpointer       user_data)
 {
     NautilusDragSlotProxyInfo *drag_info;
     NautilusWindowSlot *target_slot;
     GtkRoot *window;
-    GdkAtom target;
-    int action;
+    GdkDragAction action;
     char *target_uri;
     GFile *location;
-    gboolean valid_text_drag;
-    gboolean valid_xds_drag;
+    const GValue *value;
 
     drag_info = user_data;
 
     action = 0;
-    valid_text_drag = FALSE;
-    valid_xds_drag = FALSE;
 
-    if (gtk_drag_get_source_widget (context) == widget)
+    value = gtk_drop_target_get_value (target);
+    if (value == NULL)
     {
-        goto out;
+        return 0;
     }
 
-    window = gtk_widget_get_root (widget);
+    window = gtk_widget_get_root (drag_info->widget);
     g_assert (NAUTILUS_IS_WINDOW (window));
 
-    if (!drag_info->have_data)
-    {
-        target = gtk_drag_dest_find_target (widget, context, NULL);
-
-        if (target == GDK_NONE)
-        {
-            goto out;
-        }
-
-        gtk_drag_get_data (widget, context, target, time);
-    }
-
     target_uri = NULL;
     if (drag_info->target_file != NULL)
     {
@@ -227,48 +195,18 @@ slot_proxy_drag_motion (GtkWidget      *widget,
         }
     }
 
-    if (drag_info->have_data &&
-        drag_info->have_valid_data)
+    if (G_VALUE_HOLDS (value, GDK_TYPE_FILE_LIST))
     {
-        if (drag_info->info == NAUTILUS_ICON_DND_GNOME_ICON_LIST)
-        {
-            nautilus_drag_default_drop_action_for_icons (context, target_uri,
-                                                         drag_info->data.selection_list,
-                                                         0,
-                                                         &action);
-        }
-        else if (drag_info->info == NAUTILUS_ICON_DND_URI_LIST)
-        {
-            action = nautilus_drag_default_drop_action_for_uri_list (context, target_uri);
-        }
-        else if (drag_info->info == NAUTILUS_ICON_DND_TEXT)
-        {
-            valid_text_drag = TRUE;
-        }
-        else if (drag_info->info == NAUTILUS_ICON_DND_XDNDDIRECTSAVE ||
-                 drag_info->info == NAUTILUS_ICON_DND_RAW)
-        {
-            valid_xds_drag = TRUE;
-        }
+        GSList *items = g_value_get_boxed (value);
+        action = nautilus_dnd_get_prefered_action (drag_info->target_file, items->data);
     }
 
     g_free (target_uri);
 
 out:
-    if (action != 0 || valid_text_drag || valid_xds_drag)
-    {
-        gtk_drag_highlight (widget);
-        slot_proxy_check_switch_location_timer (drag_info, widget);
-    }
-    else
-    {
-        gtk_drag_unhighlight (widget);
-        slot_proxy_remove_switch_location_timer (drag_info);
-    }
-
-    gdk_drag_status (context, action, time);
+    slot_proxy_check_switch_location_timer (drag_info);
 
-    return TRUE;
+    return action;
 }
 
 static void
@@ -286,96 +224,37 @@ static void
 drag_info_clear (NautilusDragSlotProxyInfo *drag_info)
 {
     slot_proxy_remove_switch_location_timer (drag_info);
-
-    if (!drag_info->have_data)
-    {
-        goto out;
-    }
-
-    if (drag_info->info == NAUTILUS_ICON_DND_GNOME_ICON_LIST)
-    {
-        nautilus_drag_destroy_selection_list (drag_info->data.selection_list);
-    }
-    else if (drag_info->info == NAUTILUS_ICON_DND_URI_LIST)
-    {
-        g_list_free (drag_info->data.uri_list);
-    }
-    else if (drag_info->info == NAUTILUS_ICON_DND_TEXT ||
-             drag_info->info == NAUTILUS_ICON_DND_XDNDDIRECTSAVE ||
-             drag_info->info == NAUTILUS_ICON_DND_RAW)
-    {
-        if (drag_info->data.selection_data != NULL)
-        {
-            gtk_selection_data_free (drag_info->data.selection_data);
-        }
-    }
-
-out:
-    drag_info->have_data = FALSE;
-    drag_info->have_valid_data = FALSE;
-
-    drag_info->drop_occurred = FALSE;
 }
 
 static void
-slot_proxy_drag_leave (GtkWidget      *widget,
-                       GdkDragContext *context,
-                       unsigned int    time,
-                       gpointer        user_data)
+slot_proxy_drag_leave (GtkDropTarget *target,
+                       gpointer       user_data)
 {
     NautilusDragSlotProxyInfo *drag_info;
 
     drag_info = user_data;
 
-    gtk_drag_unhighlight (widget);
     drag_info_clear (drag_info);
 }
 
-static gboolean
-slot_proxy_drag_drop (GtkWidget      *widget,
-                      GdkDragContext *context,
-                      int             x,
-                      int             y,
-                      unsigned int    time,
-                      gpointer        user_data)
-{
-    GdkAtom target;
-    NautilusDragSlotProxyInfo *drag_info;
-
-    drag_info = user_data;
-    g_assert (!drag_info->have_data);
-
-    drag_info->drop_occurred = TRUE;
-
-    target = gtk_drag_dest_find_target (widget, context, NULL);
-    gtk_drag_get_data (widget, context, target, time);
-
-    return TRUE;
-}
-
-
 static void
-slot_proxy_handle_drop (GtkWidget                 *widget,
-                        GdkDragContext            *context,
-                        unsigned int               time,
-                        NautilusDragSlotProxyInfo *drag_info)
+slot_proxy_handle_drop (GtkDropTarget *target,
+                        const GValue  *value,
+                        gdouble        x,
+                        gdouble        y,
+                        gpointer       user_data)
 {
     GtkRoot *window;
     NautilusWindowSlot *target_slot;
     NautilusFilesView *target_view;
     char *target_uri;
-    GList *uri_list;
+    GList *uri_list = NULL;
     GFile *location;
+    NautilusDragSlotProxyInfo *drag_info;
 
-    if (!drag_info->have_data ||
-        !drag_info->have_valid_data)
-    {
-        gtk_drag_finish (context, FALSE, FALSE, time);
-        drag_info_clear (drag_info);
-        return;
-    }
+    drag_info = user_data;
 
-    window = gtk_widget_get_root (widget);
+    window = gtk_widget_get_root (drag_info->widget);
     g_assert (NAUTILUS_IS_WINDOW (window));
 
     if (drag_info->target_slot != NULL)
@@ -413,105 +292,33 @@ slot_proxy_handle_drop (GtkWidget                 *widget,
 
     if (target_slot != NULL && target_view != NULL)
     {
-        if (drag_info->info == NAUTILUS_ICON_DND_GNOME_ICON_LIST)
+        if (G_VALUE_HOLDS (value, GDK_TYPE_FILE_LIST))
         {
-            uri_list = nautilus_drag_uri_list_from_selection_list (drag_info->data.selection_list);
-            g_assert (uri_list != NULL);
+            GSList *items = g_value_get_boxed (value);
+            for (GSList *l = items; l != NULL; l = l->next)
+            {
+                uri_list = g_list_prepend (uri_list, g_file_get_uri (l->data));
+            }
 
             nautilus_files_view_drop_proxy_received_uris (target_view,
                                                           uri_list,
                                                           target_uri,
-                                                          gdk_drag_context_get_selected_action (context));
+                                                          gdk_drop_get_actions 
(gtk_drop_target_get_current_drop (target)));
             g_list_free_full (uri_list, g_free);
         }
-        else if (drag_info->info == NAUTILUS_ICON_DND_URI_LIST)
-        {
-            nautilus_files_view_drop_proxy_received_uris (target_view,
-                                                          drag_info->data.uri_list,
-                                                          target_uri,
-                                                          gdk_drag_context_get_selected_action (context));
-        }
-
-        gtk_drag_finish (context, TRUE, FALSE, time);
-    }
-    else
-    {
-        gtk_drag_finish (context, FALSE, FALSE, time);
     }
-
     g_free (target_uri);
 
     drag_info_clear (drag_info);
 }
 
-static void
-slot_proxy_drag_data_received (GtkWidget        *widget,
-                               GdkDragContext   *context,
-                               int               x,
-                               int               y,
-                               GtkSelectionData *data,
-                               unsigned int      info,
-                               unsigned int      time,
-                               gpointer          user_data)
-{
-    NautilusDragSlotProxyInfo *drag_info;
-    char **uris;
-
-    drag_info = user_data;
-
-    g_assert (!drag_info->have_data);
-
-    drag_info->have_data = TRUE;
-    drag_info->info = info;
-
-    if (gtk_selection_data_get_length (data) < 0)
-    {
-        drag_info->have_valid_data = FALSE;
-        return;
-    }
-
-    if (info == NAUTILUS_ICON_DND_GNOME_ICON_LIST)
-    {
-        drag_info->data.selection_list = nautilus_drag_build_selection_list (data);
-
-        drag_info->have_valid_data = drag_info->data.selection_list != NULL;
-    }
-    else if (info == NAUTILUS_ICON_DND_URI_LIST)
-    {
-        uris = gtk_selection_data_get_uris (data);
-        drag_info->data.uri_list = nautilus_drag_uri_list_from_array ((const char **) uris);
-        g_strfreev (uris);
-
-        drag_info->have_valid_data = drag_info->data.uri_list != NULL;
-    }
-    else if (info == NAUTILUS_ICON_DND_TEXT ||
-             info == NAUTILUS_ICON_DND_XDNDDIRECTSAVE ||
-             info == NAUTILUS_ICON_DND_RAW)
-    {
-        drag_info->data.selection_data = gtk_selection_data_copy (data);
-        drag_info->have_valid_data = drag_info->data.selection_data != NULL;
-    }
-
-    if (drag_info->drop_occurred)
-    {
-        slot_proxy_handle_drop (widget, context, time, drag_info);
-    }
-}
-
 void
 nautilus_drag_slot_proxy_init (GtkWidget          *widget,
                                NautilusFile       *target_file,
                                NautilusWindowSlot *target_slot)
 {
     NautilusDragSlotProxyInfo *drag_info;
-
-    const GtkTargetEntry targets[] =
-    {
-        { NAUTILUS_ICON_DND_GNOME_ICON_LIST_TYPE, 0, NAUTILUS_ICON_DND_GNOME_ICON_LIST },
-        { NAUTILUS_ICON_DND_XDNDDIRECTSAVE_TYPE, 0, NAUTILUS_ICON_DND_XDNDDIRECTSAVE }, /* XDS Protocol Type 
*/
-        { NAUTILUS_ICON_DND_RAW_TYPE, 0, NAUTILUS_ICON_DND_RAW }
-    };
-    GtkTargetList *target_list;
+    GtkDropTarget *target;
 
     g_assert (GTK_IS_WIDGET (widget));
 
@@ -533,31 +340,15 @@ nautilus_drag_slot_proxy_init (GtkWidget          *widget,
     }
 
     drag_info->widget = widget;
-
-    gtk_drag_dest_set (widget, 0,
-                       NULL, 0,
-                       GDK_ACTION_MOVE |
-                       GDK_ACTION_COPY |
-                       GDK_ACTION_LINK |
-                       GDK_ACTION_ASK);
-
-    target_list = gtk_target_list_new (targets, G_N_ELEMENTS (targets));
-    gtk_target_list_add_uri_targets (target_list, NAUTILUS_ICON_DND_URI_LIST);
-    gtk_target_list_add_text_targets (target_list, NAUTILUS_ICON_DND_TEXT);
-    gtk_drag_dest_set_target_list (widget, target_list);
-    gtk_target_list_unref (target_list);
-
-    g_signal_connect (widget, "drag-motion",
-                      G_CALLBACK (slot_proxy_drag_motion),
-                      drag_info);
-    g_signal_connect (widget, "drag-drop",
-                      G_CALLBACK (slot_proxy_drag_drop),
-                      drag_info);
-    g_signal_connect (widget, "drag-data-received",
-                      G_CALLBACK (slot_proxy_drag_data_received),
-                      drag_info);
-    g_signal_connect (widget, "drag-leave",
-                      G_CALLBACK (slot_proxy_drag_leave),
-                      drag_info);
+    /* TODO: Implement GDK_ACTION_ASK */
+    target = gtk_drop_target_new (G_TYPE_INVALID, GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK);
+
+    gtk_drop_target_set_preload (target, TRUE);
+    /* TODO: Implement GDK_TYPE_STRING */
+    gtk_drop_target_set_gtypes (target, (GType[1]) { GDK_TYPE_FILE_LIST }, 1);
+    g_signal_connect (target, "enter", G_CALLBACK (slot_proxy_drag_motion), drag_info);
+    g_signal_connect (target, "motion", G_CALLBACK (slot_proxy_drag_motion), drag_info);
+    g_signal_connect (target, "drop", G_CALLBACK (slot_proxy_handle_drop), drag_info);
+    g_signal_connect (target, "leave", G_CALLBACK (slot_proxy_drag_leave), drag_info);
+    gtk_widget_add_controller (widget, GTK_EVENT_CONTROLLER (target));
 }
-#endif
diff --git a/src/nautilus-window-slot-dnd.h b/src/nautilus-window-slot-dnd.h
index 0988dffb2..bd77969a9 100644
--- a/src/nautilus-window-slot-dnd.h
+++ b/src/nautilus-window-slot-dnd.h
@@ -25,7 +25,6 @@
 
 #pragma once
 
-#if 0 && NAUTILUS_DND_NEEDS_GTK4_REIMPLEMENTATION
 #include <gio/gio.h>
 #include <gtk/gtk.h>
 
@@ -36,4 +35,3 @@
 void nautilus_drag_slot_proxy_init (GtkWidget *widget,
                                     NautilusFile *target_file,
                                     NautilusWindowSlot *target_slot);
-#endif


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