2008-07-01 22:57:50 +00:00
|
|
|
/* GDK - The GIMP Drawing Kit
|
2002-10-07 22:43:26 +00:00
|
|
|
* Copyright (C) 1995-1999 Peter Mattis, Spencer Kimball and Josh MacDonald
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
2012-02-27 13:01:10 +00:00
|
|
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
2002-10-07 22:43:26 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
|
|
|
* file for a list of people on the GTK+ Team. See the ChangeLog
|
|
|
|
* files for a list of changes. These files are distributed with
|
|
|
|
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
|
|
|
*/
|
|
|
|
|
2008-06-22 14:28:52 +00:00
|
|
|
#include "config.h"
|
2010-10-15 02:05:51 +00:00
|
|
|
|
2018-07-02 11:39:09 +00:00
|
|
|
#include "gdkdragprivate.h"
|
2010-10-15 02:05:51 +00:00
|
|
|
#include "gdkdisplay.h"
|
2018-03-20 10:46:11 +00:00
|
|
|
#include "gdksurface.h"
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
#include "gdkintl.h"
|
2017-11-18 04:53:25 +00:00
|
|
|
#include "gdkcontentformats.h"
|
2017-12-13 14:03:53 +00:00
|
|
|
#include "gdkcontentprovider.h"
|
|
|
|
#include "gdkcontentserializer.h"
|
2016-01-13 19:51:19 +00:00
|
|
|
#include "gdkcursor.h"
|
2017-11-18 04:53:25 +00:00
|
|
|
#include "gdkenumtypes.h"
|
2017-08-05 13:34:39 +00:00
|
|
|
#include "gdkeventsprivate.h"
|
2016-01-13 19:51:19 +00:00
|
|
|
|
|
|
|
static struct {
|
|
|
|
GdkDragAction action;
|
|
|
|
const gchar *name;
|
|
|
|
GdkCursor *cursor;
|
|
|
|
} drag_cursors[] = {
|
|
|
|
{ GDK_ACTION_ASK, "dnd-ask", NULL },
|
|
|
|
{ GDK_ACTION_COPY, "dnd-copy", NULL },
|
|
|
|
{ GDK_ACTION_MOVE, "dnd-move", NULL },
|
|
|
|
{ GDK_ACTION_LINK, "dnd-link", NULL },
|
|
|
|
{ 0, "dnd-none", NULL },
|
|
|
|
};
|
2010-07-09 00:34:45 +00:00
|
|
|
|
2017-12-05 16:30:58 +00:00
|
|
|
enum {
|
|
|
|
PROP_0,
|
2017-12-13 14:03:53 +00:00
|
|
|
PROP_CONTENT,
|
2018-04-27 10:32:17 +00:00
|
|
|
PROP_DEVICE,
|
2017-12-05 16:30:58 +00:00
|
|
|
PROP_DISPLAY,
|
2017-12-13 14:03:53 +00:00
|
|
|
PROP_FORMATS,
|
2018-07-03 22:44:00 +00:00
|
|
|
PROP_SELECTED_ACTION,
|
|
|
|
PROP_ACTIONS,
|
2018-07-15 20:08:52 +00:00
|
|
|
PROP_SURFACE,
|
2017-12-05 16:30:58 +00:00
|
|
|
N_PROPERTIES
|
|
|
|
};
|
|
|
|
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
enum {
|
|
|
|
CANCEL,
|
|
|
|
DROP_PERFORMED,
|
|
|
|
DND_FINISHED,
|
|
|
|
N_SIGNALS
|
|
|
|
};
|
|
|
|
|
2018-07-15 19:47:43 +00:00
|
|
|
typedef struct _GdkDragPrivate GdkDragPrivate;
|
|
|
|
|
|
|
|
struct _GdkDragPrivate {
|
2018-07-15 20:08:52 +00:00
|
|
|
GdkSurface *surface;
|
2018-07-15 19:47:43 +00:00
|
|
|
|
|
|
|
GdkDisplay *display;
|
|
|
|
GdkDevice *device;
|
|
|
|
GdkContentFormats *formats;
|
|
|
|
GdkContentProvider *content;
|
|
|
|
|
|
|
|
GdkDragAction actions;
|
|
|
|
GdkDragAction selected_action;
|
|
|
|
|
|
|
|
guint drop_done : 1; /* Whether gdk_drag_drop_done() was performed */
|
|
|
|
};
|
|
|
|
|
2017-12-05 16:30:58 +00:00
|
|
|
static GParamSpec *properties[N_PROPERTIES] = { NULL, };
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
static guint signals[N_SIGNALS] = { 0 };
|
2018-06-29 17:34:14 +00:00
|
|
|
static GList *drags = NULL;
|
2002-10-07 22:43:26 +00:00
|
|
|
|
2018-07-15 19:47:43 +00:00
|
|
|
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdkDrag, gdk_drag, G_TYPE_OBJECT)
|
2018-04-30 11:14:29 +00:00
|
|
|
|
2010-06-08 19:21:18 +00:00
|
|
|
/**
|
|
|
|
* SECTION:dnd
|
2020-01-07 07:15:22 +00:00
|
|
|
* @Title: Drag And Drop
|
|
|
|
* @Short_description: Functions for controlling drag and drop handling
|
2010-06-08 19:21:18 +00:00
|
|
|
*
|
2020-01-07 07:15:22 +00:00
|
|
|
* These functions provide a low-level interface for drag and drop.
|
2010-06-08 19:21:18 +00:00
|
|
|
*
|
2018-07-12 11:53:50 +00:00
|
|
|
* The GdkDrag object represents the source side of an ongoing DND operation.
|
|
|
|
* It is created when a drag is started, and stays alive for duration of
|
2020-01-07 07:15:22 +00:00
|
|
|
* the DND operation. After a drag has been started with gdk_drag_begin(),
|
|
|
|
* the caller gets informed about the status of the ongoing drag operation
|
|
|
|
* with signals on the #GtkDrag object.
|
2018-07-12 11:53:50 +00:00
|
|
|
*
|
|
|
|
* The GdkDrop object represents the target side of an ongoing DND operation.
|
2020-01-07 07:15:22 +00:00
|
|
|
* Possible drop sites get informed about the status of the ongoing drag operation
|
|
|
|
* with events of type %GDK_DRAG_ENTER, %GDK_DRAG_LEAVE, %GDK_DRAG_MOTION and
|
|
|
|
* %GDK_DROP_START. The #GdkDrop object can be obtained from these #GdkEvents
|
|
|
|
* using gdk_event_get_drop().
|
|
|
|
*
|
|
|
|
* The actual data transfer is initiated from the target side via an async
|
|
|
|
* read, using one of the GdkDrop functions for this purpose: gdk_drop_read_async(),
|
2020-01-09 05:31:13 +00:00
|
|
|
* gdk_drop_read_value_async() or gdk_drop_read_text_async().
|
2018-07-12 11:53:50 +00:00
|
|
|
*
|
2020-01-07 07:15:22 +00:00
|
|
|
* GTK provides a higher level abstraction based on top of these functions,
|
|
|
|
* and so they are not normally needed in GTK applications. See the
|
2020-01-09 05:31:13 +00:00
|
|
|
* [Drag and Drop][gtk4-Drag-and-Drop] section of the GTK documentation
|
2018-07-12 11:53:50 +00:00
|
|
|
* for more information.
|
2010-06-08 19:21:18 +00:00
|
|
|
*/
|
|
|
|
|
2017-12-26 19:39:24 +00:00
|
|
|
/**
|
2018-06-29 17:34:14 +00:00
|
|
|
* GdkDrag:
|
2017-12-26 19:39:24 +00:00
|
|
|
*
|
2018-06-29 17:34:14 +00:00
|
|
|
* The GdkDrag struct contains only private fields and
|
2017-12-26 19:39:24 +00:00
|
|
|
* should not be accessed directly.
|
|
|
|
*/
|
|
|
|
|
2017-12-05 16:30:58 +00:00
|
|
|
/**
|
2018-06-29 17:34:14 +00:00
|
|
|
* gdk_drag_get_display:
|
|
|
|
* @drag: a #GdkDrag
|
2017-12-05 16:30:58 +00:00
|
|
|
*
|
2018-06-29 17:34:14 +00:00
|
|
|
* Gets the #GdkDisplay that the drag object was created for.
|
2017-12-05 16:30:58 +00:00
|
|
|
*
|
|
|
|
* Returns: (transfer none): a #GdkDisplay
|
|
|
|
**/
|
|
|
|
GdkDisplay *
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_get_display (GdkDrag *drag)
|
2017-12-05 16:30:58 +00:00
|
|
|
{
|
2018-07-15 19:47:43 +00:00
|
|
|
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
|
|
|
|
2018-06-29 17:34:14 +00:00
|
|
|
g_return_val_if_fail (GDK_IS_DRAG (drag), NULL);
|
2018-04-30 11:14:29 +00:00
|
|
|
|
2018-07-15 19:47:43 +00:00
|
|
|
return priv->display;
|
2017-12-05 16:30:58 +00:00
|
|
|
}
|
|
|
|
|
2010-05-25 15:54:16 +00:00
|
|
|
/**
|
2018-06-29 17:34:14 +00:00
|
|
|
* gdk_drag_get_formats:
|
|
|
|
* @drag: a #GdkDrag
|
2010-05-25 15:54:16 +00:00
|
|
|
*
|
2018-06-29 17:34:14 +00:00
|
|
|
* Retrieves the formats supported by this GdkDrag object.
|
2010-05-25 15:54:16 +00:00
|
|
|
*
|
2017-11-18 04:53:25 +00:00
|
|
|
* Returns: (transfer none): a #GdkContentFormats
|
2010-05-25 15:54:16 +00:00
|
|
|
**/
|
2017-11-18 04:53:25 +00:00
|
|
|
GdkContentFormats *
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_get_formats (GdkDrag *drag)
|
2010-05-25 15:54:16 +00:00
|
|
|
{
|
2018-07-15 19:47:43 +00:00
|
|
|
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
|
|
|
|
2018-06-29 17:34:14 +00:00
|
|
|
g_return_val_if_fail (GDK_IS_DRAG (drag), NULL);
|
2010-05-25 15:54:16 +00:00
|
|
|
|
2018-07-15 19:47:43 +00:00
|
|
|
return priv->formats;
|
2010-05-25 15:54:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-06-29 17:34:14 +00:00
|
|
|
* gdk_drag_get_actions:
|
|
|
|
* @drag: a #GdkDrag
|
2010-05-25 15:54:16 +00:00
|
|
|
*
|
2018-07-04 06:40:49 +00:00
|
|
|
* Determines the bitmask of possible actions proposed by the source.
|
2010-05-25 15:54:16 +00:00
|
|
|
*
|
2014-02-19 23:49:43 +00:00
|
|
|
* Returns: the #GdkDragAction flags
|
2010-05-25 15:54:16 +00:00
|
|
|
**/
|
|
|
|
GdkDragAction
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_get_actions (GdkDrag *drag)
|
2010-05-25 15:54:16 +00:00
|
|
|
{
|
2018-07-15 19:47:43 +00:00
|
|
|
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
|
|
|
|
2018-06-29 17:34:14 +00:00
|
|
|
g_return_val_if_fail (GDK_IS_DRAG (drag), 0);
|
2010-05-25 15:54:16 +00:00
|
|
|
|
2018-07-15 19:47:43 +00:00
|
|
|
return priv->actions;
|
2010-05-25 15:54:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-06-29 17:34:14 +00:00
|
|
|
* gdk_drag_get_selected_action:
|
|
|
|
* @drag: a #GdkDrag
|
2010-05-25 15:54:16 +00:00
|
|
|
*
|
|
|
|
* Determines the action chosen by the drag destination.
|
|
|
|
*
|
2014-02-19 23:49:43 +00:00
|
|
|
* Returns: a #GdkDragAction value
|
2010-05-25 15:54:16 +00:00
|
|
|
**/
|
|
|
|
GdkDragAction
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_get_selected_action (GdkDrag *drag)
|
2010-05-25 15:54:16 +00:00
|
|
|
{
|
2018-07-15 19:47:43 +00:00
|
|
|
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
|
|
|
|
2018-06-29 17:34:14 +00:00
|
|
|
g_return_val_if_fail (GDK_IS_DRAG (drag), 0);
|
2010-05-25 15:54:16 +00:00
|
|
|
|
2018-07-15 19:47:43 +00:00
|
|
|
return priv->selected_action;
|
2010-05-25 15:54:16 +00:00
|
|
|
}
|
|
|
|
|
2010-12-10 06:27:10 +00:00
|
|
|
/**
|
2018-06-29 17:34:14 +00:00
|
|
|
* gdk_drag_get_device:
|
|
|
|
* @drag: a #GdkDrag
|
2010-12-10 06:27:10 +00:00
|
|
|
*
|
2018-06-29 17:34:14 +00:00
|
|
|
* Returns the #GdkDevice associated to the GdkDrag object.
|
2010-12-10 06:27:10 +00:00
|
|
|
*
|
2018-06-29 17:34:14 +00:00
|
|
|
* Returns: (transfer none): The #GdkDevice associated to @drag.
|
2010-12-10 06:27:10 +00:00
|
|
|
**/
|
|
|
|
GdkDevice *
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_get_device (GdkDrag *drag)
|
2010-12-10 06:27:10 +00:00
|
|
|
{
|
2018-07-15 19:47:43 +00:00
|
|
|
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
|
|
|
|
2018-06-29 17:34:14 +00:00
|
|
|
g_return_val_if_fail (GDK_IS_DRAG (drag), NULL);
|
2010-12-10 06:27:10 +00:00
|
|
|
|
2018-07-15 19:47:43 +00:00
|
|
|
return priv->device;
|
2010-12-10 06:27:10 +00:00
|
|
|
}
|
|
|
|
|
2020-02-24 13:32:15 +00:00
|
|
|
/**
|
|
|
|
* gdk_drag_get_content:
|
|
|
|
* @drag: a #GdkDrag
|
|
|
|
*
|
|
|
|
* Returns the #GdkContentProvider associated to the GdkDrag object.
|
|
|
|
*
|
|
|
|
* Returns: (transfer none): The #GdkContentProvider associated to @drag.
|
|
|
|
**/
|
|
|
|
GdkContentProvider *
|
|
|
|
gdk_drag_get_content (GdkDrag *drag)
|
|
|
|
{
|
|
|
|
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
|
|
|
|
|
|
|
g_return_val_if_fail (GDK_IS_DRAG (drag), NULL);
|
|
|
|
|
|
|
|
return priv->content;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gdk_drag_get_surface:
|
|
|
|
* @drag: a #GdkDrag
|
|
|
|
*
|
|
|
|
* Returns the #GdkSurface where the drag originates.
|
|
|
|
*
|
|
|
|
* Returns: (transfer none): The #GdkSurface where the drag originates
|
|
|
|
**/
|
|
|
|
GdkSurface *
|
|
|
|
gdk_drag_get_surface (GdkDrag *drag)
|
|
|
|
{
|
|
|
|
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
|
|
|
|
|
|
|
g_return_val_if_fail (GDK_IS_DRAG (drag), NULL);
|
|
|
|
|
|
|
|
return priv->surface;
|
|
|
|
}
|
|
|
|
|
2010-12-10 06:27:10 +00:00
|
|
|
static void
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_init (GdkDrag *drag)
|
2010-12-10 06:27:10 +00:00
|
|
|
{
|
2018-06-29 17:34:14 +00:00
|
|
|
drags = g_list_prepend (drags, drag);
|
2010-12-10 06:27:10 +00:00
|
|
|
}
|
|
|
|
|
2017-12-05 16:30:58 +00:00
|
|
|
static void
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_set_property (GObject *gobject,
|
|
|
|
guint prop_id,
|
|
|
|
const GValue *value,
|
|
|
|
GParamSpec *pspec)
|
2017-12-05 16:30:58 +00:00
|
|
|
{
|
2018-06-29 17:34:14 +00:00
|
|
|
GdkDrag *drag = GDK_DRAG (gobject);
|
2018-07-15 19:47:43 +00:00
|
|
|
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
2017-12-05 16:30:58 +00:00
|
|
|
|
|
|
|
switch (prop_id)
|
|
|
|
{
|
2017-12-13 14:03:53 +00:00
|
|
|
case PROP_CONTENT:
|
2018-07-15 19:47:43 +00:00
|
|
|
priv->content = g_value_dup_object (value);
|
|
|
|
if (priv->content)
|
2018-05-07 15:31:26 +00:00
|
|
|
{
|
2018-07-15 19:47:43 +00:00
|
|
|
g_assert (priv->formats == NULL);
|
|
|
|
priv->formats = gdk_content_provider_ref_formats (priv->content);
|
2018-05-07 15:31:26 +00:00
|
|
|
}
|
2017-12-13 14:03:53 +00:00
|
|
|
break;
|
|
|
|
|
2018-04-27 10:32:17 +00:00
|
|
|
case PROP_DEVICE:
|
2018-07-15 19:47:43 +00:00
|
|
|
priv->device = g_value_dup_object (value);
|
|
|
|
g_assert (priv->device != NULL);
|
|
|
|
priv->display = gdk_device_get_display (priv->device);
|
2017-12-05 16:30:58 +00:00
|
|
|
break;
|
|
|
|
|
2018-05-07 15:31:26 +00:00
|
|
|
case PROP_FORMATS:
|
2018-07-15 19:47:43 +00:00
|
|
|
if (priv->formats)
|
2018-05-07 15:31:26 +00:00
|
|
|
{
|
|
|
|
GdkContentFormats *override = g_value_dup_boxed (value);
|
|
|
|
if (override)
|
|
|
|
{
|
2018-07-15 19:47:43 +00:00
|
|
|
gdk_content_formats_unref (priv->formats);
|
|
|
|
priv->formats = override;
|
2018-05-07 15:31:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-07-15 19:47:43 +00:00
|
|
|
priv->formats = g_value_dup_boxed (value);
|
|
|
|
g_assert (priv->formats != NULL);
|
2018-05-07 15:31:26 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2018-07-03 22:44:00 +00:00
|
|
|
case PROP_SELECTED_ACTION:
|
2018-07-02 23:16:47 +00:00
|
|
|
{
|
|
|
|
GdkDragAction action = g_value_get_flags (value);
|
2018-07-03 22:44:00 +00:00
|
|
|
gdk_drag_set_selected_action (drag, action);
|
2018-07-02 23:16:47 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2018-07-03 22:52:21 +00:00
|
|
|
case PROP_ACTIONS:
|
|
|
|
{
|
|
|
|
GdkDragAction actions = g_value_get_flags (value);
|
2018-07-04 06:32:27 +00:00
|
|
|
gdk_drag_set_actions (drag, actions);
|
2018-07-03 22:52:21 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2018-07-15 20:08:52 +00:00
|
|
|
case PROP_SURFACE:
|
|
|
|
priv->surface = g_value_dup_object (value);
|
|
|
|
g_assert (priv->surface != NULL);
|
|
|
|
break;
|
|
|
|
|
2017-12-05 16:30:58 +00:00
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_get_property (GObject *gobject,
|
|
|
|
guint prop_id,
|
|
|
|
GValue *value,
|
|
|
|
GParamSpec *pspec)
|
2017-12-05 16:30:58 +00:00
|
|
|
{
|
2018-06-29 17:34:14 +00:00
|
|
|
GdkDrag *drag = GDK_DRAG (gobject);
|
2018-07-15 19:47:43 +00:00
|
|
|
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
2017-12-05 16:30:58 +00:00
|
|
|
|
|
|
|
switch (prop_id)
|
|
|
|
{
|
2017-12-13 14:03:53 +00:00
|
|
|
case PROP_CONTENT:
|
2018-07-15 19:47:43 +00:00
|
|
|
g_value_set_object (value, priv->content);
|
2017-12-13 14:03:53 +00:00
|
|
|
break;
|
|
|
|
|
2018-04-27 10:32:17 +00:00
|
|
|
case PROP_DEVICE:
|
2018-07-15 19:47:43 +00:00
|
|
|
g_value_set_object (value, priv->device);
|
2018-04-27 10:32:17 +00:00
|
|
|
break;
|
|
|
|
|
2017-12-05 16:30:58 +00:00
|
|
|
case PROP_DISPLAY:
|
2018-07-15 19:47:43 +00:00
|
|
|
g_value_set_object (value, priv->display);
|
2017-12-05 16:30:58 +00:00
|
|
|
break;
|
|
|
|
|
2017-12-13 14:03:53 +00:00
|
|
|
case PROP_FORMATS:
|
2018-07-15 19:47:43 +00:00
|
|
|
g_value_set_boxed (value, priv->formats);
|
2017-12-13 14:03:53 +00:00
|
|
|
break;
|
|
|
|
|
2018-07-03 22:44:00 +00:00
|
|
|
case PROP_SELECTED_ACTION:
|
2018-07-15 19:47:43 +00:00
|
|
|
g_value_set_flags (value, priv->selected_action);
|
2018-07-02 23:16:47 +00:00
|
|
|
break;
|
|
|
|
|
2018-07-03 22:52:21 +00:00
|
|
|
case PROP_ACTIONS:
|
2018-07-15 19:47:43 +00:00
|
|
|
g_value_set_flags (value, priv->actions);
|
2018-07-03 22:52:21 +00:00
|
|
|
break;
|
|
|
|
|
2018-07-15 20:08:52 +00:00
|
|
|
case PROP_SURFACE:
|
|
|
|
g_value_set_object (value, priv->surface);
|
|
|
|
break;
|
|
|
|
|
2017-12-05 16:30:58 +00:00
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-10 06:27:10 +00:00
|
|
|
static void
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_finalize (GObject *object)
|
2010-12-10 06:27:10 +00:00
|
|
|
{
|
2018-06-29 17:34:14 +00:00
|
|
|
GdkDrag *drag = GDK_DRAG (object);
|
2018-07-15 19:47:43 +00:00
|
|
|
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
2010-12-10 06:27:10 +00:00
|
|
|
|
2018-06-29 17:34:14 +00:00
|
|
|
drags = g_list_remove (drags, drag);
|
2017-12-13 14:03:53 +00:00
|
|
|
|
2018-07-15 19:47:43 +00:00
|
|
|
g_clear_object (&priv->content);
|
|
|
|
g_clear_pointer (&priv->formats, gdk_content_formats_unref);
|
2010-12-10 06:27:10 +00:00
|
|
|
|
2018-07-15 20:08:52 +00:00
|
|
|
g_clear_object (&priv->surface);
|
2010-12-10 06:27:10 +00:00
|
|
|
|
2018-06-29 17:34:14 +00:00
|
|
|
G_OBJECT_CLASS (gdk_drag_parent_class)->finalize (object);
|
2010-12-10 06:27:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_class_init (GdkDragClass *klass)
|
2010-12-10 06:27:10 +00:00
|
|
|
{
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
|
2018-06-29 17:34:14 +00:00
|
|
|
object_class->get_property = gdk_drag_get_property;
|
|
|
|
object_class->set_property = gdk_drag_set_property;
|
|
|
|
object_class->finalize = gdk_drag_finalize;
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
|
2017-12-13 14:03:53 +00:00
|
|
|
/**
|
2018-06-29 17:34:14 +00:00
|
|
|
* GdkDrag:content:
|
2017-12-13 14:03:53 +00:00
|
|
|
*
|
2018-06-29 17:34:14 +00:00
|
|
|
* The #GdkContentProvider.
|
2017-12-13 14:03:53 +00:00
|
|
|
*/
|
|
|
|
properties[PROP_CONTENT] =
|
|
|
|
g_param_spec_object ("content",
|
|
|
|
"Content",
|
|
|
|
"The content being dragged",
|
|
|
|
GDK_TYPE_CONTENT_PROVIDER,
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
G_PARAM_CONSTRUCT_ONLY |
|
|
|
|
G_PARAM_STATIC_STRINGS |
|
|
|
|
G_PARAM_EXPLICIT_NOTIFY);
|
|
|
|
|
2018-04-27 10:32:17 +00:00
|
|
|
/**
|
2018-06-29 17:34:14 +00:00
|
|
|
* GdkDrag:device:
|
2018-04-27 10:32:17 +00:00
|
|
|
*
|
|
|
|
* The #GdkDevice that is performing the drag.
|
|
|
|
*/
|
|
|
|
properties[PROP_DEVICE] =
|
|
|
|
g_param_spec_object ("device",
|
|
|
|
"Device",
|
|
|
|
"The device performing the drag",
|
|
|
|
GDK_TYPE_DEVICE,
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
G_PARAM_CONSTRUCT_ONLY |
|
|
|
|
G_PARAM_STATIC_STRINGS |
|
|
|
|
G_PARAM_EXPLICIT_NOTIFY);
|
|
|
|
|
2017-12-05 16:30:58 +00:00
|
|
|
/**
|
2018-06-29 17:34:14 +00:00
|
|
|
* GdkDrag:display:
|
2017-12-05 16:30:58 +00:00
|
|
|
*
|
2018-06-29 17:34:14 +00:00
|
|
|
* The #GdkDisplay that the drag belongs to.
|
2017-12-05 16:30:58 +00:00
|
|
|
*/
|
|
|
|
properties[PROP_DISPLAY] =
|
|
|
|
g_param_spec_object ("display",
|
|
|
|
"Display",
|
2018-04-27 10:32:17 +00:00
|
|
|
"Display this drag belongs to",
|
2017-12-05 16:30:58 +00:00
|
|
|
GDK_TYPE_DISPLAY,
|
2018-04-27 10:32:17 +00:00
|
|
|
G_PARAM_READABLE |
|
2017-12-05 16:30:58 +00:00
|
|
|
G_PARAM_STATIC_STRINGS |
|
|
|
|
G_PARAM_EXPLICIT_NOTIFY);
|
|
|
|
|
2017-12-13 14:03:53 +00:00
|
|
|
/**
|
2018-06-29 17:34:14 +00:00
|
|
|
* GdkDrag:formats:
|
2017-12-13 14:03:53 +00:00
|
|
|
*
|
2018-06-29 17:34:14 +00:00
|
|
|
* The possible formats that the drag can provide its data in.
|
2017-12-13 14:03:53 +00:00
|
|
|
*/
|
|
|
|
properties[PROP_FORMATS] =
|
|
|
|
g_param_spec_boxed ("formats",
|
|
|
|
"Formats",
|
|
|
|
"The possible formats for data",
|
|
|
|
GDK_TYPE_CONTENT_FORMATS,
|
2018-05-07 15:31:26 +00:00
|
|
|
G_PARAM_READWRITE |
|
|
|
|
G_PARAM_CONSTRUCT_ONLY |
|
2017-12-13 14:03:53 +00:00
|
|
|
G_PARAM_STATIC_STRINGS |
|
|
|
|
G_PARAM_EXPLICIT_NOTIFY);
|
|
|
|
|
2018-07-03 22:44:00 +00:00
|
|
|
properties[PROP_SELECTED_ACTION] =
|
|
|
|
g_param_spec_flags ("selected-action",
|
|
|
|
"Selected action",
|
2018-07-02 23:16:47 +00:00
|
|
|
"The currently selected action",
|
|
|
|
GDK_TYPE_DRAG_ACTION,
|
|
|
|
0,
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
G_PARAM_STATIC_STRINGS |
|
|
|
|
G_PARAM_EXPLICIT_NOTIFY);
|
|
|
|
|
2018-07-03 22:52:21 +00:00
|
|
|
properties[PROP_ACTIONS] =
|
|
|
|
g_param_spec_flags ("actions",
|
|
|
|
"Actions",
|
|
|
|
"The possible actions",
|
|
|
|
GDK_TYPE_DRAG_ACTION,
|
|
|
|
0,
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
G_PARAM_STATIC_STRINGS |
|
|
|
|
G_PARAM_EXPLICIT_NOTIFY);
|
2018-07-15 20:08:52 +00:00
|
|
|
|
|
|
|
properties[PROP_SURFACE] =
|
|
|
|
g_param_spec_object ("surface",
|
|
|
|
"Surface",
|
|
|
|
"The surface where the drag originates",
|
|
|
|
GDK_TYPE_SURFACE,
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
G_PARAM_CONSTRUCT_ONLY |
|
|
|
|
G_PARAM_STATIC_STRINGS |
|
|
|
|
G_PARAM_EXPLICIT_NOTIFY);
|
|
|
|
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
/**
|
2018-06-29 17:34:14 +00:00
|
|
|
* GdkDrag::cancel:
|
|
|
|
* @drag: The object on which the signal is emitted
|
|
|
|
* @reason: The reason the drag was cancelled
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
*
|
2018-06-29 17:34:14 +00:00
|
|
|
* The drag operation was cancelled.
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
*/
|
|
|
|
signals[CANCEL] =
|
2017-11-18 03:47:11 +00:00
|
|
|
g_signal_new (g_intern_static_string ("cancel"),
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
G_TYPE_FROM_CLASS (object_class),
|
2016-02-15 16:05:50 +00:00
|
|
|
G_SIGNAL_RUN_LAST,
|
2018-06-29 17:34:14 +00:00
|
|
|
G_STRUCT_OFFSET (GdkDragClass, cancel),
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
NULL, NULL,
|
2019-05-31 03:56:50 +00:00
|
|
|
NULL,
|
2016-02-15 16:02:14 +00:00
|
|
|
G_TYPE_NONE, 1, GDK_TYPE_DRAG_CANCEL_REASON);
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
|
|
|
|
/**
|
2018-06-29 17:34:14 +00:00
|
|
|
* GdkDrag::drop-performed:
|
|
|
|
* @drag: The object on which the signal is emitted
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
*
|
2018-06-29 17:34:14 +00:00
|
|
|
* The drag operation was performed on an accepting client.
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
*/
|
|
|
|
signals[DROP_PERFORMED] =
|
2017-11-18 03:47:11 +00:00
|
|
|
g_signal_new (g_intern_static_string ("drop-performed"),
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
G_TYPE_FROM_CLASS (object_class),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
2018-06-29 17:34:14 +00:00
|
|
|
G_STRUCT_OFFSET (GdkDragClass, drop_performed),
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
NULL, NULL,
|
2019-05-29 20:05:19 +00:00
|
|
|
NULL,
|
2018-06-16 02:34:48 +00:00
|
|
|
G_TYPE_NONE, 0);
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
|
|
|
|
/**
|
2018-06-29 17:34:14 +00:00
|
|
|
* GdkDrag::dnd-finished:
|
|
|
|
* @drag: The object on which the signal is emitted
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
*
|
2018-06-29 17:34:14 +00:00
|
|
|
* The drag operation was finished, the destination
|
|
|
|
* finished reading all data. The drag object can now
|
|
|
|
* free all miscellaneous data.
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
*/
|
|
|
|
signals[DND_FINISHED] =
|
2017-11-18 03:47:11 +00:00
|
|
|
g_signal_new (g_intern_static_string ("dnd-finished"),
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
G_TYPE_FROM_CLASS (object_class),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
2018-06-29 17:34:14 +00:00
|
|
|
G_STRUCT_OFFSET (GdkDragClass, dnd_finished),
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
NULL, NULL,
|
2019-05-29 20:05:19 +00:00
|
|
|
NULL,
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
|
2017-12-05 16:30:58 +00:00
|
|
|
g_object_class_install_properties (object_class, N_PROPERTIES, properties);
|
2010-12-10 06:27:10 +00:00
|
|
|
}
|
|
|
|
|
2017-12-13 14:03:53 +00:00
|
|
|
static void
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_write_done (GObject *content,
|
|
|
|
GAsyncResult *result,
|
|
|
|
gpointer task)
|
2017-12-13 14:03:53 +00:00
|
|
|
{
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
if (gdk_content_provider_write_mime_type_finish (GDK_CONTENT_PROVIDER (content), result, &error))
|
|
|
|
g_task_return_boolean (task, TRUE);
|
|
|
|
else
|
|
|
|
g_task_return_error (task, error);
|
|
|
|
|
|
|
|
g_object_unref (task);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_write_serialize_done (GObject *content,
|
|
|
|
GAsyncResult *result,
|
|
|
|
gpointer task)
|
2017-12-13 14:03:53 +00:00
|
|
|
{
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
if (gdk_content_serialize_finish (result, &error))
|
|
|
|
g_task_return_boolean (task, TRUE);
|
|
|
|
else
|
|
|
|
g_task_return_error (task, error);
|
|
|
|
|
|
|
|
g_object_unref (task);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_write_async (GdkDrag *drag,
|
|
|
|
const char *mime_type,
|
|
|
|
GOutputStream *stream,
|
|
|
|
int io_priority,
|
|
|
|
GCancellable *cancellable,
|
|
|
|
GAsyncReadyCallback callback,
|
|
|
|
gpointer user_data)
|
2017-12-13 14:03:53 +00:00
|
|
|
{
|
2018-07-15 19:47:43 +00:00
|
|
|
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
2017-12-13 14:03:53 +00:00
|
|
|
GdkContentFormats *formats, *mime_formats;
|
|
|
|
GTask *task;
|
|
|
|
GType gtype;
|
|
|
|
|
2018-06-29 17:34:14 +00:00
|
|
|
g_return_if_fail (GDK_IS_DRAG (drag));
|
2018-07-15 19:47:43 +00:00
|
|
|
g_return_if_fail (priv->content);
|
2017-12-13 14:03:53 +00:00
|
|
|
g_return_if_fail (mime_type != NULL);
|
|
|
|
g_return_if_fail (mime_type == g_intern_string (mime_type));
|
|
|
|
g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
|
|
|
|
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
|
|
|
g_return_if_fail (callback != NULL);
|
|
|
|
|
2018-06-29 17:34:14 +00:00
|
|
|
task = g_task_new (drag, cancellable, callback, user_data);
|
2017-12-13 14:03:53 +00:00
|
|
|
g_task_set_priority (task, io_priority);
|
2018-06-29 17:34:14 +00:00
|
|
|
g_task_set_source_tag (task, gdk_drag_write_async);
|
2017-12-13 14:03:53 +00:00
|
|
|
|
2018-07-15 19:47:43 +00:00
|
|
|
formats = gdk_content_provider_ref_formats (priv->content);
|
2017-12-13 14:03:53 +00:00
|
|
|
if (gdk_content_formats_contain_mime_type (formats, mime_type))
|
|
|
|
{
|
2018-07-15 19:47:43 +00:00
|
|
|
gdk_content_provider_write_mime_type_async (priv->content,
|
2017-12-13 14:03:53 +00:00
|
|
|
mime_type,
|
|
|
|
stream,
|
|
|
|
io_priority,
|
|
|
|
cancellable,
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_write_done,
|
2017-12-13 14:03:53 +00:00
|
|
|
task);
|
|
|
|
gdk_content_formats_unref (formats);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mime_formats = gdk_content_formats_new ((const gchar *[2]) { mime_type, NULL }, 1);
|
|
|
|
mime_formats = gdk_content_formats_union_serialize_gtypes (mime_formats);
|
|
|
|
gtype = gdk_content_formats_match_gtype (formats, mime_formats);
|
|
|
|
if (gtype != G_TYPE_INVALID)
|
|
|
|
{
|
|
|
|
GValue value = G_VALUE_INIT;
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
g_assert (gtype != G_TYPE_INVALID);
|
|
|
|
|
|
|
|
g_value_init (&value, gtype);
|
2018-07-15 19:47:43 +00:00
|
|
|
if (gdk_content_provider_get_value (priv->content, &value, &error))
|
2017-12-13 14:03:53 +00:00
|
|
|
{
|
|
|
|
gdk_content_serialize_async (stream,
|
|
|
|
mime_type,
|
|
|
|
&value,
|
|
|
|
io_priority,
|
|
|
|
cancellable,
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_write_serialize_done,
|
2017-12-13 14:03:53 +00:00
|
|
|
g_object_ref (task));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_task_return_error (task, error);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_value_unset (&value);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
|
|
|
_("No compatible formats to transfer clipboard contents."));
|
|
|
|
}
|
|
|
|
|
|
|
|
gdk_content_formats_unref (mime_formats);
|
|
|
|
gdk_content_formats_unref (formats);
|
|
|
|
g_object_unref (task);
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_write_finish (GdkDrag *drag,
|
|
|
|
GAsyncResult *result,
|
|
|
|
GError **error)
|
2017-12-13 14:03:53 +00:00
|
|
|
{
|
2018-06-29 17:34:14 +00:00
|
|
|
g_return_val_if_fail (g_task_is_valid (result, drag), FALSE);
|
|
|
|
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_drag_write_async, FALSE);
|
2017-12-13 14:03:53 +00:00
|
|
|
|
|
|
|
return g_task_propagate_boolean (G_TASK (result), error);
|
|
|
|
}
|
|
|
|
|
2018-05-13 15:03:57 +00:00
|
|
|
void
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_set_actions (GdkDrag *drag,
|
2018-07-04 06:32:27 +00:00
|
|
|
GdkDragAction actions)
|
2018-05-13 15:03:57 +00:00
|
|
|
{
|
2018-07-15 19:47:43 +00:00
|
|
|
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
|
|
|
|
|
|
|
if (priv->actions == actions)
|
2018-07-03 22:52:21 +00:00
|
|
|
return;
|
|
|
|
|
2018-07-15 19:47:43 +00:00
|
|
|
priv->actions = actions;
|
2018-07-03 22:52:21 +00:00
|
|
|
|
|
|
|
g_object_notify_by_pspec (G_OBJECT (drag), properties[PROP_ACTIONS]);
|
2018-05-13 15:03:57 +00:00
|
|
|
}
|
|
|
|
|
2018-07-02 23:16:47 +00:00
|
|
|
void
|
2018-07-03 22:44:00 +00:00
|
|
|
gdk_drag_set_selected_action (GdkDrag *drag,
|
|
|
|
GdkDragAction action)
|
2018-07-02 23:16:47 +00:00
|
|
|
{
|
2018-07-15 19:47:43 +00:00
|
|
|
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
2018-07-02 23:16:47 +00:00
|
|
|
GdkCursor *cursor;
|
|
|
|
|
2018-07-15 19:47:43 +00:00
|
|
|
if (priv->selected_action == action)
|
2018-07-02 23:16:47 +00:00
|
|
|
return;
|
|
|
|
|
2018-07-15 19:47:43 +00:00
|
|
|
priv->selected_action = action;
|
2018-07-02 23:16:47 +00:00
|
|
|
|
|
|
|
cursor = gdk_drag_get_cursor (drag, action);
|
|
|
|
gdk_drag_set_cursor (drag, cursor);
|
|
|
|
|
2018-07-03 22:44:00 +00:00
|
|
|
g_object_notify_by_pspec (G_OBJECT (drag), properties[PROP_SELECTED_ACTION]);
|
2018-07-02 23:16:47 +00:00
|
|
|
}
|
|
|
|
|
2015-12-02 04:33:53 +00:00
|
|
|
/**
|
2018-06-29 17:34:14 +00:00
|
|
|
* gdk_drag_get_drag_surface:
|
|
|
|
* @drag: a #GdkDrag
|
2015-12-02 04:33:53 +00:00
|
|
|
*
|
2018-03-20 14:14:10 +00:00
|
|
|
* Returns the surface on which the drag icon should be rendered
|
|
|
|
* during the drag operation. Note that the surface may not be
|
2015-12-02 04:33:53 +00:00
|
|
|
* available until the drag operation has begun. GDK will move
|
2018-03-20 14:14:10 +00:00
|
|
|
* the surface in accordance with the ongoing drag operation.
|
2018-06-29 17:34:14 +00:00
|
|
|
* The surface is owned by @drag and will be destroyed when
|
2015-12-02 04:33:53 +00:00
|
|
|
* the drag operation is over.
|
|
|
|
*
|
2018-03-20 14:14:10 +00:00
|
|
|
* Returns: (nullable) (transfer none): the drag surface, or %NULL
|
2015-12-02 04:33:53 +00:00
|
|
|
*/
|
2018-03-20 10:40:08 +00:00
|
|
|
GdkSurface *
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_get_drag_surface (GdkDrag *drag)
|
2015-12-02 04:33:53 +00:00
|
|
|
{
|
2018-06-29 17:34:14 +00:00
|
|
|
g_return_val_if_fail (GDK_IS_DRAG (drag), NULL);
|
2015-12-02 04:33:53 +00:00
|
|
|
|
2018-06-29 17:34:14 +00:00
|
|
|
if (GDK_DRAG_GET_CLASS (drag)->get_drag_surface)
|
|
|
|
return GDK_DRAG_GET_CLASS (drag)->get_drag_surface (drag);
|
2015-12-02 04:33:53 +00:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
2015-12-08 02:52:03 +00:00
|
|
|
|
|
|
|
/**
|
2018-06-29 17:34:14 +00:00
|
|
|
* gdk_drag_set_hotspot:
|
|
|
|
* @drag: a #GdkDrag
|
2018-03-20 14:14:10 +00:00
|
|
|
* @hot_x: x coordinate of the drag surface hotspot
|
|
|
|
* @hot_y: y coordinate of the drag surface hotspot
|
2015-12-08 02:52:03 +00:00
|
|
|
*
|
2018-03-20 14:14:10 +00:00
|
|
|
* Sets the position of the drag surface that will be kept
|
2015-12-08 02:52:03 +00:00
|
|
|
* under the cursor hotspot. Initially, the hotspot is at the
|
2018-03-20 14:14:10 +00:00
|
|
|
* top left corner of the drag surface.
|
2015-12-08 02:52:03 +00:00
|
|
|
*/
|
|
|
|
void
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_set_hotspot (GdkDrag *drag,
|
|
|
|
gint hot_x,
|
|
|
|
gint hot_y)
|
2015-12-08 02:52:03 +00:00
|
|
|
{
|
2018-06-29 17:34:14 +00:00
|
|
|
g_return_if_fail (GDK_IS_DRAG (drag));
|
2015-12-08 02:52:03 +00:00
|
|
|
|
2018-06-29 17:34:14 +00:00
|
|
|
if (GDK_DRAG_GET_CLASS (drag)->set_hotspot)
|
|
|
|
GDK_DRAG_GET_CLASS (drag)->set_hotspot (drag, hot_x, hot_y);
|
2015-12-08 02:52:03 +00:00
|
|
|
}
|
2015-12-07 20:07:13 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* gdk_drag_drop_done:
|
2018-06-29 17:34:14 +00:00
|
|
|
* @drag: a #GdkDrag
|
2015-12-07 20:07:13 +00:00
|
|
|
* @success: whether the drag was ultimatively successful
|
|
|
|
*
|
|
|
|
* Inform GDK if the drop ended successfully. Passing %FALSE
|
|
|
|
* for @success may trigger a drag cancellation animation.
|
|
|
|
*
|
|
|
|
* This function is called by the drag source, and should
|
|
|
|
* be the last call before dropping the reference to the
|
2018-06-29 17:34:14 +00:00
|
|
|
* @drag.
|
2015-12-07 20:07:13 +00:00
|
|
|
*
|
2018-06-29 17:34:14 +00:00
|
|
|
* The #GdkDrag will only take the first gdk_drag_drop_done()
|
2016-02-15 17:56:42 +00:00
|
|
|
* call as effective, if this function is called multiple times,
|
|
|
|
* all subsequent calls will be ignored.
|
2015-12-07 20:07:13 +00:00
|
|
|
*/
|
|
|
|
void
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_drop_done (GdkDrag *drag,
|
|
|
|
gboolean success)
|
2015-12-07 20:07:13 +00:00
|
|
|
{
|
2018-07-15 19:47:43 +00:00
|
|
|
GdkDragPrivate *priv = gdk_drag_get_instance_private (drag);
|
|
|
|
|
2018-06-29 17:34:14 +00:00
|
|
|
g_return_if_fail (GDK_IS_DRAG (drag));
|
2015-12-07 20:07:13 +00:00
|
|
|
|
2018-07-15 19:47:43 +00:00
|
|
|
if (priv->drop_done)
|
2016-02-15 17:56:42 +00:00
|
|
|
return;
|
|
|
|
|
2018-07-15 19:47:43 +00:00
|
|
|
priv->drop_done = TRUE;
|
2016-02-15 17:56:42 +00:00
|
|
|
|
2018-06-29 17:34:14 +00:00
|
|
|
if (GDK_DRAG_GET_CLASS (drag)->drop_done)
|
|
|
|
GDK_DRAG_GET_CLASS (drag)->drop_done (drag, success);
|
2015-12-07 20:07:13 +00:00
|
|
|
}
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
|
|
|
|
void
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_set_cursor (GdkDrag *drag,
|
|
|
|
GdkCursor *cursor)
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
{
|
2018-06-29 17:34:14 +00:00
|
|
|
g_return_if_fail (GDK_IS_DRAG (drag));
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
|
2018-06-29 17:34:14 +00:00
|
|
|
if (GDK_DRAG_GET_CLASS (drag)->set_cursor)
|
|
|
|
GDK_DRAG_GET_CLASS (drag)->set_cursor (drag, cursor);
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_cancel (GdkDrag *drag,
|
|
|
|
GdkDragCancelReason reason)
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
{
|
2018-06-29 17:34:14 +00:00
|
|
|
g_return_if_fail (GDK_IS_DRAG (drag));
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
|
2018-06-29 17:34:14 +00:00
|
|
|
g_signal_emit (drag, signals[CANCEL], 0, reason);
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_handle_source_event (GdkEvent *event)
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
{
|
2018-06-29 17:34:14 +00:00
|
|
|
GdkDrag *drag;
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
GList *l;
|
|
|
|
|
2018-06-29 17:34:14 +00:00
|
|
|
for (l = drags; l; l = l->next)
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
{
|
2018-06-29 17:34:14 +00:00
|
|
|
drag = l->data;
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
|
2018-06-29 17:34:14 +00:00
|
|
|
if (!GDK_DRAG_GET_CLASS (drag)->handle_event)
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
continue;
|
|
|
|
|
2018-06-29 17:34:14 +00:00
|
|
|
if (GDK_DRAG_GET_CLASS (drag)->handle_event (drag, event))
|
gdk: Allow internal management of source-side DnD
We've traditionally left GTK+ to handle the input side of things,
letting GDK only manage the windowing-specific messaging. This
way of splitting responsibilities is not compatible however with
some backends, we must fold then input management at the DnD stage
into GDK (and backends) domain.
The gdk_drag_context_manage_dnd() call is meant to be the entry
point for this mode of operation, if the drag and drop operation
becomes managed, the caller (i.e. gtkdnd.c) doesn't need to perform
grabs, nor manage input events itself.
As a consequence of this, different aspects now belong to the
backend GdkDragContext implementation:
- Because the caller doesn't see keyboard events anymore,
keyboard navigation must be managed in GDK, so is the decision
of the current action based on modifiers/button pressed.
- Because the caller won't see input events in general, the lifetime
of the drag and drop operation is now communicated through the
::drop-performed, ::dnd-finished and ::cancel events
- Because the caller doesn't participate anymore on the action
being chosen, the pointer cursor must be set by the backend.
The caller is rather notified of the final action through the
::action signal.
The caller is still responsible of dealing with the corresponding
GdkSelection, ensuring its ownership and communicating the supported
mimetypes.
2016-01-08 20:03:01 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
2016-01-13 19:51:19 +00:00
|
|
|
|
|
|
|
GdkCursor *
|
2018-06-29 17:34:14 +00:00
|
|
|
gdk_drag_get_cursor (GdkDrag *drag,
|
|
|
|
GdkDragAction action)
|
2016-01-13 19:51:19 +00:00
|
|
|
{
|
|
|
|
gint i;
|
|
|
|
|
|
|
|
for (i = 0 ; i < G_N_ELEMENTS (drag_cursors) - 1; i++)
|
|
|
|
if (drag_cursors[i].action == action)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (drag_cursors[i].cursor == NULL)
|
2017-11-03 22:19:22 +00:00
|
|
|
drag_cursors[i].cursor = gdk_cursor_new_from_name (drag_cursors[i].name, NULL);
|
|
|
|
|
2016-01-13 19:51:19 +00:00
|
|
|
return drag_cursors[i].cursor;
|
|
|
|
}
|
2016-03-09 16:00:31 +00:00
|
|
|
|
2018-05-11 22:13:11 +00:00
|
|
|
/**
|
|
|
|
* gdk_drag_action_is_unique:
|
|
|
|
* @action: a #GdkDragAction
|
|
|
|
*
|
|
|
|
* Checks if @action represents a single action or if it
|
|
|
|
* includes multiple flags that can be selected from.
|
|
|
|
*
|
|
|
|
* When @action is 0 - ie no action was given, %TRUE
|
|
|
|
* is returned.
|
|
|
|
*
|
|
|
|
* Returns: %TRUE if exactly one action was given
|
|
|
|
**/
|
2018-06-19 14:47:36 +00:00
|
|
|
gboolean
|
2018-05-11 22:13:11 +00:00
|
|
|
gdk_drag_action_is_unique (GdkDragAction action)
|
|
|
|
{
|
|
|
|
return (action & (action - 1)) == 0;
|
|
|
|
}
|