summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2015-06-26 19:00:48 +0200
committerCarlos Garnacho <carlosg@gnome.org>2015-06-29 18:43:51 +0200
commitfd3e02c7c2e6263a82939ea12b50599c20e898b0 (patch)
tree841ccdd191d1392f922b0bad9b29306fc1f4d4bf
parent86c18a807acd3a9b5724017f7bf36f1b81f7060e (diff)
downloadgtk+-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.c27
-rw-r--r--gdk/wayland/gdkwaylandselection.h5
-rw-r--r--gtk/gtkdnd.c5
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
}
/**