forked from AuroraMiddleware/gtk
dnd: Remove much of the unmanaged dnd
This commit is contained in:
parent
ff577e6c2c
commit
6cfb55a396
673
gtk/gtkdnd.c
673
gtk/gtkdnd.c
@ -36,37 +36,15 @@
|
||||
|
||||
#include "gdk/gdkcontentformatsprivate.h"
|
||||
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/keysym.h>
|
||||
#include "gdk/x11/gdkx.h"
|
||||
#ifdef XINPUT_2
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef GDK_WINDOWING_WIN32
|
||||
#include <gdk/win32/gdkwin32.h>
|
||||
#endif
|
||||
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
#include <gdk/wayland/gdkwayland.h>
|
||||
#endif
|
||||
|
||||
#include "gtkdragdest.h"
|
||||
#include "gtkgesturedrag.h"
|
||||
#include "gtkgesturesingle.h"
|
||||
#include "gtkicontheme.h"
|
||||
#include "gtkimageprivate.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkmain.h"
|
||||
#include "gtktooltipprivate.h"
|
||||
#include "gtkwindow.h"
|
||||
#include "gtkselectionprivate.h"
|
||||
#include "gtkwindowgroup.h"
|
||||
#include "gtkwindowprivate.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkdrawingarea.h"
|
||||
|
||||
|
||||
/**
|
||||
@ -88,14 +66,6 @@ static GSList *source_widgets = NULL;
|
||||
typedef struct _GtkDragSourceInfo GtkDragSourceInfo;
|
||||
typedef struct _GtkDragDestInfo GtkDragDestInfo;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GTK_DRAG_STATUS_DRAG,
|
||||
GTK_DRAG_STATUS_WAIT,
|
||||
GTK_DRAG_STATUS_DROP
|
||||
} GtkDragStatus;
|
||||
|
||||
struct _GtkDragSourceInfo
|
||||
{
|
||||
GtkWidget *widget;
|
||||
@ -105,23 +75,11 @@ struct _GtkDragSourceInfo
|
||||
GtkWidget *icon_window; /* Window for drag */
|
||||
GtkWidget *icon_widget; /* Widget for drag */
|
||||
GtkWidget *ipc_widget; /* GtkInvisible for grab, message passing */
|
||||
GdkCursor *cursor; /* Cursor for drag */
|
||||
gint hot_x, hot_y; /* Hot spot for drag */
|
||||
gint button; /* mouse button starting drag */
|
||||
|
||||
GtkDragStatus status; /* drag status */
|
||||
GdkEvent *last_event; /* pending event */
|
||||
|
||||
gint start_x, start_y; /* Initial position */
|
||||
gint cur_x, cur_y; /* Current Position */
|
||||
|
||||
guint32 grab_time; /* timestamp for initial grab */
|
||||
GList *selections; /* selections we've claimed */
|
||||
|
||||
guint update_idle; /* Idle function to update the drag */
|
||||
guint drop_timeout; /* Timeout for aborting drop */
|
||||
guint destroy_icon : 1; /* If true, destroy icon_widget */
|
||||
guint have_grab : 1; /* Do we still have the pointer grab */
|
||||
};
|
||||
|
||||
struct _GtkDragDestInfo
|
||||
@ -146,10 +104,6 @@ static void gtk_drag_get_event_actions (const GdkEvent *event,
|
||||
GdkDragAction actions,
|
||||
GdkDragAction *suggested_action,
|
||||
GdkDragAction *possible_actions);
|
||||
static GdkCursor * gtk_drag_get_cursor (GtkWidget *widget,
|
||||
GdkDragAction action,
|
||||
GtkDragSourceInfo *info);
|
||||
static void gtk_drag_update_cursor (GtkDragSourceInfo *info);
|
||||
static GtkWidget *gtk_drag_get_ipc_widget (GtkWidget *widget);
|
||||
static GtkWidget *gtk_drag_get_ipc_widget_for_display(GdkDisplay*display);
|
||||
static void gtk_drag_release_ipc_widget (GtkWidget *widget);
|
||||
@ -216,24 +170,7 @@ static void gtk_drag_context_cancel_cb (GdkDragContext *context,
|
||||
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_update (GtkDragSourceInfo *info,
|
||||
gint x_root,
|
||||
gint y_root,
|
||||
const GdkEvent *event);
|
||||
static gboolean gtk_drag_motion_cb (GtkWidget *widget,
|
||||
GdkEventMotion *event,
|
||||
gpointer data);
|
||||
static gboolean gtk_drag_key_cb (GtkWidget *widget,
|
||||
GdkEventKey *event,
|
||||
gpointer data);
|
||||
static void gtk_drag_grab_notify_cb (GtkWidget *widget,
|
||||
gboolean was_grabbed,
|
||||
gpointer data);
|
||||
static gboolean gtk_drag_button_release_cb (GtkWidget *widget,
|
||||
GdkEventButton *event,
|
||||
gpointer data);
|
||||
static gboolean gtk_drag_abort_timeout (gpointer data);
|
||||
|
||||
static void set_icon_helper (GdkDragContext *context,
|
||||
@ -241,23 +178,6 @@ static void set_icon_helper (GdkDragContext *context,
|
||||
gint hot_x,
|
||||
gint hot_y);
|
||||
|
||||
/************************
|
||||
* Cursor and Icon data *
|
||||
************************/
|
||||
|
||||
static struct {
|
||||
GdkDragAction action;
|
||||
const gchar *name;
|
||||
GdkTexture *texture;
|
||||
GdkCursor *cursor;
|
||||
} drag_cursors[] = {
|
||||
{ GDK_ACTION_DEFAULT, NULL },
|
||||
{ GDK_ACTION_ASK, "dnd-ask", NULL, NULL },
|
||||
{ GDK_ACTION_COPY, "copy", NULL, NULL },
|
||||
{ GDK_ACTION_MOVE, "move", NULL, NULL },
|
||||
{ GDK_ACTION_LINK, "alias", NULL, NULL },
|
||||
{ 0 , "no-drop", NULL, NULL },
|
||||
};
|
||||
|
||||
/*********************
|
||||
* Utility functions *
|
||||
@ -312,30 +232,6 @@ gtk_drag_get_ipc_widget (GtkWidget *widget)
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
grab_dnd_keys (GtkWidget *widget,
|
||||
GdkDevice *device,
|
||||
guint32 time)
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
gdk_device_grab (device,
|
||||
gtk_widget_get_window (widget),
|
||||
GDK_OWNERSHIP_APPLICATION, FALSE,
|
||||
GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
|
||||
NULL, time);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
}
|
||||
|
||||
static void
|
||||
ungrab_dnd_keys (GtkWidget *widget,
|
||||
GdkDevice *device,
|
||||
guint32 time)
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
gdk_device_ungrab (device, time);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
}
|
||||
|
||||
/*
|
||||
* gtk_drag_release_ipc_widget:
|
||||
* @widget: the widget to release
|
||||
@ -347,19 +243,8 @@ gtk_drag_release_ipc_widget (GtkWidget *widget)
|
||||
{
|
||||
GtkWindow *window = GTK_WINDOW (widget);
|
||||
GdkDisplay *display = gtk_widget_get_display (widget);
|
||||
GdkDragContext *context = g_object_get_data (G_OBJECT (widget), "drag-context");
|
||||
GSList *drag_widgets = g_object_get_data (G_OBJECT (display),
|
||||
"gtk-dnd-ipc-widgets");
|
||||
GdkDevice *pointer, *keyboard;
|
||||
|
||||
if (context)
|
||||
{
|
||||
pointer = gdk_drag_context_get_device (context);
|
||||
keyboard = gdk_device_get_associated_device (pointer);
|
||||
|
||||
if (keyboard)
|
||||
ungrab_dnd_keys (widget, keyboard, GDK_CURRENT_TIME);
|
||||
}
|
||||
|
||||
if (gtk_window_has_group (window))
|
||||
gtk_window_group_remove_window (gtk_window_get_group (window),
|
||||
@ -445,84 +330,6 @@ gtk_drag_get_event_actions (const GdkEvent *event,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_drag_cursor_texture (int i)
|
||||
{
|
||||
if (drag_cursors[i].texture == NULL)
|
||||
{
|
||||
char *path = g_strconcat ("/org/gtk/libgtk/cursor/", drag_cursors[i].name, ".png", NULL);
|
||||
drag_cursors[i].texture = gdk_texture_new_from_resource (path);
|
||||
g_free (path);
|
||||
}
|
||||
}
|
||||
|
||||
static GdkCursor *
|
||||
gtk_drag_get_cursor (GtkWidget *widget,
|
||||
GdkDragAction action,
|
||||
GtkDragSourceInfo *info)
|
||||
{
|
||||
gint i;
|
||||
|
||||
/* reconstruct the cursors for each new drag (thus !info),
|
||||
* to catch cursor theme changes
|
||||
*/
|
||||
if (!info)
|
||||
{
|
||||
for (i = 0 ; i < G_N_ELEMENTS (drag_cursors) - 1; i++)
|
||||
g_clear_object (&drag_cursors[i].cursor);
|
||||
}
|
||||
|
||||
for (i = 0 ; i < G_N_ELEMENTS (drag_cursors) - 1; i++)
|
||||
if (drag_cursors[i].action == action)
|
||||
break;
|
||||
|
||||
if (drag_cursors[i].cursor == NULL)
|
||||
drag_cursors[i].cursor = gdk_cursor_new_from_name (drag_cursors[i].name, NULL);
|
||||
|
||||
if (drag_cursors[i].cursor == NULL)
|
||||
{
|
||||
ensure_drag_cursor_texture (i);
|
||||
drag_cursors[i].cursor = gdk_cursor_new_from_texture (drag_cursors[i].texture, 0, 0, NULL);
|
||||
}
|
||||
|
||||
return drag_cursors[i].cursor;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_drag_update_cursor (GtkDragSourceInfo *info)
|
||||
{
|
||||
GdkCursor *cursor;
|
||||
gint i;
|
||||
|
||||
if (!info->have_grab)
|
||||
return;
|
||||
|
||||
for (i = 0 ; i < G_N_ELEMENTS (drag_cursors) - 1; i++)
|
||||
if (info->cursor == drag_cursors[i].cursor)
|
||||
break;
|
||||
|
||||
if (i == G_N_ELEMENTS (drag_cursors))
|
||||
return;
|
||||
|
||||
cursor = gtk_drag_get_cursor (info->widget,
|
||||
drag_cursors[i].action, info);
|
||||
|
||||
if (cursor != info->cursor)
|
||||
{
|
||||
GdkDevice *pointer;
|
||||
|
||||
pointer = gdk_drag_context_get_device (info->context);
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
gdk_device_grab (pointer,
|
||||
gtk_widget_get_window (info->ipc_widget),
|
||||
GDK_OWNERSHIP_APPLICATION, FALSE,
|
||||
GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
|
||||
cursor, info->grab_time);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
info->cursor = cursor;
|
||||
}
|
||||
}
|
||||
|
||||
/********************
|
||||
* Destination side *
|
||||
********************/
|
||||
@ -1151,23 +958,6 @@ gtk_drag_dest_drop (GtkWidget *widget,
|
||||
* Source side *
|
||||
***************/
|
||||
|
||||
|
||||
static gboolean
|
||||
gtk_drag_is_managed (GtkWidget *source_widget)
|
||||
{
|
||||
return
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
GDK_IS_X11_DISPLAY (gtk_widget_get_display (source_widget)) ||
|
||||
#endif
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
GDK_IS_WAYLAND_DISPLAY (gtk_widget_get_display (source_widget)) ||
|
||||
#endif
|
||||
#ifdef GDK_WINDOWING_WIN32
|
||||
GDK_IS_WIN32_DISPLAY (gtk_widget_get_display (source_widget)) ||
|
||||
#endif
|
||||
FALSE;
|
||||
}
|
||||
|
||||
/* Like gtk_drag_begin(), but also takes a GtkIconHelper
|
||||
* so that we can set the icon from the source site information
|
||||
*/
|
||||
@ -1186,14 +976,10 @@ gtk_drag_begin_internal (GtkWidget *widget,
|
||||
GdkDragAction possible_actions, suggested_action;
|
||||
GdkDragContext *context;
|
||||
GtkWidget *ipc_widget;
|
||||
GdkCursor *cursor;
|
||||
GdkDevice *pointer, *keyboard;
|
||||
GdkWindow *ipc_window;
|
||||
int start_x, start_y;
|
||||
GdkAtom selection;
|
||||
gboolean managed;
|
||||
|
||||
managed = gtk_drag_is_managed (widget);
|
||||
|
||||
pointer = keyboard = NULL;
|
||||
ipc_widget = gtk_drag_get_ipc_widget (widget);
|
||||
@ -1201,10 +987,6 @@ gtk_drag_begin_internal (GtkWidget *widget,
|
||||
gtk_drag_get_event_actions (event, button, actions,
|
||||
&suggested_action, &possible_actions);
|
||||
|
||||
cursor = gtk_drag_get_cursor (widget,
|
||||
suggested_action,
|
||||
NULL);
|
||||
|
||||
if (event)
|
||||
{
|
||||
time = gdk_event_get_time (event);
|
||||
@ -1235,33 +1017,6 @@ gtk_drag_begin_internal (GtkWidget *widget,
|
||||
|
||||
ipc_window = gtk_widget_get_window (ipc_widget);
|
||||
|
||||
if (!managed)
|
||||
{
|
||||
gboolean grabbed;
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
grabbed = gdk_device_grab (pointer, ipc_window,
|
||||
GDK_OWNERSHIP_APPLICATION, FALSE,
|
||||
GDK_POINTER_MOTION_MASK |
|
||||
GDK_BUTTON_RELEASE_MASK,
|
||||
cursor, time) == GDK_GRAB_SUCCESS;
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
|
||||
if (!grabbed)
|
||||
{
|
||||
gtk_drag_release_ipc_widget (ipc_widget);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (keyboard)
|
||||
grab_dnd_keys (ipc_widget, keyboard, time);
|
||||
|
||||
/* We use a GTK grab here to override any grabs that the widget
|
||||
* we are dragging from might have held
|
||||
*/
|
||||
gtk_device_grab_add (ipc_widget, pointer, FALSE);
|
||||
}
|
||||
|
||||
source_widgets = g_slist_prepend (source_widgets, ipc_widget);
|
||||
|
||||
if (x != -1 && y != -1)
|
||||
@ -1287,8 +1042,7 @@ gtk_drag_begin_internal (GtkWidget *widget,
|
||||
|
||||
gdk_drag_context_set_device (context, pointer);
|
||||
|
||||
if (managed &&
|
||||
!gdk_drag_context_manage_dnd (context, ipc_window, actions))
|
||||
if (!gdk_drag_context_manage_dnd (context, ipc_window, actions))
|
||||
{
|
||||
gtk_drag_release_ipc_widget (ipc_widget);
|
||||
g_object_unref (context);
|
||||
@ -1302,23 +1056,16 @@ gtk_drag_begin_internal (GtkWidget *widget,
|
||||
|
||||
info->widget = g_object_ref (widget);
|
||||
|
||||
info->button = button;
|
||||
info->cursor = cursor;
|
||||
info->target_list = target_list;
|
||||
gdk_content_formats_ref (target_list);
|
||||
|
||||
info->possible_actions = actions;
|
||||
|
||||
info->status = GTK_DRAG_STATUS_DRAG;
|
||||
info->last_event = NULL;
|
||||
info->selections = NULL;
|
||||
info->icon_window = NULL;
|
||||
info->icon_widget = NULL;
|
||||
info->destroy_icon = FALSE;
|
||||
|
||||
info->start_x = start_x;
|
||||
info->start_y = start_y;
|
||||
|
||||
gtk_widget_reset_controllers (widget);
|
||||
|
||||
g_signal_emit_by_name (widget, "drag-begin", info->context);
|
||||
@ -1341,47 +1088,20 @@ 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, "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);
|
||||
|
||||
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_y = info->start_y;
|
||||
|
||||
if (event && gdk_event_get_event_type (event) == GDK_MOTION_NOTIFY)
|
||||
gtk_drag_motion_cb (info->ipc_widget, (GdkEventMotion *)event, info);
|
||||
else
|
||||
gtk_drag_update (info, info->cur_x, info->cur_y, event);
|
||||
|
||||
g_signal_connect (info->ipc_widget, "grab-notify",
|
||||
G_CALLBACK (gtk_drag_grab_notify_cb), info);
|
||||
g_signal_connect (info->ipc_widget, "button-release-event",
|
||||
G_CALLBACK (gtk_drag_button_release_cb), info);
|
||||
g_signal_connect (info->ipc_widget, "motion-notify-event",
|
||||
G_CALLBACK (gtk_drag_motion_cb), info);
|
||||
g_signal_connect (info->ipc_widget, "key-press-event",
|
||||
G_CALLBACK (gtk_drag_key_cb), info);
|
||||
g_signal_connect (info->ipc_widget, "key-release-event",
|
||||
G_CALLBACK (gtk_drag_key_cb), info);
|
||||
}
|
||||
selection = gdk_drag_get_selection (context);
|
||||
if (selection)
|
||||
gtk_drag_source_check_selection (info, selection, time);
|
||||
|
||||
g_signal_connect (info->ipc_widget, "selection-get",
|
||||
G_CALLBACK (gtk_drag_selection_get), info);
|
||||
|
||||
info->have_grab = TRUE;
|
||||
info->grab_time = time;
|
||||
|
||||
return info->context;
|
||||
}
|
||||
|
||||
@ -1455,22 +1175,6 @@ icon_widget_destroyed (GtkWidget *widget,
|
||||
g_clear_object (&info->icon_widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_drag_update_icon_window (GtkDragSourceInfo *info)
|
||||
{
|
||||
if (!gtk_drag_is_managed (info->widget) && info->icon_window)
|
||||
{
|
||||
gtk_window_move (GTK_WINDOW (info->icon_window),
|
||||
info->cur_x - info->hot_x,
|
||||
info->cur_y - info->hot_y);
|
||||
|
||||
if (gtk_widget_get_visible (info->icon_window))
|
||||
gdk_window_raise (gtk_widget_get_window (info->icon_window));
|
||||
else
|
||||
gtk_widget_show (info->icon_window);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_drag_set_icon_widget_internal (GdkDragContext *context,
|
||||
GtkWidget *widget,
|
||||
@ -1496,12 +1200,10 @@ gtk_drag_set_icon_widget_internal (GdkDragContext *context,
|
||||
g_object_ref (widget);
|
||||
|
||||
info->icon_widget = widget;
|
||||
info->hot_x = hot_x;
|
||||
info->hot_y = hot_y;
|
||||
info->destroy_icon = destroy_on_release;
|
||||
|
||||
if (!widget)
|
||||
goto out;
|
||||
return;
|
||||
|
||||
g_signal_connect (widget, "destroy", G_CALLBACK (icon_widget_destroyed), info);
|
||||
|
||||
@ -1527,10 +1229,6 @@ gtk_drag_set_icon_widget_internal (GdkDragContext *context,
|
||||
if (gtk_bin_get_child (GTK_BIN (info->icon_window)))
|
||||
gtk_container_remove (GTK_CONTAINER (info->icon_window), gtk_bin_get_child (GTK_BIN (info->icon_window)));
|
||||
gtk_container_add (GTK_CONTAINER (info->icon_window), widget);
|
||||
|
||||
out:
|
||||
gtk_drag_update_cursor (info);
|
||||
gtk_drag_update_icon_window (info);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1731,69 +1429,6 @@ gtk_drag_set_icon_default (GdkDragContext *context)
|
||||
gtk_drag_set_icon_name (context, "text-x-generic", -2, -2);
|
||||
}
|
||||
|
||||
/*
|
||||
* _gtk_drag_source_handle_event:
|
||||
* @toplevel: Toplevel widget that received the event
|
||||
* @event: the event to handle
|
||||
*
|
||||
* Called from widget event handling code on Drag events
|
||||
* for drag sources.
|
||||
*/
|
||||
void
|
||||
_gtk_drag_source_handle_event (GtkWidget *widget,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GtkDragSourceInfo *info;
|
||||
GdkDragContext *context;
|
||||
guint32 time;
|
||||
|
||||
g_return_if_fail (widget != NULL);
|
||||
g_return_if_fail (event != NULL);
|
||||
|
||||
gdk_event_get_drag_context (event, &context);
|
||||
time = gdk_event_get_time (event);
|
||||
|
||||
info = gtk_drag_get_source_info (context, FALSE);
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
switch ((guint) gdk_event_get_event_type (event))
|
||||
{
|
||||
case GDK_DRAG_STATUS:
|
||||
{
|
||||
GdkCursor *cursor;
|
||||
if (info->have_grab)
|
||||
{
|
||||
cursor = gtk_drag_get_cursor (widget,
|
||||
gdk_drag_context_get_selected_action (context),
|
||||
info);
|
||||
if (info->cursor != cursor)
|
||||
{
|
||||
GdkDevice *pointer;
|
||||
|
||||
pointer = gdk_drag_context_get_device (context);
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
gdk_device_grab (pointer, gtk_widget_get_window (widget),
|
||||
GDK_OWNERSHIP_APPLICATION, FALSE,
|
||||
GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
|
||||
cursor, info->grab_time);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
info->cursor = cursor;
|
||||
}
|
||||
|
||||
gtk_drag_add_update_idle (info);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GDK_DROP_FINISHED:
|
||||
gtk_drag_drop_finished (info, GTK_DRAG_RESULT_SUCCESS, time);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_drag_source_check_selection (GtkDragSourceInfo *info,
|
||||
GdkAtom selection,
|
||||
@ -1905,9 +1540,6 @@ gtk_drag_drop (GtkDragSourceInfo *info,
|
||||
if (info->icon_window)
|
||||
gtk_widget_hide (info->icon_window);
|
||||
|
||||
if (!gtk_drag_is_managed (info->widget))
|
||||
gdk_drag_drop (info->context, time);
|
||||
|
||||
info->drop_timeout = gdk_threads_add_timeout (DROP_ABORT_TIME,
|
||||
gtk_drag_abort_timeout,
|
||||
info);
|
||||
@ -1992,18 +1624,6 @@ gtk_drag_source_info_destroy (GtkDragSourceInfo *info)
|
||||
gtk_drag_context_cancel_cb,
|
||||
info);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (info->ipc_widget,
|
||||
gtk_drag_grab_notify_cb,
|
||||
info);
|
||||
g_signal_handlers_disconnect_by_func (info->ipc_widget,
|
||||
gtk_drag_button_release_cb,
|
||||
info);
|
||||
g_signal_handlers_disconnect_by_func (info->ipc_widget,
|
||||
gtk_drag_motion_cb,
|
||||
info);
|
||||
g_signal_handlers_disconnect_by_func (info->ipc_widget,
|
||||
gtk_drag_key_cb,
|
||||
info);
|
||||
g_signal_handlers_disconnect_by_func (info->ipc_widget,
|
||||
gtk_drag_selection_get,
|
||||
info);
|
||||
@ -2022,162 +1642,11 @@ gtk_drag_source_info_destroy (GtkDragSourceInfo *info)
|
||||
if (info->drop_timeout)
|
||||
g_source_remove (info->drop_timeout);
|
||||
|
||||
if (info->update_idle)
|
||||
g_source_remove (info->update_idle);
|
||||
|
||||
/* keep the icon_window alive until the (possible) drag cancel animation is done */
|
||||
g_object_set_data_full (G_OBJECT (info->context), "former-gtk-source-info", info, (GDestroyNotify)gtk_drag_source_info_free);
|
||||
|
||||
gtk_drag_clear_source_info (info->context);
|
||||
g_object_unref (info->context);
|
||||
|
||||
if (info->last_event)
|
||||
gdk_event_free (info->last_event);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_drag_update_idle (gpointer data)
|
||||
{
|
||||
GtkDragSourceInfo *info = data;
|
||||
GdkWindow *dest_window;
|
||||
GdkDragProtocol protocol;
|
||||
GdkAtom selection;
|
||||
|
||||
GdkDragAction action;
|
||||
GdkDragAction possible_actions;
|
||||
guint32 time;
|
||||
|
||||
info->update_idle = 0;
|
||||
|
||||
if (info->last_event)
|
||||
{
|
||||
time = gdk_event_get_time (info->last_event);
|
||||
gtk_drag_get_event_actions (info->last_event,
|
||||
info->button,
|
||||
info->possible_actions,
|
||||
&action, &possible_actions);
|
||||
|
||||
gtk_drag_update_icon_window (info);
|
||||
gdk_drag_find_window (info->context,
|
||||
info->icon_window ? gtk_widget_get_window (info->icon_window) : NULL,
|
||||
info->cur_x, info->cur_y,
|
||||
&dest_window, &protocol);
|
||||
|
||||
if (!gdk_drag_motion (info->context, dest_window, protocol,
|
||||
info->cur_x, info->cur_y, action,
|
||||
possible_actions,
|
||||
time))
|
||||
{
|
||||
gdk_event_free ((GdkEvent *)info->last_event);
|
||||
info->last_event = NULL;
|
||||
}
|
||||
|
||||
if (dest_window)
|
||||
g_object_unref (dest_window);
|
||||
|
||||
selection = gdk_drag_get_selection (info->context);
|
||||
if (selection)
|
||||
gtk_drag_source_check_selection (info, selection, time);
|
||||
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_drag_add_update_idle (GtkDragSourceInfo *info)
|
||||
{
|
||||
/* We use an idle lower than GDK_PRIORITY_REDRAW so that exposes
|
||||
* from the last move can catch up before we move again.
|
||||
*/
|
||||
if (!info->update_idle)
|
||||
{
|
||||
info->update_idle = gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW + 5,
|
||||
gtk_drag_update_idle,
|
||||
info,
|
||||
NULL);
|
||||
g_source_set_name_by_id (info->update_idle, "[gtk+] gtk_drag_update_idle");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* gtk_drag_update:
|
||||
* @info: DragSourceInfo for the drag
|
||||
* @x_root: new X position
|
||||
* @y_root: new y position
|
||||
* @event: event received requiring update
|
||||
*
|
||||
* Updates the status of the drag; called when the
|
||||
* cursor moves or the modifier changes
|
||||
*/
|
||||
static void
|
||||
gtk_drag_update (GtkDragSourceInfo *info,
|
||||
gint x_root,
|
||||
gint y_root,
|
||||
const GdkEvent *event)
|
||||
{
|
||||
info->cur_x = x_root;
|
||||
info->cur_y = y_root;
|
||||
if (info->last_event)
|
||||
{
|
||||
gdk_event_free ((GdkEvent *)info->last_event);
|
||||
info->last_event = NULL;
|
||||
}
|
||||
if (event)
|
||||
info->last_event = gdk_event_copy ((GdkEvent *)event);
|
||||
|
||||
gtk_drag_add_update_idle (info);
|
||||
}
|
||||
|
||||
/* Called when the user finishes to drag, either by
|
||||
* releasing the mouse, or by pressing Esc.
|
||||
*/
|
||||
static void
|
||||
gtk_drag_end (GtkDragSourceInfo *info,
|
||||
guint32 time)
|
||||
{
|
||||
GdkDevice *pointer, *keyboard;
|
||||
|
||||
pointer = gdk_drag_context_get_device (info->context);
|
||||
keyboard = gdk_device_get_associated_device (pointer);
|
||||
|
||||
/* Prevent ungrab before grab (see bug 623865) */
|
||||
if (info->grab_time == GDK_CURRENT_TIME)
|
||||
time = GDK_CURRENT_TIME;
|
||||
|
||||
if (info->update_idle)
|
||||
{
|
||||
g_source_remove (info->update_idle);
|
||||
info->update_idle = 0;
|
||||
}
|
||||
|
||||
if (info->last_event)
|
||||
{
|
||||
gdk_event_free (info->last_event);
|
||||
info->last_event = NULL;
|
||||
}
|
||||
|
||||
info->have_grab = FALSE;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (info->ipc_widget,
|
||||
gtk_drag_grab_notify_cb,
|
||||
info);
|
||||
g_signal_handlers_disconnect_by_func (info->ipc_widget,
|
||||
gtk_drag_button_release_cb,
|
||||
info);
|
||||
g_signal_handlers_disconnect_by_func (info->ipc_widget,
|
||||
gtk_drag_motion_cb,
|
||||
info);
|
||||
g_signal_handlers_disconnect_by_func (info->ipc_widget,
|
||||
gtk_drag_key_cb,
|
||||
info);
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
gdk_device_ungrab (pointer, time);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
|
||||
ungrab_dnd_keys (info->ipc_widget, keyboard, time);
|
||||
gtk_device_grab_remove (info->ipc_widget, pointer);
|
||||
}
|
||||
|
||||
/* Called on cancellation of a drag, either by the user
|
||||
@ -2188,9 +1657,6 @@ gtk_drag_cancel_internal (GtkDragSourceInfo *info,
|
||||
GtkDragResult result,
|
||||
guint32 time)
|
||||
{
|
||||
gtk_drag_end (info, time);
|
||||
if (!gtk_drag_is_managed (info->widget))
|
||||
gdk_drag_abort (info->context, time);
|
||||
gtk_drag_drop_finished (info, result, time);
|
||||
}
|
||||
|
||||
@ -2199,7 +1665,6 @@ gtk_drag_context_drop_performed_cb (GdkDragContext *context,
|
||||
guint32 time_,
|
||||
GtkDragSourceInfo *info)
|
||||
{
|
||||
gtk_drag_end (info, time_);
|
||||
gtk_drag_drop (info, time_);
|
||||
}
|
||||
|
||||
@ -2242,120 +1707,6 @@ gtk_drag_context_dnd_finished_cb (GdkDragContext *context,
|
||||
gtk_drag_source_info_destroy (info);
|
||||
}
|
||||
|
||||
/* “motion-notify-event” callback during drag. */
|
||||
static gboolean
|
||||
gtk_drag_motion_cb (GtkWidget *widget,
|
||||
GdkEventMotion *event,
|
||||
gpointer data)
|
||||
{
|
||||
GtkDragSourceInfo *info = (GtkDragSourceInfo *)data;
|
||||
double x_root, y_root;
|
||||
|
||||
gdk_event_get_root_coords ((GdkEvent *)event, &x_root, &y_root);
|
||||
|
||||
gtk_drag_update (info, (int)x_root, (int)y_root, (GdkEvent *) event);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* “key-press/release-event” callback during drag */
|
||||
static gboolean
|
||||
gtk_drag_key_cb (GtkWidget *widget,
|
||||
GdkEventKey *event,
|
||||
gpointer data)
|
||||
{
|
||||
GtkDragSourceInfo *info = (GtkDragSourceInfo *)data;
|
||||
|
||||
if (gdk_event_get_event_type ((GdkEvent *)event) == GDK_KEY_PRESS)
|
||||
{
|
||||
guint keyval;
|
||||
guint32 time;
|
||||
|
||||
gdk_event_get_keyval ((GdkEvent *)event, &keyval);
|
||||
time = gdk_event_get_time ((GdkEvent *)event);
|
||||
|
||||
switch (keyval)
|
||||
{
|
||||
case GDK_KEY_Escape:
|
||||
gtk_drag_cancel_internal (info, GTK_DRAG_RESULT_USER_CANCELLED, time);
|
||||
break;
|
||||
|
||||
case GDK_KEY_space:
|
||||
case GDK_KEY_Return:
|
||||
case GDK_KEY_ISO_Enter:
|
||||
case GDK_KEY_KP_Enter:
|
||||
case GDK_KEY_KP_Space:
|
||||
if ((gdk_drag_context_get_selected_action (info->context) != 0) &&
|
||||
(gdk_drag_context_get_dest_window (info->context) != NULL))
|
||||
{
|
||||
gtk_drag_end (info, time);
|
||||
gtk_drag_drop (info, time);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_drag_cancel_internal (info, GTK_DRAG_RESULT_NO_TARGET, time);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_drag_grab_notify_cb (GtkWidget *widget,
|
||||
gboolean was_grabbed,
|
||||
gpointer data)
|
||||
{
|
||||
GtkDragSourceInfo *info = (GtkDragSourceInfo *)data;
|
||||
GdkDevice *pointer;
|
||||
|
||||
pointer = gdk_drag_context_get_device (info->context);
|
||||
|
||||
if (gtk_widget_device_is_shadowed (widget, pointer))
|
||||
{
|
||||
/* We have to block callbacks to avoid recursion here, because
|
||||
* 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_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);
|
||||
}
|
||||
}
|
||||
|
||||
/* “button-release-event” callback during drag */
|
||||
static gboolean
|
||||
gtk_drag_button_release_cb (GtkWidget *widget,
|
||||
GdkEventButton *event,
|
||||
gpointer data)
|
||||
{
|
||||
GtkDragSourceInfo *info = (GtkDragSourceInfo *)data;
|
||||
guint button;
|
||||
guint32 time;
|
||||
|
||||
gdk_event_get_button ((GdkEvent *)event, &button);
|
||||
time = gdk_event_get_time ((GdkEvent *)event);
|
||||
|
||||
if (button != info->button)
|
||||
return FALSE;
|
||||
|
||||
if ((gdk_drag_context_get_selected_action (info->context) != 0) &&
|
||||
(gdk_drag_context_get_dest_window (info->context) != NULL))
|
||||
{
|
||||
gtk_drag_end (info, time);
|
||||
gtk_drag_drop (info, time);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_drag_cancel_internal (info, GTK_DRAG_RESULT_NO_TARGET, time);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_drag_abort_timeout (gpointer data)
|
||||
{
|
||||
@ -2365,7 +1716,7 @@ gtk_drag_abort_timeout (gpointer data)
|
||||
info->drop_timeout = 0;
|
||||
gtk_drag_drop_finished (info, GTK_DRAG_RESULT_TIMEOUT_EXPIRED, time);
|
||||
|
||||
return FALSE;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -52,8 +52,6 @@ void gtk_drag_set_icon_definition (GdkDragContext
|
||||
GtkImageDefinition *def,
|
||||
gint hot_x,
|
||||
gint hot_y);
|
||||
void _gtk_drag_source_handle_event (GtkWidget *widget,
|
||||
GdkEvent *event);
|
||||
void _gtk_drag_dest_handle_event (GtkWidget *toplevel,
|
||||
GdkEvent *event);
|
||||
|
||||
|
@ -1895,7 +1895,6 @@ gtk_main_do_event (GdkEvent *event)
|
||||
|
||||
case GDK_DRAG_STATUS:
|
||||
case GDK_DROP_FINISHED:
|
||||
_gtk_drag_source_handle_event (event_widget, event);
|
||||
break;
|
||||
case GDK_DRAG_ENTER:
|
||||
case GDK_DRAG_LEAVE:
|
||||
|
Loading…
Reference in New Issue
Block a user