Add gdk_drag_context_get_drag_window

This makes gdk_wayland_drag_context_get_dnd_window
backend-independent API and adds an implementation
for X11.
This commit is contained in:
Matthias Clasen 2015-12-01 23:33:53 -05:00
parent d46b67dc79
commit fff8297a50
6 changed files with 76 additions and 0 deletions

View File

@ -967,6 +967,7 @@ gdk_drag_context_set_device
gdk_drag_context_get_source_window
gdk_drag_context_get_dest_window
gdk_drag_context_get_protocol
gdk_drag_context_get_drag_window
<SUBSECTION Standard>
GDK_DRAG_CONTEXT

View File

@ -454,3 +454,29 @@ gdk_drag_get_selection (GdkDragContext *context)
return GDK_DRAG_CONTEXT_GET_CLASS (context)->get_selection (context);
}
/**
* gdk_drag_context_get_drag_window:
* @context: a #GdkDragContext
*
* Returns the window on which the drag icon should be rendered
* during the drag operation. Note that the window may not be
* available until the drag operation has begun. GDK will move
* the window in accordance with the ongoing drag operation.
* The window is owned by @context and will be destroyed when
* the drag operation is over.
*
* Returns: (transfer none): the drag window, or %NULL
*
* Since: 3.20
*/
GdkWindow *
gdk_drag_context_get_drag_window (GdkDragContext *context)
{
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL);
if (GDK_DRAG_CONTEXT_GET_CLASS (context)->get_drag_window)
return GDK_DRAG_CONTEXT_GET_CLASS (context)->get_drag_window (context);
return NULL;
}

View File

@ -171,6 +171,9 @@ void gdk_drag_abort (GdkDragContext *context,
GDK_AVAILABLE_IN_ALL
gboolean gdk_drag_drop_succeeded (GdkDragContext *context);
GDK_AVAILABLE_IN_3_20
GdkWindow *gdk_drag_context_get_drag_window (GdkDragContext *context);
G_END_DECLS
#endif /* __GDK_DND_H__ */

View File

@ -62,6 +62,7 @@ struct _GdkDragContextClass {
gboolean success,
guint32 time_);
gboolean (*drop_status) (GdkDragContext *context);
GdkWindow* (*get_drag_window) (GdkDragContext *context);
};
struct _GdkDragContext {
@ -73,6 +74,7 @@ struct _GdkDragContext {
gboolean is_source;
GdkWindow *source_window;
GdkWindow *dest_window;
GdkWindow *drag_window;
GList *targets;
GdkDragAction actions;

View File

@ -293,6 +293,12 @@ gdk_wayland_drag_context_init (GdkWaylandDragContext *context_wayland)
context->actions = GDK_ACTION_COPY | GDK_ACTION_MOVE;
}
static GdkWindow *
gdk_wayland_drag_context_get_drag_window (GdkDragContext *context)
{
return GDK_WAYLAND_DRAG_CONTEXT (context)->dnd_window;
}
static void
gdk_wayland_drag_context_class_init (GdkWaylandDragContextClass *klass)
{
@ -310,6 +316,7 @@ gdk_wayland_drag_context_class_init (GdkWaylandDragContextClass *klass)
context_class->drop_finish = gdk_wayland_drag_context_drop_finish;
context_class->drop_status = gdk_wayland_drag_context_drop_status;
context_class->get_selection = gdk_wayland_drag_context_get_selection;
context_class->get_drag_window = gdk_wayland_drag_context_get_drag_window;
}
GdkDragProtocol

View File

@ -85,6 +85,8 @@ struct _GdkX11DragContext
GSList *window_caches;
GdkWindow *drag_window;
Window dest_xid; /* The last window we looked up */
Window drop_xid; /* The (non-proxied) window that is receiving drops */
guint xdnd_targets_set : 1; /* Whether we've already set XdndTypeList */
@ -183,6 +185,12 @@ static void gdk_x11_drag_context_drop_finish (GdkDragContext *context,
static gboolean gdk_x11_drag_context_drop_status (GdkDragContext *context);
static GdkAtom gdk_x11_drag_context_get_selection (GdkDragContext *context);
static GdkWindow *
gdk_x11_drag_context_get_drag_window (GdkDragContext *context)
{
return GDK_X11_DRAG_CONTEXT (context)->drag_window;
}
static void
gdk_x11_drag_context_class_init (GdkX11DragContextClass *klass)
{
@ -200,6 +208,7 @@ gdk_x11_drag_context_class_init (GdkX11DragContextClass *klass)
context_class->drop_finish = gdk_x11_drag_context_drop_finish;
context_class->drop_status = gdk_x11_drag_context_drop_status;
context_class->get_selection = gdk_x11_drag_context_get_selection;
context_class->get_drag_window = gdk_x11_drag_context_get_drag_window;
}
static void
@ -1914,6 +1923,26 @@ gdk_drag_do_leave (GdkX11DragContext *context_x11,
}
}
static GdkWindow *
create_drag_window (GdkScreen *screen)
{
GdkWindowAttr attrs;
guint mask;
attrs.x = attrs.y = 0;
attrs.width = attrs.height = 100;
attrs.wclass = GDK_INPUT_OUTPUT;
attrs.window_type = GDK_WINDOW_TEMP;
attrs.type_hint = GDK_WINDOW_TYPE_HINT_DND;
attrs.visual = gdk_screen_get_rgba_visual (screen);
if (!attrs.visual)
attrs.visual = gdk_screen_get_system_visual (screen);
mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_TYPE_HINT;
return gdk_window_new (gdk_screen_get_root_window (screen), &attrs, mask);
}
GdkDragContext *
_gdk_x11_window_drag_begin (GdkWindow *window,
GdkDevice *device,
@ -1934,6 +1963,8 @@ _gdk_x11_window_drag_begin (GdkWindow *window,
gdk_drag_context_set_device (context, device);
GDK_X11_DRAG_CONTEXT (context)->drag_window = create_drag_window (gdk_window_get_screen (window));
return context;
}
@ -2088,6 +2119,12 @@ gdk_x11_drag_context_drag_motion (GdkDragContext *context,
GdkX11DragContext *context_x11 = GDK_X11_DRAG_CONTEXT (context);
GdkWindowImplX11 *impl;
if (context_x11->drag_window)
{
gdk_window_move (context_x11->drag_window, x_root, y_root);
gdk_window_raise (context_x11->drag_window);
}
context_x11->old_actions = context->actions;
context->actions = possible_actions;