gtkdnd: Optionally use gdk_drag_context_manage_dnd()

When this is in use, there's essentially a bunch of dead code here.
When all backends are ported, we'll be able to remove grab/cursor
management plus a bunch of source-side event handlers.
This commit is contained in:
Carlos Garnacho 2016-01-08 21:31:51 +01:00
parent bfee45e6f9
commit e4f5e31b8b

View File

@ -234,6 +234,17 @@ static void gtk_drag_selection_get (GtkWidget *widget,
gpointer data); gpointer data);
static void gtk_drag_remove_icon (GtkDragSourceInfo *info); static void gtk_drag_remove_icon (GtkDragSourceInfo *info);
static void gtk_drag_source_info_destroy (GtkDragSourceInfo *info); 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_action_cb (GdkDragContext *context,
GdkDragAction action,
GtkDragSourceInfo *info);
static void gtk_drag_context_dnd_finished_cb (GdkDragContext *context,
GtkDragSourceInfo *info);
static void gtk_drag_add_update_idle (GtkDragSourceInfo *info); static void gtk_drag_add_update_idle (GtkDragSourceInfo *info);
static void gtk_drag_update (GtkDragSourceInfo *info, static void gtk_drag_update (GtkDragSourceInfo *info,
@ -2159,6 +2170,12 @@ gtk_drag_begin_internal (GtkWidget *widget,
GdkDevice *pointer, *keyboard; GdkDevice *pointer, *keyboard;
GdkWindow *ipc_window; GdkWindow *ipc_window;
gint start_x, start_y; gint start_x, start_y;
GdkAtom selection;
gboolean managed = FALSE;
#ifdef GDK_WINDOWING_X11
managed = GDK_IS_X11_DISPLAY (gtk_widget_get_display (widget));
#endif
pointer = keyboard = NULL; pointer = keyboard = NULL;
ipc_widget = gtk_drag_get_ipc_widget (widget); ipc_widget = gtk_drag_get_ipc_widget (widget);
@ -2201,6 +2218,8 @@ gtk_drag_begin_internal (GtkWidget *widget,
ipc_window = gtk_widget_get_window (ipc_widget); ipc_window = gtk_widget_get_window (ipc_widget);
if (!managed)
{
if (gdk_device_grab (pointer, ipc_window, if (gdk_device_grab (pointer, ipc_window,
GDK_OWNERSHIP_APPLICATION, FALSE, GDK_OWNERSHIP_APPLICATION, FALSE,
GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_MASK |
@ -2218,6 +2237,7 @@ gtk_drag_begin_internal (GtkWidget *widget,
* we are dragging from might have held * we are dragging from might have held
*/ */
gtk_device_grab_add (ipc_widget, pointer, FALSE); gtk_device_grab_add (ipc_widget, pointer, FALSE);
}
tmp_list = g_list_last (target_list->list); tmp_list = g_list_last (target_list->list);
while (tmp_list) while (tmp_list)
@ -2251,6 +2271,14 @@ gtk_drag_begin_internal (GtkWidget *widget,
gdk_drag_context_set_device (context, pointer); gdk_drag_context_set_device (context, pointer);
g_list_free (targets); g_list_free (targets);
if (managed &&
!gdk_drag_context_manage_dnd (context, ipc_window, actions))
{
gtk_drag_release_ipc_widget (ipc_widget);
g_object_unref (context);
return NULL;
}
info = gtk_drag_get_source_info (context, TRUE); info = gtk_drag_get_source_info (context, TRUE);
info->ipc_widget = ipc_widget; info->ipc_widget = ipc_widget;
@ -2300,6 +2328,23 @@ gtk_drag_begin_internal (GtkWidget *widget,
} }
} }
if (managed)
{
g_signal_connect (context, "drop-performed",
G_CALLBACK (gtk_drag_context_drop_performed_cb), info);
g_signal_connect (context, "dnd-finished",
G_CALLBACK (gtk_drag_context_dnd_finished_cb), info);
g_signal_connect (context, "cancel",
G_CALLBACK (gtk_drag_context_cancel_cb), info);
g_signal_connect (context, "action",
G_CALLBACK (gtk_drag_context_action_cb), info);
selection = gdk_drag_get_selection (context);
if (selection)
gtk_drag_source_check_selection (info, selection, time);
}
else
{
info->cur_x = info->start_x; info->cur_x = info->start_x;
info->cur_y = info->start_y; info->cur_y = info->start_y;
@ -2320,6 +2365,8 @@ gtk_drag_begin_internal (GtkWidget *widget,
G_CALLBACK (gtk_drag_key_cb), info); G_CALLBACK (gtk_drag_key_cb), info);
g_signal_connect (info->ipc_widget, "key-release-event", g_signal_connect (info->ipc_widget, "key-release-event",
G_CALLBACK (gtk_drag_key_cb), info); G_CALLBACK (gtk_drag_key_cb), info);
}
g_signal_connect (info->ipc_widget, "selection-get", g_signal_connect (info->ipc_widget, "selection-get",
G_CALLBACK (gtk_drag_selection_get), info); G_CALLBACK (gtk_drag_selection_get), info);
@ -3351,6 +3398,74 @@ gtk_drag_cancel_internal (GtkDragSourceInfo *info,
gtk_drag_drop_finished (info, result, time); gtk_drag_drop_finished (info, result, time);
} }
static void
gtk_drag_context_drop_performed_cb (GdkDragContext *context,
guint32 time_,
GtkDragSourceInfo *info)
{
gtk_drag_end (info, time_);
gtk_drag_drop (info, time_);
}
static void
gtk_drag_context_cancel_cb (GdkDragContext *context,
GtkDragSourceInfo *info)
{
gtk_drag_cancel_internal (info, GTK_DRAG_RESULT_ERROR, GDK_CURRENT_TIME);
}
static void
gtk_drag_context_action_cb (GdkDragContext *context,
GdkDragAction action,
GtkDragSourceInfo *info)
{
if (info->proxy_dest)
{
if (info->proxy_dest->proxy_drop_wait)
{
gboolean result = gdk_drag_context_get_selected_action (context) != 0;
/* Aha - we can finally pass the DROP on... */
gdk_drop_reply (info->proxy_dest->context, result, info->proxy_dest->proxy_drop_time);
if (result)
gdk_drag_drop (info->context, info->proxy_dest->proxy_drop_time);
else
gtk_drag_finish (info->proxy_dest->context, FALSE, FALSE, info->proxy_dest->proxy_drop_time);
}
else
{
gdk_drag_status (info->proxy_dest->context,
gdk_drag_context_get_selected_action (context),
GDK_CURRENT_TIME);
}
g_signal_stop_emission_by_name (context, "action");
}
}
static void
gtk_drag_context_dnd_finished_cb (GdkDragContext *context,
GtkDragSourceInfo *info)
{
gtk_drag_source_release_selections (info, GDK_CURRENT_TIME);
if (info->proxy_dest)
{
/* The time from the event isn't reliable for Xdnd drags */
gtk_drag_finish (info->proxy_dest->context, TRUE, FALSE,
info->proxy_dest->proxy_drop_time);
}
if (gdk_drag_context_get_selected_action (context) == GDK_ACTION_MOVE)
{
g_signal_emit_by_name (info->widget,
"drag-data-delete",
context);
}
gtk_drag_source_info_destroy (info);
}
/* “motion-notify-event” callback during drag. */ /* “motion-notify-event” callback during drag. */
static gboolean static gboolean
gtk_drag_motion_cb (GtkWidget *widget, gtk_drag_motion_cb (GtkWidget *widget,