[gtk/readonly-events-1: 2/9] motion controller: Match focus event propagation



commit d99bcc67ec99efef0c5a7f820f3230895b1fcd5d
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Feb 20 23:20:58 2020 -0500

    motion controller: Match focus event propagation
    
    Make the crossing event generation for pointer events
    match what we do for focus now.

 gtk/gtkeventcontrollermotion.c | 29 ++++++++++---------
 gtk/gtkmain.c                  | 64 ++++++++++++++++++++++++++++++++++++++----
 gtk/gtkprivate.h               |  6 ++++
 gtk/gtkwindow.c                |  9 +++---
 4 files changed, 84 insertions(+), 24 deletions(-)
---
diff --git a/gtk/gtkeventcontrollermotion.c b/gtk/gtkeventcontrollermotion.c
index d0182cbcc0..10bd80991f 100644
--- a/gtk/gtkeventcontrollermotion.c
+++ b/gtk/gtkeventcontrollermotion.c
@@ -41,9 +41,6 @@ struct _GtkEventControllerMotion
 {
   GtkEventController parent_instance;
 
-  GdkEvent *current_event;
-  const GtkCrossingData *current_crossing;
-
   guint is_pointer             : 1;
   guint contains_pointer       : 1;
 };
@@ -105,18 +102,28 @@ update_pointer_focus (GtkEventController    *controller,
 
   if (crossing->direction == GTK_CROSSING_IN)
     {
+     if (crossing->new_descendent != NULL)
+        {
+          contains_pointer = TRUE;
+        }
       if (crossing->new_target == widget)
-        is_pointer = TRUE;
-      if (crossing->new_target != NULL)
+        {
+          contains_pointer = TRUE;
+          is_pointer = TRUE;
+        }
+    }
+  else
+    {
+      if (crossing->new_descendent != NULL ||
+          crossing->new_target == widget)
         contains_pointer = TRUE;
+      is_pointer = FALSE;
     }
 
   if (motion->contains_pointer != contains_pointer)
     {
-      if (contains_pointer)
-        enter = TRUE;
-      else
-        leave = TRUE;
+      enter = contains_pointer;
+      leave = !contains_pointer;
     }
 
   if (leave)
@@ -150,11 +157,7 @@ gtk_event_controller_motion_handle_crossing (GtkEventController    *controller,
   if (crossing->type != GTK_CROSSING_POINTER)
     return;
 
-  motion->current_crossing = crossing;
-
   update_pointer_focus (controller, crossing, x, y);
-
-  motion->current_crossing = NULL;
 }
 
 static void
diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c
index c17636beff..15637ed549 100644
--- a/gtk/gtkmain.c
+++ b/gtk/gtkmain.c
@@ -1309,20 +1309,52 @@ gtk_synthesize_crossing_events (GtkRoot         *toplevel,
                                 GdkCrossingMode  mode)
 {
   GtkCrossingData crossing;
+  GtkWidget *ancestor;
   GtkWidget *widget;
   GList *list, *l;
   double x, y;
+  GtkWidget *prev;
+  gboolean seen_ancestor;
+
+  if (old_target && new_target)
+    ancestor = gtk_widget_common_ancestor (old_target, new_target);
+  else
+    ancestor = NULL;
 
   crossing.type = GTK_CROSSING_POINTER;
   crossing.mode = mode;
   crossing.old_target = old_target;
+  crossing.old_descendent = NULL;
   crossing.new_target = new_target;
+  crossing.new_descendent = NULL;
 
   crossing.direction = GTK_CROSSING_OUT;
 
+  prev = NULL;
+  seen_ancestor = FALSE;
   widget = old_target;
   while (widget)
     {
+      crossing.old_descendent = prev;
+      if (seen_ancestor)
+        {
+          crossing.new_descendent = new_target ? prev : NULL;
+        }
+      else if (widget == ancestor)
+        {
+          GtkWidget *w;
+
+          crossing.new_descendent = NULL;
+          for (w = new_target; w != ancestor; w = gtk_widget_get_parent (w))
+            crossing.new_descendent = w;
+
+          seen_ancestor = TRUE;
+        }
+      else
+        {
+          crossing.new_descendent = NULL;
+        }
+      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);
@@ -1330,18 +1362,38 @@ gtk_synthesize_crossing_events (GtkRoot         *toplevel,
     }
 
   list = NULL;
-  widget = new_target;
-  while (widget)
-    {
-      list = g_list_prepend (list, widget);
-      widget = gtk_widget_get_parent (widget);
-    }
+  for (widget = new_target; widget; widget = gtk_widget_get_parent (widget))
+    list = g_list_prepend (list, widget);
 
   crossing.direction = GTK_CROSSING_IN;
 
+  seen_ancestor = FALSE;
   for (l = list; l; l = l->next)
     {
       widget = l->data;
+      if (l->next)
+        crossing.new_descendent = l->next->data;
+      else
+        crossing.new_descendent = NULL;
+      if (seen_ancestor)
+        {
+          crossing.old_descendent = NULL;
+        }
+      else if (widget == ancestor)
+        {
+          GtkWidget *w;
+
+          crossing.old_descendent = NULL;
+          for (w = old_target; w != ancestor; w = gtk_widget_get_parent (w))
+            crossing.old_descendent = w;
+
+          seen_ancestor = TRUE;
+        }
+      else
+        {
+          crossing.old_descendent = old_target ? crossing.new_descendent : NULL;
+        }
+
       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);
diff --git a/gtk/gtkprivate.h b/gtk/gtkprivate.h
index 13bbc058e1..9e4e73a11f 100644
--- a/gtk/gtkprivate.h
+++ b/gtk/gtkprivate.h
@@ -31,6 +31,7 @@
 
 #include "gtkcsstypesprivate.h"
 #include "gtktexthandleprivate.h"
+#include "gtkeventcontrollerprivate.h"
 
 G_BEGIN_DECLS
 
@@ -97,6 +98,11 @@ gboolean   gtk_propagate_event          (GtkWidget       *widget,
                                          GdkEvent        *event);
 void       gtk_main_do_event       (GdkEvent           *event);
 
+GtkWidget *gtk_get_event_widget         (GdkEvent  *event);
+
+void check_crossing_invariants (GtkWidget       *widget,
+                                GtkCrossingData *crossing);
+
 gdouble _gtk_get_slowdown (void);
 void    _gtk_set_slowdown (gdouble slowdown_factor);
 
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 6ae7b55ac4..d267c548f8 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -6355,10 +6355,11 @@ gtk_window_move_focus (GtkWidget        *widget,
     gtk_window_set_focus (GTK_WINDOW (widget), NULL);
 }
 
-static void
+void
 check_crossing_invariants (GtkWidget *widget,
                            GtkCrossingData *crossing)
 {
+#ifdef G_ENBABLE_DEBUG
   if (crossing->old_target == NULL)
     g_assert (crossing->old_descendent == NULL);
   else if (crossing->old_descendent == NULL)
@@ -6379,6 +6380,7 @@ check_crossing_invariants (GtkWidget *widget,
       g_assert (gtk_widget_is_ancestor (crossing->new_descendent, widget));
       g_assert (crossing->new_target == crossing->new_descendent || gtk_widget_is_ancestor 
(crossing->new_target, crossing->new_descendent));
     }
+#endif
 }
 
 static void
@@ -6440,7 +6442,6 @@ synthesize_focus_change_events (GtkWindow *window,
       check_crossing_invariants (widget, &crossing);
       gtk_widget_handle_crossing (widget, &crossing, 0, 0);
       gtk_widget_unset_state_flags (widget, flags);
-      gtk_widget_set_focus_child (widget, NULL);
       prev = widget;
       widget = gtk_widget_get_parent (widget);
     }
@@ -6471,9 +6472,7 @@ synthesize_focus_change_events (GtkWindow *window,
 
           crossing.old_descendent = NULL;
           for (w = old_focus; w != ancestor; w = gtk_widget_get_parent (w))
-            {
-              crossing.old_descendent = w;
-            }
+            crossing.old_descendent = w;
 
           seen_ancestor = TRUE;
         }


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