gdk: Remove gdk_drag_manage_dnd()

Instead, pass the actions as part of gdk_drag_begin() and insist DND is
always managed.

A new side effect is that gdk_drag_begin() can now return %NULL.
This commit is contained in:
Benjamin Otte 2017-12-11 01:45:31 +01:00
parent 7e0844d92f
commit 643a6c2311
13 changed files with 85 additions and 174 deletions

View File

@ -869,7 +869,6 @@ gdk_drag_context_get_source_window
gdk_drag_context_get_dest_window
gdk_drag_context_get_drag_window
gdk_drag_context_set_hotspot
gdk_drag_context_manage_dnd
<SUBSECTION Standard>
GDK_DRAG_CONTEXT

View File

@ -87,6 +87,7 @@ GdkDragContext *
_gdk_broadway_window_drag_begin (GdkWindow *window,
GdkDevice *device,
GdkContentFormats *formats,
GdkDragAction actions,
gint dx,
gint dy)
{

View File

@ -50,8 +50,9 @@ void _gdk_broadway_window_register_dnd (GdkWindow *window);
GdkDragContext * _gdk_broadway_window_drag_begin (GdkWindow *window,
GdkDevice *device,
GdkContentFormats *formats,
gint x_root,
gint y_root);
GdkDragAction actions,
gint dx,
gint dy);
void _gdk_broadway_window_translate (GdkWindow *window,
cairo_region_t *area,
gint dx,

View File

@ -376,10 +376,6 @@ gdk_drag_context_class_init (GdkDragContextClass *klass)
*
* The drag and drop operation was cancelled.
*
* This signal will only be emitted if the #GdkDragContext manages
* the drag and drop operation. See gdk_drag_context_manage_dnd()
* for more information.
*
* Since: 3.20
*/
signals[CANCEL] =
@ -398,10 +394,6 @@ gdk_drag_context_class_init (GdkDragContextClass *klass)
*
* The drag and drop operation was performed on an accepting client.
*
* This signal will only be emitted if the #GdkDragContext manages
* the drag and drop operation. See gdk_drag_context_manage_dnd()
* for more information.
*
* Since: 3.20
*/
signals[DROP_PERFORMED] =
@ -421,10 +413,6 @@ gdk_drag_context_class_init (GdkDragContextClass *klass)
* finished reading all data. The drag source can now free all
* miscellaneous data.
*
* This signal will only be emitted if the #GdkDragContext manages
* the drag and drop operation. See gdk_drag_context_manage_dnd()
* for more information.
*
* Since: 3.20
*/
signals[DND_FINISHED] =
@ -443,10 +431,6 @@ gdk_drag_context_class_init (GdkDragContextClass *klass)
*
* A new action is being chosen for the drag and drop operation.
*
* This signal will only be emitted if the #GdkDragContext manages
* the drag and drop operation. See gdk_drag_context_manage_dnd()
* for more information.
*
* Since: 3.20
*/
signals[ACTION_CHANGED] =
@ -799,47 +783,6 @@ gdk_drag_drop_done (GdkDragContext *context,
GDK_DRAG_CONTEXT_GET_CLASS (context)->drop_done (context, success);
}
/**
* gdk_drag_context_manage_dnd:
* @context: a #GdkDragContext
* @ipc_window: Window to use for IPC messaging/events
* @actions: the actions supported by the drag source
*
* Requests the drag and drop operation to be managed by @context.
* When a drag and drop operation becomes managed, the #GdkDragContext
* will internally handle all input and source-side #GdkEventDND events
* as required by the windowing system.
*
* Once the drag and drop operation is managed, the drag context will
* emit the following signals:
* - The #GdkDragContext::action-changed signal whenever the final action
* to be performed by the drag and drop operation changes.
* - The #GdkDragContext::drop-performed signal after the user performs
* the drag and drop gesture (typically by releasing the mouse button).
* - The #GdkDragContext::dnd-finished signal after the drag and drop
* operation concludes (after all #GdkSelection transfers happen).
* - The #GdkDragContext::cancel signal if the drag and drop operation is
* finished but doesn't happen over an accepting destination, or is
* cancelled through other means.
*
* Returns: #TRUE if the drag and drop operation is managed.
*
* Since: 3.20
**/
gboolean
gdk_drag_context_manage_dnd (GdkDragContext *context,
GdkWindow *ipc_window,
GdkDragAction actions)
{
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), FALSE);
g_return_val_if_fail (GDK_IS_WINDOW (ipc_window), FALSE);
if (GDK_DRAG_CONTEXT_GET_CLASS (context)->manage_dnd)
return GDK_DRAG_CONTEXT_GET_CLASS (context)->manage_dnd (context, ipc_window, actions);
return FALSE;
}
void
gdk_drag_context_set_cursor (GdkDragContext *context,
GdkCursor *cursor)

