/* * 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 . * * Authors: Benjamin Otte */ #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; }