[gtk/wip/otte/dnd: 1/9] gdk: Make gdk_drop_status() take preferred action



commit 7cd728a0ea3da812ea2b049cc79311a2349fd205
Author: Benjamin Otte <otte redhat com>
Date:   Sun Mar 1 18:50:15 2020 +0100

    gdk: Make gdk_drop_status() take preferred action
    
    This allows textview/text dnd to properly display a MOVE icon when in
    the widget the drag started from but a COPY icon otherwise.

 gdk/gdkdrop.c                 | 15 ++++++++++++---
 gdk/gdkdrop.h                 |  3 ++-
 gdk/gdkdropprivate.h          |  3 ++-
 gdk/wayland/gdkdrop-wayland.c | 20 +++++++-------------
 gdk/win32/gdkdrop-win32.c     |  8 +++++---
 gdk/x11/gdkdrop-x11.c         | 23 +++++++++++++++--------
 gtk/gtkdrop.c                 |  4 ++--
 7 files changed, 45 insertions(+), 31 deletions(-)
---
diff --git a/gdk/gdkdrop.c b/gdk/gdkdrop.c
index fd4169a29b..29c33f8ef5 100644
--- a/gdk/gdkdrop.c
+++ b/gdk/gdkdrop.c
@@ -75,7 +75,8 @@ G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdkDrop, gdk_drop, G_TYPE_OBJECT)
 
 static void
 gdk_drop_default_status (GdkDrop       *self,
-                         GdkDragAction  actions)
+                         GdkDragAction  actions,
+                         GdkDragAction  preferred)
 {
 }
 
@@ -545,6 +546,8 @@ gdk_drop_get_drag (GdkDrop *self)
  * @self: a #GdkDrop
  * @actions: Supported actions of the destination, or 0 to indicate
  *    that a drop will not be accepted
+ * @preferred: A unique action that's a member of @actions indicating the
+ *    preferred action.
  *
  * Selects all actions that are potentially supported by the destination.
  *
@@ -552,6 +555,9 @@ gdk_drop_get_drag (GdkDrop *self)
  * the ones provided by gdk_drop_get_actions(). Those actions may
  * change in the future, even depending on the actions you provide here.
  *
+ * The @preferred action is a hint to the drag'n'drop mechanism about which
+ * action to use when multiple actions are possible.
+ *
  * This function should be called by drag destinations in response to
  * %GDK_DRAG_ENTER or %GDK_DRAG_MOTION events. If the destination does
  * not yet know the exact actions it supports, it should set any possible
