[gtk/dnd-gestures-2: 50/57] Turn GtkDropTarget into an event controller
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/dnd-gestures-2: 50/57] Turn GtkDropTarget into an event controller
- Date: Mon, 6 Jan 2020 05:44:36 +0000 (UTC)
commit ff757460d306d3805662e0b03ab77ac28541049c
Author: Matthias Clasen <mclasen redhat com>
Date: Sun Jan 5 22:53:53 2020 -0500
Turn GtkDropTarget into an event controller
We are still propagating the drag events manually,
but we are now calling gtk_widget_run_controllers
to pass them to drop targets.
gtk/gtkdnd.c | 140 ++++++++---------------------------------
gtk/gtkdndprivate.h | 14 +++++
gtk/gtkdragdest.c | 178 +++++++++++++++++++++++++++++++++++++++-------------
3 files changed, 176 insertions(+), 156 deletions(-)
---
diff --git a/gtk/gtkdnd.c b/gtk/gtkdnd.c
index eda5c11f6f..eff878ed03 100644
--- a/gtk/gtkdnd.c
+++ b/gtk/gtkdnd.c
@@ -63,26 +63,9 @@
*/
-typedef struct _GtkDragDestInfo GtkDragDestInfo;
-
-struct _GtkDragDestInfo
-{
- GtkWidget *widget; /* Widget in which drag is in */
- GdkDrop *drop; /* drop */
-};
-
/* Forward declarations */
-static GtkWidget *gtk_drop_find_widget (GtkWidget *widget,
+static gboolean gtk_drop_find_widget (GtkWidget *widget,
GdkEvent *event);
-static void gtk_drag_dest_leave (GtkWidget *widget,
- GdkDrop *drop);
-static gboolean gtk_drop_target_handle_event (GtkDropTarget *dest,
- GdkEvent *event);
-static void gtk_drag_dest_set_widget (GtkDragDestInfo *info,
- GtkWidget *widget);
-
-static GtkDragDestInfo * gtk_drag_get_dest_info (GdkDrop *drop,
- gboolean create);
/*
@@ -116,41 +99,17 @@ _gtk_drag_dest_handle_event (GtkWidget *toplevel,
break;
case GDK_DRAG_LEAVE:
- if (info->widget)
+ if (info->dest)
{
- gtk_drag_dest_leave (info->widget, drop);
- gtk_drag_dest_set_widget (info, NULL);
+ gtk_drop_target_emit_drag_leave (info->dest, drop);
+ gtk_drag_dest_set_target (info, NULL);
}
break;
case GDK_DRAG_MOTION:
case GDK_DROP_START:
{
- GtkWidget *widget;
-
- if (event_type == GDK_DROP_START)
- {
- /* We send a leave here so that the widget unhighlights
- * properly.
- */
- if (info->widget)
- {
- gtk_drag_dest_leave (info->widget, drop);
- gtk_drag_dest_set_widget (info, NULL);
- }
- }
-
- widget = gtk_drop_find_widget (toplevel, event);
-
- if (info->widget && info->widget != widget)
- {
- gtk_drag_dest_leave (info->widget, drop);
- gtk_drag_dest_set_widget (info, NULL);
- }
-
- if (widget)
- gtk_drag_dest_set_widget (info, widget);
- else
+ if (!gtk_drop_find_widget (toplevel, event))
gdk_drop_status (drop, 0);
}
break;
@@ -160,7 +119,7 @@ _gtk_drag_dest_handle_event (GtkWidget *toplevel,
}
}
-static GtkWidget *
+static gboolean
gtk_drop_find_widget (GtkWidget *event_widget,
GdkEvent *event)
{
@@ -170,26 +129,25 @@ gtk_drop_find_widget (GtkWidget *event_widget,
if (!gtk_widget_get_mapped (event_widget) ||
!gtk_widget_get_sensitive (event_widget))
- return NULL;
+ return FALSE;
gdk_event_get_coords (event, &x, &y);
widget = gtk_widget_pick (event_widget, x, y, GTK_PICK_DEFAULT);
if (!widget)
- return NULL;
+ return FALSE;
gtk_widget_translate_coordinates (event_widget, widget, x, y, &wx, &wy);
while (widget)
{
- GtkDropTarget *dest;
GtkWidget *parent;
GList *hierarchy = NULL;
gboolean found = FALSE;
if (!gtk_widget_get_mapped (widget))
- return NULL;
+ return FALSE;
if (gtk_widget_get_state_flags (widget) & GTK_STATE_FLAG_INSENSITIVE)
{
@@ -207,17 +165,9 @@ gtk_drop_find_widget (GtkWidget *event_widget,
hierarchy = g_list_prepend (hierarchy, g_object_ref (parent));
}
- /* If the current widget is registered as a drop site, check to
- * emit "drag-motion" to check if we are actually in a drop
- * site.
- */
- dest = gtk_drop_target_get (widget);
- if (dest)
- {
- gdk_event_set_coords (event, wx, wy);
- found = gtk_drop_target_handle_event (dest, event);
- gdk_event_set_coords (event, x, y);
- }
+ gdk_event_set_coords (event, wx, wy);
+ found = gtk_widget_run_controllers (widget, event, GTK_PHASE_BUBBLE);
+ gdk_event_set_coords (event, x, y);
if (!found)
{
@@ -236,33 +186,33 @@ gtk_drop_find_widget (GtkWidget *event_widget,
g_list_free_full (hierarchy, g_object_unref);
if (found)
- return widget;
+ return TRUE;
if (parent)
g_object_remove_weak_pointer (G_OBJECT (parent), (gpointer *) &parent);
else
- return NULL;
+ return FALSE;
if (!gtk_widget_translate_coordinates (widget, parent, wx, wy, &wx, &wy))
- return NULL;
+ return FALSE;
widget = parent;
}
- return NULL;
+ return FALSE;
}
-static void
-gtk_drag_dest_set_widget (GtkDragDestInfo *info,
- GtkWidget *widget)
+void
+gtk_drag_dest_set_target (GtkDragDestInfo *info,
+ GtkDropTarget *dest)
{
- if (info->widget)
- g_object_remove_weak_pointer (G_OBJECT (info->widget), (gpointer *) &info->widget);
+ if (info->dest)
+ g_object_remove_weak_pointer (G_OBJECT (info->dest), (gpointer *) &info->dest);
- info->widget = widget;
+ info->dest = dest;
- if (info->widget)
- g_object_add_weak_pointer (G_OBJECT (info->widget), (gpointer *) &info->widget);
+ if (info->dest)
+ g_object_add_weak_pointer (G_OBJECT (info->dest), (gpointer *) &info->dest);
}
static void
@@ -270,12 +220,12 @@ gtk_drag_dest_info_destroy (gpointer data)
{
GtkDragDestInfo *info = (GtkDragDestInfo *)data;
- gtk_drag_dest_set_widget (info, NULL);
+ gtk_drag_dest_set_target (info, NULL);
g_slice_free (GtkDragDestInfo, data);
}
-static GtkDragDestInfo *
+GtkDragDestInfo *
gtk_drag_get_dest_info (GdkDrop *drop,
gboolean create)
{
@@ -295,41 +245,3 @@ gtk_drag_get_dest_info (GdkDrop *drop,
return info;
}
-
-/*
- * Default drag handlers
- */
-static void
-gtk_drag_dest_leave (GtkWidget *widget,
- GdkDrop *drop)
-{
- GtkDropTarget *dest;
-
- dest = gtk_drop_target_get (widget);
- g_return_if_fail (dest != NULL);
-
- gtk_drop_target_emit_drag_leave (dest, drop);
-}
-
-static gboolean
-gtk_drop_target_handle_event (GtkDropTarget *dest,
- GdkEvent *event)
-{
- GdkDrop *drop;
- double x, y;
-
- drop = gdk_event_get_drop (event);
- gdk_event_get_coords (event, &x, &y);
-
- switch ((int)gdk_event_get_event_type (event))
- {
- case GDK_DRAG_MOTION:
- return gtk_drop_target_emit_drag_motion (dest, drop, x, y);
- case GDK_DROP_START:
- return gtk_drop_target_emit_drag_drop (dest, drop, x, y);
- default:
- break;
- }
-
- return FALSE;
-}
diff --git a/gtk/gtkdndprivate.h b/gtk/gtkdndprivate.h
index ad829e05b7..b316a9fded 100644
--- a/gtk/gtkdndprivate.h
+++ b/gtk/gtkdndprivate.h
@@ -20,6 +20,7 @@
#define __GTK_DND_PRIVATE_H__
#include "gtkwidget.h"
+#include "gtkdragdest.h"
G_BEGIN_DECLS
@@ -27,6 +28,19 @@ G_BEGIN_DECLS
void _gtk_drag_dest_handle_event (GtkWidget *toplevel,
GdkEvent *event);
+typedef struct _GtkDragDestInfo GtkDragDestInfo;
+
+struct _GtkDragDestInfo
+{
+ GtkDropTarget *dest;
+ GdkDrop *drop; /* drop */
+};
+
+GtkDragDestInfo * gtk_drag_get_dest_info (GdkDrop *drop,
+ gboolean create);
+void gtk_drag_dest_set_target (GtkDragDestInfo *info,
+ GtkDropTarget *dest);
+
G_END_DECLS
#endif /* __GTK_DND_PRIVATE_H__ */
diff --git a/gtk/gtkdragdest.c b/gtk/gtkdragdest.c
index 4ad84fbe2f..cd12f995ed 100644
--- a/gtk/gtkdragdest.c
+++ b/gtk/gtkdragdest.c
@@ -31,7 +31,7 @@
#include "gtkintl.h"
#include "gtknative.h"
#include "gtktypebuiltins.h"
-#include "gtkeventcontroller.h"
+#include "gtkeventcontrollerprivate.h"
#include "gtkmarshalers.h"
#include "gtkselectionprivate.h"
@@ -51,7 +51,7 @@
struct _GtkDropTarget
{
- GObject parent_instance;
+ GtkEventController parent_object;
GdkContentFormats *formats;
GdkDragAction actions;
@@ -64,7 +64,7 @@ struct _GtkDropTarget
struct _GtkDropTargetClass
{
- GObjectClass parent_class;
+ GtkEventControllerClass parent_class;
gboolean (*drag_motion) (GtkDropTarget *dest,
int x,
@@ -94,7 +94,15 @@ static gboolean gtk_drop_target_drag_motion (GtkDropTarget *dest,
int x,
int y);
-G_DEFINE_TYPE (GtkDropTarget, gtk_drop_target, G_TYPE_OBJECT);
+static gboolean gtk_drop_target_handle_event (GtkEventController *controller,
+ const GdkEvent *event);
+static gboolean gtk_drop_target_filter_event (GtkEventController *controller,
+ const GdkEvent *event);
+static void gtk_drop_target_set_widget (GtkEventController *controller,
+ GtkWidget *widget);
+static void gtk_drop_target_unset_widget (GtkEventController *controller);
+
+G_DEFINE_TYPE (GtkDropTarget, gtk_drop_target, GTK_TYPE_EVENT_CONTROLLER);
static void
gtk_drop_target_init (GtkDropTarget *dest)
@@ -165,11 +173,17 @@ static void
gtk_drop_target_class_init (GtkDropTargetClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
+ GtkEventControllerClass *controller_class = GTK_EVENT_CONTROLLER_CLASS (class);
object_class->finalize = gtk_drop_target_finalize;
object_class->set_property = gtk_drop_target_set_property;
object_class->get_property = gtk_drop_target_get_property;
+ controller_class->handle_event = gtk_drop_target_handle_event;
+ controller_class->filter_event = gtk_drop_target_filter_event;
+ controller_class->set_widget = gtk_drop_target_set_widget;
+ controller_class->unset_widget = gtk_drop_target_unset_widget;
+
class->drag_motion = gtk_drop_target_drag_motion;
/**
@@ -445,28 +459,11 @@ void
gtk_drop_target_attach (GtkDropTarget *dest,
GtkWidget *widget)
{
- GtkDropTarget *old_dest;
-
g_return_if_fail (GTK_IS_DROP_TARGET (dest));
- g_return_if_fail (dest->widget == NULL);
g_return_if_fail (GTK_IS_WIDGET (widget));
- old_dest = g_object_get_data (G_OBJECT (widget), I_("gtk-drag-dest"));
- if (old_dest)
- {
- g_signal_handlers_disconnect_by_func (widget, gtk_drag_dest_realized, old_dest);
- g_signal_handlers_disconnect_by_func (widget, gtk_drag_dest_hierarchy_changed, old_dest);
- }
-
- if (gtk_widget_get_realized (widget))
- gtk_drag_dest_realized (widget);
-
- dest->widget = widget;
-
- g_signal_connect (widget, "realize", G_CALLBACK (gtk_drag_dest_realized), dest);
- g_signal_connect (widget, "notify::root", G_CALLBACK (gtk_drag_dest_hierarchy_changed), dest);
-
- g_object_set_data_full (G_OBJECT (widget), I_("gtk-drag-dest"), dest, g_object_unref);
+ gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (dest), GTK_PHASE_BUBBLE);
+ gtk_widget_add_controller (widget, GTK_EVENT_CONTROLLER (dest));
}
/**
@@ -478,17 +475,12 @@ gtk_drop_target_attach (GtkDropTarget *dest,
void
gtk_drop_target_detach (GtkDropTarget *dest)
{
- g_return_if_fail (GTK_IS_DROP_TARGET (dest));
-
- if (dest->widget)
- {
- g_signal_handlers_disconnect_by_func (dest->widget, gtk_drag_dest_realized, dest);
- g_signal_handlers_disconnect_by_func (dest->widget, gtk_drag_dest_hierarchy_changed, dest);
+ GtkWidget *widget;
- g_object_set_data (G_OBJECT (dest->widget), I_("gtk-drag-dest"), NULL);
+ g_return_if_fail (GTK_IS_DROP_TARGET (dest));
- dest->widget = NULL;
- }
+ widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
+ gtk_widget_remove_controller (widget, GTK_EVENT_CONTROLLER (dest));
}
/**
@@ -504,7 +496,7 @@ gtk_drop_target_get_target (GtkDropTarget *dest)
{
g_return_val_if_fail (GTK_IS_DROP_TARGET (dest), NULL);
- return dest->widget;
+ return gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
}
/**
@@ -650,6 +642,10 @@ void
gtk_drop_target_set_armed (GtkDropTarget *dest,
gboolean armed)
{
+ GtkWidget *widget;
+
+ widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
+
dest->armed_pending = FALSE;
if (dest->armed == armed)
@@ -657,13 +653,10 @@ gtk_drop_target_set_armed (GtkDropTarget *dest,
dest->armed = armed;
- if (dest->widget)
- {
- if (armed)
- gtk_drag_highlight (dest->widget);
- else
- gtk_drag_unhighlight (dest->widget);
- }
+ if (armed)
+ gtk_drag_highlight (widget);
+ else
+ gtk_drag_unhighlight (widget);
g_object_notify_by_pspec (G_OBJECT (dest), properties[PROP_ARMED]);
}
@@ -674,6 +667,104 @@ gtk_drop_target_get_armed (GtkDropTarget *dest)
return dest->armed;
}
+static gboolean
+gtk_drop_target_filter_event (GtkEventController *controller,
+ const GdkEvent *event)
+{
+ switch ((int)gdk_event_get_event_type (event))
+ {
+ case GDK_DRAG_ENTER:
+ case GDK_DRAG_LEAVE:
+ case GDK_DRAG_MOTION:
+ case GDK_DROP_START:
+ return GTK_EVENT_CONTROLLER_CLASS (gtk_drop_target_parent_class)->filter_event (controller, event);
+
+ default:;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+gtk_drop_target_handle_event (GtkEventController *controller,
+ const GdkEvent *event)
+{
+ GtkDropTarget *dest = GTK_DROP_TARGET (controller);
+ GdkDrop *drop;
+ GtkDragDestInfo *info;
+ double x, y;
+ gboolean found = FALSE;
+
+ gdk_event_get_coords (event, &x, &y);
+
+ drop = gdk_event_get_drop (event);
+ info = gtk_drag_get_dest_info (drop, TRUE);
+
+ switch ((int)gdk_event_get_event_type (event))
+ {
+ case GDK_DRAG_MOTION:
+ found = gtk_drop_target_emit_drag_motion (dest, drop, x, y);
+ break;
+
+ case GDK_DROP_START:
+ /* We send a leave before the drop so that the widget unhighlights
+ * properly.
+ */
+ if (info->dest)
+ {
+ gtk_drop_target_emit_drag_leave (info->dest, drop);
+ gtk_drag_dest_set_target (info, NULL);
+ }
+
+ found = gtk_drop_target_emit_drag_drop (dest, drop, x, y);
+ break;
+
+ default:
+ break;
+ }
+
+ if (found)
+ {
+ if (info->dest && info->dest != dest)
+ {
+ gtk_drop_target_emit_drag_leave (info->dest, drop);
+ gtk_drag_dest_set_target (info, NULL);
+ }
+
+ gtk_drag_dest_set_target (info, dest);
+ }
+
+ return found;
+}
+
+static void
+gtk_drop_target_set_widget (GtkEventController *controller,
+ GtkWidget *widget)
+{
+ GtkDropTarget *dest = GTK_DROP_TARGET (controller);
+
+ GTK_EVENT_CONTROLLER_CLASS (gtk_drop_target_parent_class)->set_widget (controller, widget);
+
+ if (gtk_widget_get_realized (widget))
+ gtk_drag_dest_realized (widget);
+
+ g_signal_connect (widget, "realize", G_CALLBACK (gtk_drag_dest_realized), dest);
+ g_signal_connect (widget, "notify::root", G_CALLBACK (gtk_drag_dest_hierarchy_changed), dest);
+}
+
+static void
+gtk_drop_target_unset_widget (GtkEventController *controller)
+{
+ GtkWidget *widget;
+
+ widget = gtk_event_controller_get_widget (controller);
+
+ g_signal_handlers_disconnect_by_func (widget, gtk_drag_dest_realized, controller);
+ g_signal_handlers_disconnect_by_func (widget, gtk_drag_dest_hierarchy_changed, controller);
+
+ GTK_EVENT_CONTROLLER_CLASS (gtk_drop_target_parent_class)->unset_widget (controller);
+}
+
/**
* gtk_drag_highlight: (method)
* @widget: a widget to highlight
@@ -810,13 +901,16 @@ gtk_drop_target_read_selection (GtkDropTarget *dest,
gpointer user_data)
{
GTask *task;
+ GtkWidget *widget;
g_return_if_fail (GTK_IS_DROP_TARGET (dest));
task = g_task_new (dest, NULL, callback, user_data);
g_object_set_data_full (G_OBJECT (task), "drop", g_object_ref (dest->drop), g_object_unref);
- if (dest->widget)
- g_object_set_data (G_OBJECT (task), "display", gtk_widget_get_display (dest->widget));
+
+ widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
+ if (widget)
+ g_object_set_data (G_OBJECT (task), "display", gtk_widget_get_display (widget));
gdk_drop_read_async (dest->drop,
(const char *[2]) { target, NULL },
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]