dnd: Allow programmatic drag cancellation

Add a gtk_drag_cancel() function that can be used on the
source side to cancel an ongoing drag operation. This can
be useful, e.g. if the data that is being dragged becomes
unavailable.

gtk_drag_cancel() will become public API in 3.16; we keep it
private here so we can use it from GtkNotebook.
This commit is contained in:
Matthias Clasen
2015-01-29 23:49:48 -05:00
parent 650c25e06c
commit 62616a716f
3 changed files with 26 additions and 10 deletions

View File

@@ -6509,6 +6509,7 @@ gtk_drag_unhighlight
<SUBSECTION Source Side>
gtk_drag_begin
gtk_drag_begin_with_coordinates
gtk_drag_cancel
gtk_drag_set_icon_widget
gtk_drag_set_icon_pixbuf
gtk_drag_set_icon_stock

View File

@@ -245,7 +245,7 @@ static void gtk_drag_drop (GtkDragSourceInfo *info,
static void gtk_drag_drop_finished (GtkDragSourceInfo *info,
GtkDragResult result,
guint time);
static void gtk_drag_cancel (GtkDragSourceInfo *info,
static void gtk_drag_cancel_internal (GtkDragSourceInfo *info,
GtkDragResult result,
guint32 time);
@@ -4218,9 +4218,9 @@ gtk_drag_end (GtkDragSourceInfo *info,
* or programmatically.
*/
static void
gtk_drag_cancel (GtkDragSourceInfo *info,
GtkDragResult result,
guint32 time)
gtk_drag_cancel_internal (GtkDragSourceInfo *info,
GtkDragResult result,
guint32 time)
{
gtk_drag_end (info, time);
gdk_drag_abort (info->context, time);
@@ -4277,7 +4277,7 @@ gtk_drag_key_cb (GtkWidget *widget,
switch (event->keyval)
{
case GDK_KEY_Escape:
gtk_drag_cancel (info, GTK_DRAG_RESULT_USER_CANCELLED, event->time);
gtk_drag_cancel_internal (info, GTK_DRAG_RESULT_USER_CANCELLED, event->time);
return TRUE;
case GDK_KEY_space:
@@ -4293,7 +4293,7 @@ gtk_drag_key_cb (GtkWidget *widget,
}
else
{
gtk_drag_cancel (info, GTK_DRAG_RESULT_NO_TARGET, event->time);
gtk_drag_cancel_internal (info, GTK_DRAG_RESULT_NO_TARGET, event->time);
}
return TRUE;
@@ -4360,7 +4360,7 @@ gtk_drag_grab_broken_event_cb (GtkWidget *widget,
|| event->grab_window == gtk_widget_get_window (info->ipc_widget))
return FALSE;
gtk_drag_cancel (info, GTK_DRAG_RESULT_GRAB_BROKEN, gtk_get_current_event_time ());
gtk_drag_cancel_internal (info, GTK_DRAG_RESULT_GRAB_BROKEN, gtk_get_current_event_time ());
return TRUE;
}
@@ -4377,9 +4377,10 @@ gtk_drag_grab_notify_cb (GtkWidget *widget,
if (gtk_widget_device_is_shadowed (widget, pointer))
{
/* We have to block callbacks to avoid recursion here, because
gtk_drag_cancel calls gtk_grab_remove (via gtk_drag_end) */
* gtk_drag_cancel_internal calls gtk_grab_remove (via gtk_drag_end)
*/
g_signal_handlers_block_by_func (widget, gtk_drag_grab_notify_cb, data);
gtk_drag_cancel (info, GTK_DRAG_RESULT_GRAB_BROKEN, gtk_get_current_event_time ());
gtk_drag_cancel_internal (info, GTK_DRAG_RESULT_GRAB_BROKEN, gtk_get_current_event_time ());
g_signal_handlers_unblock_by_func (widget, gtk_drag_grab_notify_cb, data);
}
}
@@ -4403,7 +4404,7 @@ gtk_drag_button_release_cb (GtkWidget *widget,
}
else
{
gtk_drag_cancel (info, GTK_DRAG_RESULT_NO_TARGET, event->time);
gtk_drag_cancel_internal (info, GTK_DRAG_RESULT_NO_TARGET, event->time);
}
return TRUE;
@@ -4456,3 +4457,15 @@ gtk_drag_check_threshold (GtkWidget *widget,
return (ABS (current_x - start_x) > drag_threshold ||
ABS (current_y - start_y) > drag_threshold);
}
void
gtk_drag_cancel (GdkDragContext *context)
{
GtkDragSourceInfo *info;
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
info = gtk_drag_get_source_info (context, FALSE);
if (info != NULL)
gtk_drag_cancel_internal (info, GTK_DRAG_RESULT_ERROR, gtk_get_current_event_time ());
}

View File

@@ -163,6 +163,8 @@ void _gtk_widget_remove_controller (GtkWidget
GList * _gtk_widget_list_controllers (GtkWidget *widget,
GtkPropagationPhase phase);
void gtk_drag_cancel (GdkDragContext *context);
G_END_DECLS
#endif /* __GTK_WIDGET_PRIVATE_H__ */