[gtk/wip/otte/dnd: 3/9] gtk: Bubble drag events like motion events



commit 88fe458489bb1bd2f628fba3a5e2111c2370d137
Author: Benjamin Otte <otte redhat com>
Date:   Wed Feb 19 04:44:41 2020 +0100

    gtk: Bubble drag events like motion events
    
    Emit crossing events - with a new GTK_CROSSING_DROP type - like we do
    for motion events. There is no more special casing for them.
    
    Note that the gesture has not been updated yet, so some obscure behavior
    may occur.

 gtk/gtkeventcontrollerprivate.h |  7 +++-
 gtk/gtkmain.c                   | 86 ++++++++++++++++++-----------------------
 gtk/gtkwidgetprivate.h          |  6 ---
 3 files changed, 42 insertions(+), 57 deletions(-)
---
diff --git a/gtk/gtkeventcontrollerprivate.h b/gtk/gtkeventcontrollerprivate.h
index e9e17f14e4..571d78f960 100644
--- a/gtk/gtkeventcontrollerprivate.h
+++ b/gtk/gtkeventcontrollerprivate.h
@@ -24,7 +24,8 @@
 
 typedef enum {
   GTK_CROSSING_FOCUS,
-  GTK_CROSSING_POINTER
+  GTK_CROSSING_POINTER,
+  GTK_CROSSING_DROP
 } GtkCrossingType;
 
 typedef enum {
@@ -47,11 +48,12 @@ typedef struct _GtkCrossingData GtkCrossingData;
  * @new_descendent: the direct child of the receiving widget that
  *     is an ancestor of @new_target, or %NULL if @new_target is not
  *     a descendent of the receiving widget
+ * @drop: the #GdkDrop if this is info for a drop operation
  *
  * The struct that is passed to gtk_event_controller_handle_crossing().
  *
  * The @old_target and @new_target fields are set to the old or new
- * focus or hover location.
+ * focus, drop or hover location.
  */
 struct _GtkCrossingData {
   GtkCrossingType type;
@@ -61,6 +63,7 @@ struct _GtkCrossingData {
   GtkWidget *old_descendent;
   GtkWidget *new_target;
   GtkWidget *new_descendent;
+  GdkDrop *drop;
 };
 
 struct _GtkEventController
diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c
index 20b232c5f6..98bb83dd22 100644
--- a/gtk/gtkmain.c
+++ b/gtk/gtkmain.c
@@ -1304,12 +1304,14 @@ translate_event_coordinates (GdkEvent  *event,
   return TRUE;
 }
 
-void
+static void
 gtk_synthesize_crossing_events (GtkRoot         *toplevel,
+                                GtkCrossingType  crossing_type,
                                 GtkWidget       *old_target,
                                 GtkWidget       *new_target,
                                 GdkEvent        *event,
-                                GdkCrossingMode  mode)
+                                GdkCrossingMode  mode,
+                                GdkDrop         *drop)
 {
   GtkCrossingData crossing;
   GtkWidget *ancestor;
@@ -1324,12 +1326,13 @@ gtk_synthesize_crossing_events (GtkRoot         *toplevel,
   else
     ancestor = NULL;
 
-  crossing.type = GTK_CROSSING_POINTER;
+  crossing.type = crossing_type;
   crossing.mode = mode;
   crossing.old_target = old_target;
   crossing.old_descendent = NULL;
   crossing.new_target = new_target;
   crossing.new_descendent = NULL;
+  crossing.drop = drop;
 
   crossing.direction = GTK_CROSSING_OUT;
 
@@ -1360,7 +1363,8 @@ gtk_synthesize_crossing_events (GtkRoot         *toplevel,
       check_crossing_invariants (widget, &crossing);
       translate_event_coordinates (event, &x, &y, widget);
       gtk_widget_handle_crossing (widget, &crossing, x, y);
-      gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_PRELIGHT);
+      if (crossing_type == GTK_CROSSING_POINTER)
+        gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_PRELIGHT);
       widget = gtk_widget_get_parent (widget);
     }
 
@@ -1399,7 +1403,8 @@ gtk_synthesize_crossing_events (GtkRoot         *toplevel,
 
       translate_event_coordinates (event, &x, &y, widget);
       gtk_widget_handle_crossing (widget, &crossing, x, y);
-      gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_PRELIGHT, FALSE);
+      if (crossing_type == GTK_CROSSING_POINTER)
+        gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_PRELIGHT, FALSE);
     }
 
   g_list_free (list);
@@ -1445,8 +1450,12 @@ is_pointing_event (GdkEvent *event)
     case GDK_TOUCH_CANCEL:
     case GDK_TOUCHPAD_PINCH:
     case GDK_TOUCHPAD_SWIPE:
+    case GDK_DRAG_ENTER:
+    case GDK_DRAG_LEAVE:
+    case GDK_DRAG_MOTION:
+    case GDK_DROP_START:
       return TRUE;
-      break;
+
     default:
       return FALSE;
     }
@@ -1479,21 +1488,6 @@ is_focus_event (GdkEvent *event)
     }
 }
 
-static gboolean
-is_dnd_event (GdkEvent *event)
-{
-  switch ((guint) gdk_event_get_event_type (event))
-    {
-    case GDK_DRAG_ENTER:
-    case GDK_DRAG_LEAVE:
-    case GDK_DRAG_MOTION:
-    case GDK_DROP_START:
-      return TRUE;
-    default:
-      return FALSE;
-    }
-}
-
 static inline void
 set_widget_active_state (GtkWidget       *target,
                          const gboolean   release)
@@ -1549,14 +1543,22 @@ handle_pointing_event (GdkEvent *event)
     case GDK_TOUCH_CANCEL:
       old_target = update_pointer_focus_state (toplevel, event, NULL);
       if (type == GDK_LEAVE_NOTIFY)
