diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2015-06-26 19:00:48 +0200 |
---|---|---|
committer | Carlos Garnacho <carlosg@gnome.org> | 2015-06-29 18:43:51 +0200 |
commit | fd3e02c7c2e6263a82939ea12b50599c20e898b0 (patch) | |
tree | 841ccdd191d1392f922b0bad9b29306fc1f4d4bf | |
parent | 86c18a807acd3a9b5724017f7bf36f1b81f7060e (diff) | |
download | gtk+-wip/wayland-dnd-actions.tar.gz |
wayland: Apply GdkDragContext::status action in a delayed mannerwip/wayland-dnd-actions
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".
-rw-r--r-- | gdk/wayland/gdkdnd-wayland.c | 27 | ||||
-rw-r--r-- | gdk/wayland/gdkwaylandselection.h | 5 | ||||
-rw-r--r-- | 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 82e426518a..ff948b661d 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 d201e61cc9..fef9ac48e6 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 5777fe4da9..c5483a1a5c 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 } /** |