@@ -559,7 +565,8 @@ gdk_drop_get_drag (GdkDrop *self)
  */
 void
 gdk_drop_status (GdkDrop       *self,
-                 GdkDragAction  actions)
+                 GdkDragAction  actions,
+                 GdkDragAction  preferred)
 {
 #ifndef G_DISABLE_CHECKS
   GdkDropPrivate *priv = gdk_drop_get_instance_private (self);
@@ -567,8 +574,10 @@ gdk_drop_status (GdkDrop       *self,
 
   g_return_if_fail (GDK_IS_DROP (self));
   g_return_if_fail (priv->state != GDK_DROP_STATE_FINISHED);
+  g_return_if_fail (gdk_drag_action_is_unique (preferred));
+  g_return_if_fail ((preferred & actions) == preferred);
 
-  GDK_DROP_GET_CLASS (self)->status (self, actions);
+  GDK_DROP_GET_CLASS (self)->status (self, actions, preferred);
 }
 
 /**
diff --git a/gdk/gdkdrop.h b/gdk/gdkdrop.h
index 6e29864293..c1990b1d67 100644
--- a/gdk/gdkdrop.h
+++ b/gdk/gdkdrop.h
@@ -54,7 +54,8 @@ GdkDrag *               gdk_drop_get_drag               (GdkDrop
 
 GDK_AVAILABLE_IN_ALL
 void                    gdk_drop_status                 (GdkDrop                *self,
-                                                         GdkDragAction           actions);
+                                                         GdkDragAction           actions,
+                                                         GdkDragAction           preferred);
 GDK_AVAILABLE_IN_ALL
 void                    gdk_drop_finish                 (GdkDrop                *self,
                                                          GdkDragAction           action);
diff --git a/gdk/gdkdropprivate.h b/gdk/gdkdropprivate.h
index 82b5e41945..6dbf8a0acf 100644
--- a/gdk/gdkdropprivate.h
+++ b/gdk/gdkdropprivate.h
@@ -40,7 +40,8 @@ struct _GdkDropClass {
   GObjectClass parent_class;
 
   void                  (* status)                              (GdkDrop                *self,
-                                                                 GdkDragAction           actions);
+                                                                 GdkDragAction           actions,
+                                                                 GdkDragAction           preferred);
   void                  (* finish)                              (GdkDrop                *self,
                                                                  GdkDragAction           action);
 
diff --git a/gdk/wayland/gdkdrop-wayland.c b/gdk/wayland/gdkdrop-wayland.c
index 2af4379077..5d72b3fcf6 100644
--- a/gdk/wayland/gdkdrop-wayland.c
+++ b/gdk/wayland/gdkdrop-wayland.c
@@ -122,7 +122,8 @@ gdk_wayland_drop_drop_set_status (GdkWaylandDrop *drop_wayland,
 
 static void
 gdk_wayland_drop_commit_status (GdkWaylandDrop *wayland_drop,
-                                GdkDragAction   actions)
+                                GdkDragAction   actions,
+                                GdkDragAction   preferred)
 {
   GdkDisplay *display;
 
@@ -135,15 +136,7 @@ gdk_wayland_drop_commit_status (GdkWaylandDrop *wayland_drop,
       uint32_t preferred_action;
 
       dnd_actions = gdk_to_wl_actions (actions);
-
-      if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY)
-        preferred_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
-      else if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE)
-        preferred_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
-      else if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
-        preferred_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
-      else
-        preferred_action = 0;
+      preferred_action = gdk_to_wl_actions (preferred);
 
       wl_data_offer_set_actions (wayland_drop->offer, dnd_actions, preferred_action);
     }
@@ -153,11 +146,12 @@ gdk_wayland_drop_commit_status (GdkWaylandDrop *wayland_drop,
 
 static void
 gdk_wayland_drop_status (GdkDrop       *drop,
-                         GdkDragAction  actions)
+                         GdkDragAction  actions,
+                         GdkDragAction  preferred)
 {
   GdkWaylandDrop *wayland_drop = GDK_WAYLAND_DROP (drop);
 
-  gdk_wayland_drop_commit_status (wayland_drop, actions);
+  gdk_wayland_drop_commit_status (wayland_drop, actions, preferred);
 }
 
 static void
@@ -170,7 +164,7 @@ gdk_wayland_drop_finish (GdkDrop       *drop,
 
   if (action)
     {
-      gdk_wayland_drop_commit_status (wayland_drop, action);
+      gdk_wayland_drop_commit_status (wayland_drop, action, action);
 
       if (display_wayland->data_device_manager_version >=
           WL_DATA_OFFER_FINISH_SINCE_VERSION)
diff --git a/gdk/win32/gdkdrop-win32.c b/gdk/win32/gdkdrop-win32.c
index f7244f8f2e..ff6035dc4f 100644
--- a/gdk/win32/gdkdrop-win32.c
+++ b/gdk/win32/gdkdrop-win32.c
@@ -1059,7 +1059,8 @@ gdk_dropfiles_filter (GdkWin32Display *display,
 
 static void
 gdk_win32_drop_status (GdkDrop       *drop,
-                       GdkDragAction  actions)
+                       GdkDragAction  actions,
+                       GdkDragAction  preferred)
 {
   GdkWin32Drop *drop_win32 = GDK_WIN32_DROP (drop);
   GdkDrag *drag;
@@ -1067,10 +1068,11 @@ gdk_win32_drop_status (GdkDrop       *drop,
   g_return_if_fail (drop != NULL);
 
   GDK_NOTE (DND, g_print ("gdk_win32_drop_status: %s\n"
-                          " context=%p:{source_actions=%s}\n",
+                          " context=%p:{source_actions=%s, preferred=%s}\n",
                           _gdk_win32_drag_action_to_string (actions),
                           drop,
-                          _gdk_win32_drag_action_to_string (gdk_drop_get_actions (drop))));
+                          _gdk_win32_drag_action_to_string (gdk_drop_get_actions (drop)),
+                          _gdk_win32_drag_action_to_string (preferred)));
 
   drop_win32->actions = actions;
 
diff --git a/gdk/x11/gdkdrop-x11.c b/gdk/x11/gdkdrop-x11.c
index d5cce6a6e1..6043f52b26 100644
--- a/gdk/x11/gdkdrop-x11.c
+++ b/gdk/x11/gdkdrop-x11.c
@@ -719,7 +719,8 @@ gdk_x11_drop_do_nothing (Window   window,
 
 static void
 gdk_x11_drop_status (GdkDrop       *drop,
-                     GdkDragAction  actions)
+                     GdkDragAction  actions,
+                     GdkDragAction  preferred)
 {
   GdkX11Drop *drop_x11 = GDK_X11_DROP (drop);
   GdkDragAction possible_actions, suggested_action;
@@ -732,14 +733,20 @@ gdk_x11_drop_status (GdkDrop       *drop,
 
   if (drop_x11->suggested_action != 0)
     suggested_action = drop_x11->suggested_action;
-  else if (possible_actions & GDK_ACTION_COPY)
-    suggested_action = GDK_ACTION_COPY;
-  else if (possible_actions & GDK_ACTION_MOVE)
-    suggested_action = GDK_ACTION_MOVE;
-  else if (possible_actions & GDK_ACTION_ASK)
-    suggested_action = GDK_ACTION_ASK;
   else
-    suggested_action = 0;
+    suggested_action = preferred & possible_actions;
+
+  if (suggested_action == 0 && possible_actions != 0)
+    {
+      if (possible_actions & GDK_ACTION_COPY)
+        suggested_action = GDK_ACTION_COPY;
+      else if (possible_actions & GDK_ACTION_MOVE)
+        suggested_action = GDK_ACTION_MOVE;
+      else if (possible_actions & GDK_ACTION_ASK)
+        suggested_action = GDK_ACTION_ASK;
+      else
+        suggested_action = 0;
+    }
 
   xev.xclient.type = ClientMessage;
   xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "XdndStatus");
diff --git a/gtk/gtkdrop.c b/gtk/gtkdrop.c
index 7c4c834dbc..eac5995b1f 100644
--- a/gtk/gtkdrop.c
+++ b/gtk/gtkdrop.c
@@ -86,7 +86,7 @@ gtk_drop_end_event (GdkDrop *drop)
 
   if (self->waiting)
     {
-      gdk_drop_status (drop, 0);
+      gdk_drop_status (drop, 0, 0);
       self->waiting = FALSE;
     }
   self->active = FALSE;
@@ -106,7 +106,7 @@ gtk_drop_status (GdkDrop       *drop,
   if (!self->waiting)
     return FALSE;
 
-  gdk_drop_status (drop, actions);
+  gdk_drop_status (drop, actions, preferred_action);
   self->waiting = FALSE;
   return TRUE;
 }


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