View File

@ -137,6 +137,7 @@ GDK_AVAILABLE_IN_ALL
GdkDragContext * gdk_drag_begin (GdkWindow *window,
GdkDevice *device,
GdkContentFormats *formats,
GdkDragAction actions,
gint dx,
gint dy);
@ -155,10 +156,6 @@ void gdk_drag_context_set_hotspot (GdkDragContext *context,
gint hot_x,
gint hot_y);
GDK_AVAILABLE_IN_3_20
gboolean gdk_drag_context_manage_dnd (GdkDragContext *context,
GdkWindow *ipc_window,
GdkDragAction actions);
G_END_DECLS
#endif /* __GDK_DND_H__ */

View File

@ -105,9 +105,6 @@ struct _GdkDragContextClass {
void (*drop_done) (GdkDragContext *context,
gboolean success);
gboolean (*manage_dnd) (GdkDragContext *context,
GdkWindow *ipc_window,
GdkDragAction actions);
void (*set_cursor) (GdkDragContext *context,
GdkCursor *cursor);
void (*cancel) (GdkDragContext *context,

View File

@ -6928,6 +6928,7 @@ gdk_window_register_dnd (GdkWindow *window)
* @window: the source window for this drag
* @device: the device that controls this drag
* @formats: (transfer none): the offered formats
* @actions: the actions supported by this drag
* @dx: the x offset to @device's position where the drag nominally started
* @dy: the y offset to @device's position where the drag nominally started
*
@ -6935,16 +6936,18 @@ gdk_window_register_dnd (GdkWindow *window)
*
* This function is called by the drag source.
*
* Returns: (transfer full): a newly created #GdkDragContext
* Returns: (transfer full) (nullable): a newly created #GdkDragContext or
* %NULL on error.
*/
GdkDragContext *
gdk_drag_begin (GdkWindow *window,
GdkDevice *device,
GdkContentFormats *formats,
gint x_root,
gint y_root)
GdkDragAction actions,
gint dx,
gint dy)
{
return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->drag_begin (window, device, formats, x_root, y_root);
return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->drag_begin (window, device, formats, actions, dx, dy);
}
/**

View File

@ -220,8 +220,9 @@ struct _GdkWindowImplClass
GdkDragContext * (*drag_begin) (GdkWindow *window,
GdkDevice *device,
GdkContentFormats *formats,
gint x_root,
gint y_root);
GdkDragAction actions,
gint dx,
gint dy);
void (*process_updates_recurse) (GdkWindow *window,
cairo_region_t *region);

View File

@ -454,40 +454,6 @@ gdk_wayland_drag_context_set_hotspot (GdkDragContext *context,
gdk_window_invalidate_rect (context_wayland->dnd_window, &damage_rect, FALSE);
}
static gboolean
gdk_wayland_drag_context_manage_dnd (GdkDragContext *context,
GdkWindow *ipc_window,
GdkDragAction actions)
{
GdkWaylandDragContext *context_wayland;
GdkWaylandDisplay *display_wayland;
GdkDevice *device;
GdkWindow *toplevel;
device = gdk_drag_context_get_device (context);
display_wayland = GDK_WAYLAND_DISPLAY (gdk_device_get_display (device));
toplevel = _gdk_device_window_at_position (device, NULL, NULL, NULL, TRUE);
context_wayland = GDK_WAYLAND_DRAG_CONTEXT (context);
if (display_wayland->data_device_manager_version >=
WL_DATA_SOURCE_SET_ACTIONS_SINCE_VERSION)
{
wl_data_source_set_actions (context_wayland->data_source,
gdk_to_wl_actions (actions));
}
wl_data_device_start_drag (gdk_wayland_device_get_data_device (device),
context_wayland->data_source,
gdk_wayland_window_get_wl_surface (toplevel),
context_wayland->dnd_surface,
_gdk_wayland_display_get_serial (display_wayland));
gdk_seat_ungrab (gdk_device_get_seat (device));
return TRUE;
}
static void
gdk_wayland_drag_context_set_cursor (GdkDragContext *context,
GdkCursor *cursor)
@ -557,7 +523,6 @@ gdk_wayland_drag_context_class_init (GdkWaylandDragContextClass *klass)
context_class->get_drag_window = gdk_wayland_drag_context_get_drag_window;
context_class->set_hotspot = gdk_wayland_drag_context_set_hotspot;
context_class->drop_done = gdk_wayland_drag_context_drop_done;
context_class->manage_dnd = gdk_wayland_drag_context_manage_dnd;
context_class->set_cursor = gdk_wayland_drag_context_set_cursor;
context_class->action_changed = gdk_wayland_drag_context_action_changed;
context_class->drop_performed = gdk_wayland_drag_context_drop_performed;
@ -586,16 +551,21 @@ GdkDragContext *
_gdk_wayland_window_drag_begin (GdkWindow *window,
GdkDevice *device,
GdkContentFormats *formats,
GdkDragAction actions,
gint dx,
gint dy)
{
GdkWaylandDragContext *context_wayland;
GdkDragContext *context;
GdkWaylandDisplay *display_wayland;
GdkWindow *toplevel;
const char *const *mimetypes;
gsize i, n_mimetypes;
display_wayland = GDK_WAYLAND_DISPLAY (gdk_device_get_display (device));
context_wayland = g_object_new (GDK_TYPE_WAYLAND_DRAG_CONTEXT,
"display", gdk_window_get_display (window),
"display", display_wayland,
NULL);
context = GDK_DRAG_CONTEXT (context_wayland);
context->source_window = g_object_ref (window);
@ -616,9 +586,27 @@ _gdk_wayland_window_drag_begin (GdkWindow *window,
wl_data_source_offer (context_wayland->data_source, mimetypes[i]);
}
toplevel = _gdk_device_window_at_position (device, NULL, NULL, NULL, TRUE);
if (display_wayland->data_device_manager_version >=
WL_DATA_SOURCE_SET_ACTIONS_SINCE_VERSION)
{
wl_data_source_set_actions (context_wayland->data_source,
gdk_to_wl_actions (actions));
}
wl_data_device_start_drag (gdk_wayland_device_get_data_device (device),
context_wayland->data_source,
gdk_wayland_window_get_wl_surface (toplevel),
context_wayland->dnd_surface,
_gdk_wayland_display_get_serial (display_wayland));
gdk_seat_ungrab (gdk_device_get_seat (device));
return context;
}
GdkDragContext *
_gdk_wayland_drop_context_new (GdkDisplay *display,
struct wl_data_device *data_device)

View File

@ -94,8 +94,9 @@ void _gdk_wayland_window_register_dnd (GdkWindow *window);
GdkDragContext *_gdk_wayland_window_drag_begin (GdkWindow *window,
GdkDevice *device,
GdkContentFormats *formats,
gint x_root,
gint y_root);
GdkDragAction actions,
gint dx,
gint dy);
void _gdk_wayland_window_offset_next_wl_buffer (GdkWindow *window,
int x,
int y);

View File

@ -235,9 +235,6 @@ static void gdk_x11_drag_context_set_hotspot (GdkDragContext *context,
gint hot_y);
static void gdk_x11_drag_context_drop_done (GdkDragContext *context,
gboolean success);
static gboolean gdk_x11_drag_context_manage_dnd (GdkDragContext *context,
GdkWindow *window,
GdkDragAction actions);
static void gdk_x11_drag_context_set_cursor (GdkDragContext *context,
GdkCursor *cursor);
static void gdk_x11_drag_context_cancel (GdkDragContext *context,
@ -396,7 +393,6 @@ gdk_x11_drag_context_class_init (GdkX11DragContextClass *klass)
context_class->get_drag_window = gdk_x11_drag_context_get_drag_window;
context_class->set_hotspot = gdk_x11_drag_context_set_hotspot;
context_class->drop_done = gdk_x11_drag_context_drop_done;
context_class->manage_dnd = gdk_x11_drag_context_manage_dnd;
context_class->set_cursor = gdk_x11_drag_context_set_cursor;
context_class->cancel = gdk_x11_drag_context_cancel;
context_class->drop_performed = gdk_x11_drag_context_drop_performed;
@ -2097,44 +2093,6 @@ create_drag_window (GdkDisplay *display)
return window;
}
GdkDragContext *
_gdk_x11_window_drag_begin (GdkWindow *window,
GdkDevice *device,
GdkContentFormats *formats,
gint dx,
gint dy)
{
GdkDragContext *context;
int x_root, y_root;
context = (GdkDragContext *) g_object_new (GDK_TYPE_X11_DRAG_CONTEXT,
"display", gdk_window_get_display (window),
NULL);
context->is_source = TRUE;
context->source_window = window;
g_object_ref (window);
context->formats = gdk_content_formats_ref (formats);
precache_target_list (context);
context->actions = 0;
gdk_drag_context_set_device (context, device);
gdk_device_get_position (device, &x_root, &y_root);
x_root += dx;
y_root += dy;
GDK_X11_DRAG_CONTEXT (context)->start_x = x_root;
GDK_X11_DRAG_CONTEXT (context)->start_y = y_root;
GDK_X11_DRAG_CONTEXT (context)->last_x = x_root;
GDK_X11_DRAG_CONTEXT (context)->last_y = y_root;
GDK_X11_DRAG_CONTEXT (context)->drag_window = create_drag_window (gdk_window_get_display(window));
return context;
}
Window
_gdk_x11_display_get_drag_protocol (GdkDisplay *display,
Window xid,
@ -2900,30 +2858,53 @@ drag_context_ungrab (GdkDragContext *context)
}
}
static gboolean
gdk_x11_drag_context_manage_dnd (GdkDragContext *context,
GdkWindow *ipc_window,
GdkDragAction actions)
GdkDragContext *
_gdk_x11_window_drag_begin (GdkWindow *window,
GdkDevice *device,
GdkContentFormats *formats,
GdkDragAction actions,
gint dx,
gint dy)
{
GdkX11DragContext *x11_context = GDK_X11_DRAG_CONTEXT (context);
GdkDragContext *context;
int x_root, y_root;
if (x11_context->ipc_window)
return FALSE;
context = (GdkDragContext *) g_object_new (GDK_TYPE_X11_DRAG_CONTEXT,
"display", gdk_window_get_display (window),
NULL);
context->is_source = TRUE;
context->source_window = window;
g_object_ref (window);
context->formats = gdk_content_formats_ref (formats);
precache_target_list (context);
gdk_drag_context_set_device (context, device);
gdk_device_get_position (device, &x_root, &y_root);
x_root += dx;
y_root += dy;
GDK_X11_DRAG_CONTEXT (context)->start_x = x_root;
GDK_X11_DRAG_CONTEXT (context)->start_y = y_root;
GDK_X11_DRAG_CONTEXT (context)->last_x = x_root;
GDK_X11_DRAG_CONTEXT (context)->last_y = y_root;
context->protocol = GDK_DRAG_PROTO_XDND;
x11_context->ipc_window = g_object_ref (ipc_window);
GDK_X11_DRAG_CONTEXT (context)->actions = actions;
GDK_X11_DRAG_CONTEXT (context)->ipc_window = g_object_ref (window);
if (drag_context_grab (context))
GDK_X11_DRAG_CONTEXT (context)->drag_window = create_drag_window (gdk_window_get_display(window));
if (!drag_context_grab (context))
{
x11_context->actions = actions;
move_drag_window (context, x11_context->start_x, x11_context->start_y);
return TRUE;
}
else
{
g_clear_object (&x11_context->ipc_window);
return FALSE;
g_object_unref (context);
return NULL;
}
move_drag_window (context, x_root, y_root);
return context;
}
static void

View File

@ -285,6 +285,7 @@ void _gdk_x11_window_register_dnd (GdkWindow *window);
GdkDragContext * _gdk_x11_window_drag_begin (GdkWindow *window,
GdkDevice *device,
GdkContentFormats *formats,
GdkDragAction actions,
gint x_root,
gint y_root);

View File

@ -1129,12 +1129,10 @@ gtk_drag_begin_internal (GtkWidget *widget,
dy = 0;
}
context = gdk_drag_begin (ipc_window, pointer, target_list, dx, dy);
if (!gdk_drag_context_manage_dnd (context, ipc_window, actions))
context = gdk_drag_begin (ipc_window, pointer, target_list, actions, dx, dy);
if (context == NULL)
{
gtk_drag_release_ipc_widget (ipc_widget);
g_object_unref (context);
return NULL;
}