forked from AuroraMiddleware/gtk
7cd728a0ea
This allows textview/text dnd to properly display a MOVE icon when in the widget the drag started from but a COPY icon otherwise.
114 lines
2.5 KiB
C
114 lines
2.5 KiB
C
/*
|
|
* Copyright © 2020 Benjamin Otte
|
|
*
|
|
* 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.1 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
|
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Authors: Benjamin Otte <otte@gnome.org>
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include "gtkdropprivate.h"
|
|
|
|
typedef struct _GtkDrop GtkDrop;
|
|
|
|
struct _GtkDrop
|
|
{
|
|
/* TRUE if we are waiting for a gdk_drop_status() call */
|
|
gboolean waiting;
|
|
/* TRUE if begin_event() has been called but end_event() hasn't yet - purely for debugging */
|
|
gboolean active;
|
|
};
|
|
|
|
static void
|
|
gtk_drop_free (gpointer data)
|
|
{
|
|
GtkDrop *self = data;
|
|
|
|
g_slice_free (GtkDrop, self);
|
|
}
|
|
|
|
static GtkDrop *
|
|
gtk_drop_lookup (GdkDrop *drop)
|
|
{
|
|
static GQuark drop_quark = 0;
|
|
GtkDrop *result;
|
|
|
|
if (G_UNLIKELY (drop_quark == 0))
|
|
drop_quark = g_quark_from_string ("-gtk-drop-data");
|
|
|
|
result = g_object_get_qdata (G_OBJECT (drop), drop_quark);
|
|
if (result == NULL)
|
|
{
|
|
result = g_slice_new0 (GtkDrop);
|
|
g_object_set_qdata_full (G_OBJECT (drop), drop_quark, result, gtk_drop_free);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void
|
|
gtk_drop_begin_event (GdkDrop *drop,
|
|
GdkEventType event_type)
|
|
{
|
|
GtkDrop *self;
|
|
|
|
self = gtk_drop_lookup (drop);
|
|
|
|
g_assert (self->waiting == FALSE);
|
|
g_assert (self->active == FALSE);
|
|
|
|
self->active = TRUE;
|
|
if (event_type == GDK_DRAG_ENTER ||
|
|
event_type == GDK_DRAG_MOTION)
|
|
self->waiting = TRUE;
|
|
}
|
|
|
|
void
|
|
gtk_drop_end_event (GdkDrop *drop)
|
|
{
|
|
GtkDrop *self;
|
|
|
|
self = gtk_drop_lookup (drop);
|
|
|
|
g_assert (self->active == TRUE);
|
|
|
|
if (self->waiting)
|
|
{
|
|
gdk_drop_status (drop, 0, 0);
|
|
self->waiting = FALSE;
|
|
}
|
|
self->active = FALSE;
|
|
}
|
|
|
|
gboolean
|
|
gtk_drop_status (GdkDrop *drop,
|
|
GdkDragAction actions,
|
|
GdkDragAction preferred_action)
|
|
{
|
|
GtkDrop *self;
|
|
|
|
self = gtk_drop_lookup (drop);
|
|
|
|
g_assert (self->active == TRUE);
|
|
|
|
if (!self->waiting)
|
|
return FALSE;
|
|
|
|
gdk_drop_status (drop, actions, preferred_action);
|
|
self->waiting = FALSE;
|
|
return TRUE;
|
|
}
|
|
|