[gtk+/wip/wayland-dnd-actions: 674/674] wayland: Apply GdkDragContext::status action in a delayed manner



commit fd3e02c7c2e6263a82939ea12b50599c20e898b0
Author: Carlos Garnacho <carlosg gnome org>
Date:   Fri Jun 26 19:00:48 2015 +0200

    wayland: Apply GdkDragContext::status action in a delayed manner
    
    In gtkdnd.c, the drag dest event handler will run through all, which may
    result in multiple gdk_drag_status() calls along the way if there's
    multiple widgets in the hierarchy doing DnD.
    
    This may make us a lot more verbose than desired, so let the wayland
    ::status handler only cache the result, and commit it after the DnD
    event handler traversed the whole tree.
    
    This could be seen on eog, both the window and inner widgets handle DnD,
    which result in the selected action ping-ponging between "none" and "copy".

 gdk/wayland/gdkdnd-wayland.c      |   27 ++++++++++++++++++++-------
 gdk/wayland/gdkwaylandselection.h |    5 +++++
 gtk/gtkdnd.c                      |    5 +++++
 3 files changed, 30 insertions(+), 7 deletions(-)
---
diff --git a/gdk/wayland/gdkdnd-wayland.c b/gdk/wayland/gdkdnd-wayland.c
index 82e4265..ff948b6 100644
--- a/gdk/wayland/gdkdnd-wayland.c
+++ b/gdk/wayland/gdkdnd-wayland.c
@@ -43,6 +43,7 @@ struct _GdkWaylandDragContext
   GdkWindow *dnd_window;
   struct wl_surface *dnd_surface;
   struct wl_data_source *data_source;
+  GdkDragAction selected_action;
   uint32_t serial;
   gdouble x;
   gdouble y;
@@ -253,15 +254,11 @@ gdk_wayland_drag_context_drag_status (GdkDragContext *context,
                                      GdkDragAction   action,
                                      guint32         time_)
 {
-  GdkDisplay *display;
-  uint32_t dnd_actions;
 
-  display = gdk_device_get_display (gdk_drag_context_get_device (context));
-
-  dnd_actions = gdk_to_wl_actions (action);
-  gdk_wayland_selection_set_current_offer_actions (display, dnd_actions);
+  GdkWaylandDragContext *wayland_context;
 
-  gdk_wayland_drop_context_set_status (context, action != 0);
+  wayland_context = GDK_WAYLAND_DRAG_CONTEXT (context);
+  wayland_context->selected_action = action;
 }
 
 static void
@@ -515,3 +512,19 @@ gdk_wayland_drag_context_get_dnd_window (GdkDragContext *context)
   wayland_context = GDK_WAYLAND_DRAG_CONTEXT (context);
   return wayland_context->dnd_window;
 }
+
+void
+gdk_wayland_drag_context_commit_status (GdkDragContext *context)
+{
+  GdkWaylandDragContext *wayland_context;
+  GdkDisplay *display;
+  uint32_t dnd_actions;
+
+  wayland_context = GDK_WAYLAND_DRAG_CONTEXT (context);
+  display = gdk_device_get_display (gdk_drag_context_get_device (context));
+
+  dnd_actions = gdk_to_wl_actions (wayland_context->selected_action);
+  gdk_wayland_selection_set_current_offer_actions (display, dnd_actions);
+
+  gdk_wayland_drop_context_set_status (context, wayland_context->selected_action != 0);
+}
diff --git a/gdk/wayland/gdkwaylandselection.h b/gdk/wayland/gdkwaylandselection.h
index d201e61..fef9ac4 100644
--- a/gdk/wayland/gdkwaylandselection.h
+++ b/gdk/wayland/gdkwaylandselection.h
@@ -52,6 +52,11 @@ GDK_AVAILABLE_IN_ALL
 GdkWindow *
 gdk_wayland_drag_context_get_dnd_window (GdkDragContext *context);
 
+#define gdk_wayland_drag_context_commit_status gdk_wayland_drag_context_commit_status_libgtk_only
+GDK_AVAILABLE_IN_ALL
+void
+gdk_wayland_drag_context_commit_status (GdkDragContext *context);
+
 #endif
 
 G_END_DECLS
diff --git a/gtk/gtkdnd.c b/gtk/gtkdnd.c
index 5777fe4..c5483a1 100644
--- a/gtk/gtkdnd.c
+++ b/gtk/gtkdnd.c
@@ -1715,6 +1715,11 @@ _gtk_drag_dest_handle_event (GtkWidget *toplevel,
     default:
       g_assert_not_reached ();
     }
+
+#ifdef GDK_WINDOWING_WAYLAND
+  if (GDK_IS_WAYLAND_DISPLAY (gtk_widget_get_display (toplevel)))
+    gdk_wayland_drag_context_commit_status (context);
+#endif
 }
 
 /**


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