diff options
author | Matthias Clasen <mclasen@redhat.com> | 2020-02-20 23:20:58 -0500 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2020-02-21 00:51:03 -0500 |
commit | e062137b2ce59fd52ab5604b65345a00200631dc (patch) | |
tree | 8fb4c3153301c7476a7fabff3ecec158d6bcb4b9 | |
parent | 77aed615e803d3039af62a1416368248c0457c39 (diff) | |
download | gtk+-e062137b2ce59fd52ab5604b65345a00200631dc.tar.gz |
motion controller: Match focus event propagation
Make the crossing event generation for pointer events
match what we do for focus now.
-rw-r--r-- | gtk/gtkeventcontrollermotion.c | 37 | ||||
-rw-r--r-- | gtk/gtkmain.c | 64 | ||||
-rw-r--r-- | gtk/gtkprivate.h | 6 | ||||
-rw-r--r-- | gtk/gtkwindow.c | 4 |
4 files changed, 85 insertions, 26 deletions
diff --git a/gtk/gtkeventcontrollermotion.c b/gtk/gtkeventcontrollermotion.c index d0182cbcc0..aaea7081d9 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) @@ -145,16 +152,8 @@ gtk_event_controller_motion_handle_crossing (GtkEventController *controller, double x, double y) { - GtkEventControllerMotion *motion = GTK_EVENT_CONTROLLER_MOTION (controller); - - if (crossing->type != GTK_CROSSING_POINTER) - return; - - motion->current_crossing = crossing; - - update_pointer_focus (controller, crossing, x, y); - - motion->current_crossing = NULL; + if (crossing->type == GTK_CROSSING_POINTER) + update_pointer_focus (controller, crossing, x, y); } static void diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c index 21ea620b7e..8ca682925f 100644 --- a/gtk/gtkmain.c +++ b/gtk/gtkmain.c @@ -1312,20 +1312,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); @@ -1333,18 +1365,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 9a60d813d1..7b1c9c2f6d 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -6352,10 +6352,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) @@ -6376,6 +6377,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 |