From aad3135e4c30c977c80ba39a65f28623aa4c4592 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 15 Feb 2016 17:02:14 +0100 Subject: [PATCH] gdk: Add GdkDragCancelReason enum as argument to GdkDragContext::cancel We should conform to a minimal set of reasons for the gtk side to emit a better GtkDragResult than GTK_DRAG_RESULT_ERROR. This fixes the notebook tab DnD feature, where we rely on GTK_DRAG_RESULT_NO_TARGET. In the wayland side, unfortunately we can't honor either NO_TARGET nor USER_CANCELLED, we don't know of the latter, so we could return false positives on the former. https://bugzilla.gnome.org/show_bug.cgi?id=761954 --- docs/reference/gdk/gdk3-sections.txt | 1 + gdk/gdkdnd.c | 9 +++++---- gdk/gdkdnd.h | 16 ++++++++++++++++ gdk/gdkdndprivate.h | 6 ++++-- gdk/wayland/gdkdnd-wayland.c | 3 ++- gdk/wayland/gdkselection-wayland.c | 2 +- gdk/x11/gdkdnd-x11.c | 14 ++++++++------ gtk/gtkdnd.c | 27 ++++++++++++++++++++++----- 8 files changed, 59 insertions(+), 19 deletions(-) diff --git a/docs/reference/gdk/gdk3-sections.txt b/docs/reference/gdk/gdk3-sections.txt index 0e5c66cba2..bdee96b54b 100644 --- a/docs/reference/gdk/gdk3-sections.txt +++ b/docs/reference/gdk/gdk3-sections.txt @@ -976,6 +976,7 @@ gdk_cursor_get_type Drag and Drop dnd GdkDragContext +GdkDragCancelReason gdk_drag_get_selection gdk_drag_abort gdk_drop_reply diff --git a/gdk/gdkdnd.c b/gdk/gdkdnd.c index 5427eabe7c..150bb3c6cf 100644 --- a/gdk/gdkdnd.c +++ b/gdk/gdkdnd.c @@ -288,8 +288,8 @@ gdk_drag_context_class_init (GdkDragContextClass *klass) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GdkDragContextClass, cancel), NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); + g_cclosure_marshal_VOID__ENUM, + G_TYPE_NONE, 1, GDK_TYPE_DRAG_CANCEL_REASON); /** * GdkDragContext::drop-performed: @@ -704,11 +704,12 @@ gdk_drag_context_set_cursor (GdkDragContext *context, } void -gdk_drag_context_cancel (GdkDragContext *context) +gdk_drag_context_cancel (GdkDragContext *context, + GdkDragCancelReason reason) { g_return_if_fail (GDK_IS_DRAG_CONTEXT (context)); - g_signal_emit (context, signals[CANCEL], 0); + g_signal_emit (context, signals[CANCEL], 0, reason); } GList * diff --git a/gdk/gdkdnd.h b/gdk/gdkdnd.h index 65c8c873f2..f86079c7db 100644 --- a/gdk/gdkdnd.h +++ b/gdk/gdkdnd.h @@ -64,6 +64,22 @@ typedef enum GDK_ACTION_ASK = 1 << 5 } GdkDragAction; +/** + * GdkDragCancelReason: + * @GDK_DRAG_CANCEL_NO_TARGET: There is no suitable drop target. + * @GDK_DRAG_CANCEL_USER_CANCELLED: Drag cancelled by the user + * @GDK_DRAG_CANCEL_ERROR: Unspecified error. + * + * Used in #GdkDragContext to the reason of a cancelled DND operation. + * + * Since: 3.20 + */ +typedef enum { + GDK_DRAG_CANCEL_NO_TARGET, + GDK_DRAG_CANCEL_USER_CANCELLED, + GDK_DRAG_CANCEL_ERROR +} GdkDragCancelReason; + /** * GdkDragProtocol: * @GDK_DRAG_PROTO_NONE: no protocol. diff --git a/gdk/gdkdndprivate.h b/gdk/gdkdndprivate.h index e62435d3f8..8eb94b8fa0 100644 --- a/gdk/gdkdndprivate.h +++ b/gdk/gdkdndprivate.h @@ -74,7 +74,8 @@ struct _GdkDragContextClass { GdkDragAction actions); void (*set_cursor) (GdkDragContext *context, GdkCursor *cursor); - void (*cancel) (GdkDragContext *context); + void (*cancel) (GdkDragContext *context, + GdkDragCancelReason reason); void (*drop_performed) (GdkDragContext *context, guint32 time); void (*dnd_finished) (GdkDragContext *context); @@ -110,7 +111,8 @@ GList * gdk_drag_context_list (void); void gdk_drag_context_set_cursor (GdkDragContext *context, GdkCursor *cursor); -void gdk_drag_context_cancel (GdkDragContext *context); +void gdk_drag_context_cancel (GdkDragContext *context, + GdkDragCancelReason reason); gboolean gdk_drag_context_handle_source_event (GdkEvent *event); GdkCursor * gdk_drag_get_cursor (GdkDragAction action); diff --git a/gdk/wayland/gdkdnd-wayland.c b/gdk/wayland/gdkdnd-wayland.c index cf2376df26..1d71d90f34 100644 --- a/gdk/wayland/gdkdnd-wayland.c +++ b/gdk/wayland/gdkdnd-wayland.c @@ -441,7 +441,8 @@ gdk_wayland_drag_context_drop_performed (GdkDragContext *context, } static void -gdk_wayland_drag_context_cancel (GdkDragContext *context) +gdk_wayland_drag_context_cancel (GdkDragContext *context, + GdkDragCancelReason reason) { gdk_drag_context_set_cursor (context, NULL); } diff --git a/gdk/wayland/gdkselection-wayland.c b/gdk/wayland/gdkselection-wayland.c index 64aac2756a..5ed13aefb8 100644 --- a/gdk/wayland/gdkselection-wayland.c +++ b/gdk/wayland/gdkselection-wayland.c @@ -847,7 +847,7 @@ data_source_cancelled (void *data, context = gdk_wayland_drag_context_lookup_by_data_source (source); if (context) - gdk_drag_context_cancel (context); + gdk_drag_context_cancel (context, GDK_DRAG_CANCEL_ERROR); gdk_selection_owner_set (NULL, atom, GDK_CURRENT_TIME, TRUE); gdk_wayland_selection_unset_data_source (display, atom); diff --git a/gdk/x11/gdkdnd-x11.c b/gdk/x11/gdkdnd-x11.c index 56f3372fdd..767ef32272 100644 --- a/gdk/x11/gdkdnd-x11.c +++ b/gdk/x11/gdkdnd-x11.c @@ -240,7 +240,8 @@ static gboolean gdk_x11_drag_context_manage_dnd (GdkDragContext *context, GdkDragAction actions); static void gdk_x11_drag_context_set_cursor (GdkDragContext *context, GdkCursor *cursor); -static void gdk_x11_drag_context_cancel (GdkDragContext *context); +static void gdk_x11_drag_context_cancel (GdkDragContext *context, + GdkDragCancelReason reason); static void gdk_x11_drag_context_drop_performed (GdkDragContext *context, guint32 time); @@ -2821,7 +2822,8 @@ gdk_x11_drag_context_set_cursor (GdkDragContext *context, } static void -gdk_x11_drag_context_cancel (GdkDragContext *context) +gdk_x11_drag_context_cancel (GdkDragContext *context, + GdkDragCancelReason reason) { drag_context_ungrab (context); gdk_drag_drop_done (context, FALSE); @@ -2951,7 +2953,7 @@ gdk_dnd_handle_key_event (GdkDragContext *context, switch (event->keyval) { case GDK_KEY_Escape: - gdk_drag_context_cancel (context); + gdk_drag_context_cancel (context, GDK_DRAG_CANCEL_USER_CANCELLED); return TRUE; case GDK_KEY_space: @@ -2966,7 +2968,7 @@ gdk_dnd_handle_key_event (GdkDragContext *context, gdk_event_get_time ((GdkEvent *) event)); } else - gdk_drag_context_cancel (context); + gdk_drag_context_cancel (context, GDK_DRAG_CANCEL_NO_TARGET); return TRUE; @@ -3029,7 +3031,7 @@ gdk_dnd_handle_grab_broken_event (GdkDragContext *context, event->grab_window == x11_context->ipc_window) return FALSE; - gdk_drag_context_cancel (context); + gdk_drag_context_cancel (context, GDK_DRAG_CANCEL_ERROR); return TRUE; } @@ -3050,7 +3052,7 @@ gdk_dnd_handle_button_event (GdkDragContext *context, gdk_event_get_time ((GdkEvent *) event)); } else - gdk_drag_context_cancel (context); + gdk_drag_context_cancel (context, GDK_DRAG_CANCEL_NO_TARGET); return TRUE; } diff --git a/gtk/gtkdnd.c b/gtk/gtkdnd.c index 760bdde7c0..e00aab28ae 100644 --- a/gtk/gtkdnd.c +++ b/gtk/gtkdnd.c @@ -243,8 +243,9 @@ static void gtk_drag_source_info_destroy (GtkDragSourceInfo *info); static void gtk_drag_context_drop_performed_cb (GdkDragContext *context, guint time, GtkDragSourceInfo *info); -static void gtk_drag_context_cancel_cb (GdkDragContext *context, - GtkDragSourceInfo *info); +static void gtk_drag_context_cancel_cb (GdkDragContext *context, + GdkDragCancelReason reason, + GtkDragSourceInfo *info); static void gtk_drag_context_action_cb (GdkDragContext *context, GdkDragAction action, GtkDragSourceInfo *info); @@ -3454,10 +3455,26 @@ gtk_drag_context_drop_performed_cb (GdkDragContext *context, } static void -gtk_drag_context_cancel_cb (GdkDragContext *context, - GtkDragSourceInfo *info) +gtk_drag_context_cancel_cb (GdkDragContext *context, + GdkDragCancelReason reason, + GtkDragSourceInfo *info) { - gtk_drag_cancel_internal (info, GTK_DRAG_RESULT_ERROR, GDK_CURRENT_TIME); + GtkDragResult result; + + switch (reason) + { + case GDK_DRAG_CANCEL_NO_TARGET: + result = GTK_DRAG_RESULT_NO_TARGET; + break; + case GDK_DRAG_CANCEL_USER_CANCELLED: + result = GTK_DRAG_RESULT_USER_CANCELLED; + break; + case GDK_DRAG_CANCEL_ERROR: + default: + result = GTK_DRAG_RESULT_ERROR; + break; + } + gtk_drag_cancel_internal (info, result, GDK_CURRENT_TIME); } static void