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/.
|
|
|
|
*/
|
|
|
|
|
2021-02-17 14:22:54 +00:00
|
|
|
/**
|
2021-02-21 05:13:57 +00:00
|
|
|
* GdkDrag:
|
2021-02-17 14:22:54 +00:00
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
* The `GdkDrag` object represents the source of an ongoing DND operation.
|
2021-02-17 14:22:54 +00:00
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
* A `GdkDrag` is created when a drag is started, and stays alive for duration of
|
|
|
|
* the DND operation. After a drag has been started with [func@Gdk.Drag.begin],
|
2021-02-17 14:22:54 +00:00
|
|
|
* the caller gets informed about the status of the ongoing drag operation
|
|
|
|
* with signals on the `GdkDrag` object.
|
|
|
|
*
|
|
|
|
* GTK provides a higher level abstraction based on top of these functions,
|
|
|
|
* and so they are not normally needed in GTK applications. See the
|
|
|
|
* "Drag and Drop" section of the GTK documentation for more information.
|
|
|
|
*/
|
|
|
|
|
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"
|
2022-09-24 03:33:42 +00:00
|
|
|
#include <glib/gi18n-lib.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;
|
2020-07-24 18:40:36 +00:00
|
|
|
const char *name;
|
2016-01-13 19:51:19 +00:00
|
|
|
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
|
|
|
|
2017-12-05 16:30:58 +00:00
|
|
|
/**
|
2021-02-25 01:03:36 +00:00
|
|
|
* gdk_drag_get_display: (attributes org.gtk.Method.get_property=display)
|
2021-02-21 05:13:57 +00:00
|
|
|
* @drag: a `GdkDrag`
|
2017-12-05 16:30:58 +00:00
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
* Gets the `GdkDisplay` that the drag object was created for.
|
2017-12-05 16:30:58 +00:00
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
* Returns: (transfer none): a `GdkDisplay`
|
|
|
|
*/
|
2017-12-05 16:30:58 +00:00
|
|
|
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
|
|
|
/**
|
2021-02-25 01:03:36 +00:00
|
|
|
* gdk_drag_get_formats: (attributes org.gtk.Method.get_property=formats)
|
2021-02-21 05:13:57 +00:00
|
|
|
* @drag: a `GdkDrag`
|
2010-05-25 15:54:16 +00:00
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
* Retrieves the formats supported by this `GdkDrag` object.
|
2010-05-25 15:54:16 +00:00
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
* Returns: (transfer none): a `GdkContentFormats`
|
|
|
|
*/
|
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
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-02-25 01:03:36 +00:00
|
|
|
* gdk_drag_get_actions: (attributes org.gtk.Method.get_property=actions)
|
2021-02-21 05:13:57 +00:00
|
|
|
* @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
|
|
|
*
|
2021-02-21 05:13:57 +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
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-02-25 01:03:36 +00:00
|
|
|
* gdk_drag_get_selected_action: (attributes org.gtk.Method.get_property=selected-action)
|
2021-02-21 05:13:57 +00:00
|
|
|
* @drag: a `GdkDrag`
|
2010-05-25 15:54:16 +00:00
|
|
|
*
|
|
|
|
* Determines the action chosen by the drag destination.
|
|
|
|
*
|
2021-02-21 05:13:57 +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
|
|
|
/**
|
2021-02-25 01:03:36 +00:00
|
|
|
* gdk_drag_get_device: (attributes org.gtk.Method.get_property=device)
|
2021-02-21 05:13:57 +00:00
|
|
|
* @drag: a `GdkDrag`
|
2010-12-10 06:27:10 +00:00
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
* Returns the `GdkDevice` associated to the `GdkDrag` object.
|
2010-12-10 06:27:10 +00:00
|
|
|
*
|
2021-02-21 05:13:57 +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
|
|
|
/**
|
2021-02-25 01:03:36 +00:00
|
|
|
* gdk_drag_get_content: (attributes org.gtk.Method.get_property=content)
|
2021-02-21 05:13:57 +00:00
|
|
|
* @drag: a `GdkDrag`
|
2020-02-24 13:32:15 +00:00
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
* Returns the `GdkContentProvider` associated to the `GdkDrag` object.
|
2020-02-24 13:32:15 +00:00
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
* Returns: (transfer none): The `GdkContentProvider` associated to @drag.
|
|
|
|
*/
|
2020-02-24 13:32:15 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-02-25 01:03:36 +00:00
|
|
|
* gdk_drag_get_surface: (attributes org.gtk.Method.get_property=surface)
|
2021-02-21 05:13:57 +00:00
|
|
|
* @drag: a `GdkDrag`
|
2020-02-24 13:32:15 +00:00
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
* Returns the `GdkSurface` where the drag originates.
|
2020-02-24 13:32:15 +00:00
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
* Returns: (transfer none): The `GdkSurface` where the drag originates
|
|
|
|
*/
|
2020-02-24 13:32:15 +00:00
|
|
|
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
|
|
|
/**
|
2021-02-25 01:03:36 +00:00
|
|
|
* GdkDrag:content: (attributes org.gtk.Property.get=gdk_drag_get_content)
|
2017-12-13 14:03:53 +00:00
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
* The `GdkContentProvider`.
|
2017-12-13 14:03:53 +00:00
|
|
|
*/
|
|
|
|
properties[PROP_CONTENT] =
|
2022-05-11 12:19:39 +00:00
|
|
|
g_param_spec_object ("content", NULL, NULL,
|
2017-12-13 14:03:53 +00:00
|
|
|
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
|
|
|
/**
|
2021-02-25 01:03:36 +00:00
|
|
|
* GdkDrag:device: (attributes org.gtk.Property.get=gdk_drag_get_device)
|
2018-04-27 10:32:17 +00:00
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
* The `GdkDevice` that is performing the drag.
|
2018-04-27 10:32:17 +00:00
|
|
|
*/
|
|
|
|
properties[PROP_DEVICE] =
|
2022-05-11 12:19:39 +00:00
|
|
|
g_param_spec_object ("device", NULL, NULL,
|
2018-04-27 10:32:17 +00:00
|
|
|
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
|
|
|
/**
|
2021-02-25 01:03:36 +00:00
|
|
|
* GdkDrag:display: (attributes org.gtk.Property.get=gdk_drag_get_display)
|
2017-12-05 16:30:58 +00:00
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
* The `GdkDisplay` that the drag belongs to.
|
2017-12-05 16:30:58 +00:00
|
|
|
*/
|
|
|
|
properties[PROP_DISPLAY] =
|
2022-05-11 12:19:39 +00:00
|
|
|
g_param_spec_object ("display", NULL, NULL,
|
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
|
|
|
/**
|
2021-02-25 01:03:36 +00:00
|
|
|
* GdkDrag:formats: (attributes org.gtk.Property.get=gdk_drag_get_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] =
|
2022-05-11 12:19:39 +00:00
|
|
|
g_param_spec_boxed ("formats", NULL, NULL,
|
2017-12-13 14:03:53 +00:00
|
|
|
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);
|
|
|
|
|
2021-02-21 05:13:57 +00:00
|
|
|
/**
|
2021-02-25 01:03:36 +00:00
|
|
|
* GdkDrag:selected-action: (attributes org.gtk.Property.get=gdk_drag_get_selected_action)
|
2021-02-21 05:13:57 +00:00
|
|
|
*
|
|
|
|
* The currently selected action of the drag.
|
|
|
|
*/
|
2018-07-03 22:44:00 +00:00
|
|
|
properties[PROP_SELECTED_ACTION] =
|
2022-05-11 12:19:39 +00:00
|
|
|
g_param_spec_flags ("selected-action", NULL, NULL,
|
2018-07-02 23:16:47 +00:00
|
|
|
GDK_TYPE_DRAG_ACTION,
|
|
|
|
0,
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
G_PARAM_STATIC_STRINGS |
|
|
|
|
G_PARAM_EXPLICIT_NOTIFY);
|
|
|
|
|
2021-02-21 05:13:57 +00:00
|
|
|
/**
|
2021-02-25 01:03:36 +00:00
|
|
|
* GdkDrag:actions: (attributes org.gtk.Property.get=gdk_drag_get_actions)
|
2021-02-21 05:13:57 +00:00
|
|
|
*
|
|
|
|
* The possible actions of this drag.
|
|
|
|
*/
|
2018-07-03 22:52:21 +00:00
|
|
|
properties[PROP_ACTIONS] =
|
2022-05-11 12:19:39 +00:00
|
|
|
g_param_spec_flags ("actions", NULL, NULL,
|
2018-07-03 22:52:21 +00:00
|
|
|
GDK_TYPE_DRAG_ACTION,
|
|
|
|
0,
|
|
|
|
G_PARAM_READWRITE |
|
|
|
|
G_PARAM_STATIC_STRINGS |
|
|
|
|
G_PARAM_EXPLICIT_NOTIFY);
|
2018-07-15 20:08:52 +00:00
|
|
|
|
2021-02-21 05:13:57 +00:00
|
|
|
/**
|
2021-02-25 01:03:36 +00:00
|
|
|
* GdkDrag:surface: (attributes org.gtk.Property.get=gdk_drag_get_surface)
|
2021-02-21 05:13:57 +00:00
|
|
|
*
|
|
|
|
* The surface where the drag originates.
|
|
|
|
*/
|
2018-07-15 20:08:52 +00:00
|
|
|
properties[PROP_SURFACE] =
|
2022-05-11 12:19:39 +00:00
|
|
|
g_param_spec_object ("surface", NULL, NULL,
|
2018-07-15 20:08:52 +00:00
|
|
|
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
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
* Emitted when the drag operation is 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
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
* Emitted when the drop operation is 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
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
* Emitted when the destination side has 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;
|
|
|
|
}
|
|
|
|
|
2020-07-24 18:40:36 +00:00
|
|
|
mime_formats = gdk_content_formats_new ((const char *[2]) { mime_type, NULL }, 1);
|
2017-12-13 14:03:53 +00:00
|
|
|
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:
|
2021-02-21 05:13:57 +00:00
|
|
|
* @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
|
2021-02-21 05:13:57 +00:00
|
|
|
* during the drag operation.
|
|
|
|
*
|
|
|
|
* Note that the surface may not be available until the drag operation
|
|
|
|
* has begun. GDK will move the surface in accordance with the ongoing
|
|
|
|
* drag operation. The surface is owned by @drag and will be destroyed
|
|
|
|
* when the drag operation is over.
|
2015-12-02 04:33:53 +00:00
|
|
|
*
|
2021-05-21 00:45:06 +00:00
|
|
|
* Returns: (nullable) (transfer none): the drag surface
|
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:
|
2021-02-21 05:13:57 +00:00
|
|
|
* @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
|
2021-02-21 05:13:57 +00:00
|
|
|
* under the cursor hotspot.
|
|
|
|
*
|
|
|
|
* Initially, the hotspot is at the 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,
|
2020-07-24 13:54:49 +00:00
|
|
|
int hot_x,
|
|
|
|
int 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:
|
2021-02-21 05:13:57 +00:00
|
|
|
* @drag: a `GdkDrag`
|
2015-12-07 20:07:13 +00:00
|
|
|
* @success: whether the drag was ultimatively successful
|
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
* Informs GDK that the drop ended.
|
2015-12-07 20:07:13 +00:00
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
* Passing %FALSE for @success may trigger a drag cancellation
|
|
|
|
* animation.
|
2015-12-07 20:07:13 +00:00
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
* This function is called by the drag source, and should be the
|
|
|
|
* last call before dropping the reference to the @drag.
|
|
|
|
*
|
|
|
|
* The `GdkDrag` will only take the first [method@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
|
|
|
{
|
2020-07-24 13:54:49 +00:00
|
|
|
int i;
|
2016-01-13 19:51:19 +00:00
|
|
|
|
|
|
|
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);
|
2021-02-21 05:13:57 +00:00
|
|
|
|
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:
|
2021-02-21 05:13:57 +00:00
|
|
|
* @action: a `GdkDragAction`
|
2018-05-11 22:13:11 +00:00
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
* Checks if @action represents a single action or includes
|
|
|
|
* multiple actions.
|
2018-05-11 22:13:11 +00:00
|
|
|
*
|
|
|
|
* When @action is 0 - ie no action was given, %TRUE
|
|
|
|
* is returned.
|
|
|
|
*
|
|
|
|
* Returns: %TRUE if exactly one action was given
|
2021-02-21 05:13:57 +00:00
|
|
|
*/
|
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;
|
|
|
|
}
|