-        gtk_synthesize_crossing_events (GTK_ROOT (toplevel), old_target, NULL,
-                                        event, gdk_crossing_event_get_mode (event));
+        gtk_synthesize_crossing_events (GTK_ROOT (toplevel), GTK_CROSSING_POINTER, old_target, NULL,
+                                        event, gdk_crossing_event_get_mode (event), NULL);
+      break;
+    case GDK_DRAG_LEAVE:
+      old_target = update_pointer_focus_state (toplevel, event, NULL);
+      gtk_synthesize_crossing_events (GTK_ROOT (toplevel), GTK_CROSSING_DROP, old_target, NULL,
+                                      event, GDK_CROSSING_NORMAL, gdk_drag_event_get_drop (event));
       break;
     case GDK_ENTER_NOTIFY:
       if (gdk_crossing_event_get_mode (event) == GDK_CROSSING_GRAB ||
           gdk_crossing_event_get_mode (event) == GDK_CROSSING_UNGRAB)
         break;
       G_GNUC_FALLTHROUGH;
+    case GDK_DRAG_ENTER:
+    case GDK_DRAG_MOTION:
+    case GDK_DROP_START:
     case GDK_TOUCH_BEGIN:
     case GDK_TOUCH_UPDATE:
     case GDK_MOTION_NOTIFY:
@@ -1575,14 +1577,18 @@ handle_pointing_event (GdkEvent *event)
           if (!gtk_window_lookup_pointer_focus_implicit_grab (toplevel, device,
                                                               sequence))
             {
-              gtk_synthesize_crossing_events (GTK_ROOT (toplevel), old_target, target,
-                                              event, GDK_CROSSING_NORMAL);
+              gtk_synthesize_crossing_events (GTK_ROOT (toplevel), GTK_CROSSING_POINTER, old_target, target,
+                                              event, GDK_CROSSING_NORMAL, NULL);
             }
 
           gtk_window_maybe_update_cursor (toplevel, NULL, device);
         }
-
-      if (type == GDK_TOUCH_BEGIN)
+      else if (type == GDK_DRAG_ENTER || type == GDK_DRAG_MOTION || type == GDK_DROP_START)
+        {
+          gtk_synthesize_crossing_events (GTK_ROOT (toplevel), GTK_CROSSING_DROP, old_target, target,
+                                          event, GDK_CROSSING_NORMAL, gdk_drag_event_get_drop (event));
+        }
+      else if (type == GDK_TOUCH_BEGIN)
         gtk_window_set_pointer_focus_grab (toplevel, device, sequence, target);
 
       /* Let it take the effective pointer focus anyway, as it may change due
@@ -1605,8 +1611,8 @@ handle_pointing_event (GdkEvent *event)
           new_target = gtk_widget_pick (GTK_WIDGET (native), x, y, GTK_PICK_DEFAULT);
           if (new_target == NULL)
             new_target = GTK_WIDGET (toplevel);
-          gtk_synthesize_crossing_events (GTK_ROOT (toplevel), target, new_target,
-                                          event, GDK_CROSSING_UNGRAB);
+          gtk_synthesize_crossing_events (GTK_ROOT (toplevel), GTK_CROSSING_POINTER, target, new_target,
+                                          event, GDK_CROSSING_UNGRAB, NULL);
           gtk_window_maybe_update_cursor (toplevel, NULL, device);
         }
 
@@ -1640,23 +1646,6 @@ handle_key_event (GdkEvent *event)
   return focus_widget ? focus_widget : event_widget;
 }
 
-static GtkWidget *
-handle_dnd_event (GdkEvent *event)
-{
-  GtkWidget *event_widget;
-  GtkWidget *target;
-  gdouble x, y;
-  GtkWidget *native;
-
-  event_widget = gtk_get_event_widget (event);
-
-  gdk_event_get_position (event, &x, &y);
-  native = GTK_WIDGET (gtk_widget_get_native (event_widget));
-  target = gtk_widget_pick (native, x, y, GTK_PICK_DEFAULT);
-
-  return target;
-}
-
 void
 gtk_main_do_event (GdkEvent *event)
 {
@@ -1715,8 +1704,6 @@ gtk_main_do_event (GdkEvent *event)
           goto cleanup;
         }
     }
-  else if (is_dnd_event (event))
-    target_widget = handle_dnd_event (event);
 
   if (!target_widget)
     goto cleanup;
@@ -1812,14 +1799,15 @@ gtk_main_do_event (GdkEvent *event)
       /* Crossing event propagation happens during picking */
       break;
 
-    case GDK_DRAG_ENTER:
     case GDK_DRAG_MOTION:
     case GDK_DROP_START:
       if (gtk_propagate_event (target_widget, event))
         break;
       G_GNUC_FALLTHROUGH;
 
+    case GDK_DRAG_ENTER:
     case GDK_DRAG_LEAVE:
+      /* Crossing event propagation happens during picking */
       gtk_drag_dest_handle_event (target_widget, event);
       break;
 
diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h
index 93ded92b50..b1efa36f39 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -259,12 +259,6 @@ GdkSurface *       _gtk_widget_get_device_surface          (GtkWidget *widget,
                                                             GdkDevice *device);
 GList *           _gtk_widget_list_devices                 (GtkWidget *widget);
 
-void              gtk_synthesize_crossing_events           (GtkRoot         *toplevel,
-                                                            GtkWidget       *from,
-                                                            GtkWidget       *to,
-                                                            GdkEvent        *source,
-                                                            GdkCrossingMode  mode);
-
 void              _gtk_widget_synthesize_crossing          (GtkWidget       *from,
                                                             GtkWidget       *to,
                                                             GdkDevice       *device,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]