[gtk/readonly-events-1: 3/10] motion controller: Match focus event propagation
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/readonly-events-1: 3/10] motion controller: Match focus event propagation
- Date: Fri, 21 Feb 2020 05:24:17 +0000 (UTC)
commit a2f053ebd2fe6833e4dabf2ceefcceb677f2cbf7
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 | 37 ++++++++++++------------
gtk/gtkmain.c | 64 ++++++++++++++++++++++++++++++++++++++----
gtk/gtkprivate.h | 6 ++++
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 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..66f48ca5ca 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
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]