From adba0b972e2a86d8f169222d7e64c346dc746325 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 5 Aug 2022 16:39:56 +0200 Subject: [PATCH] gtkwindow: Synthesize pointer crossing events on state changes When widgets go mapped/unmapped, we repick but don't generate crossing events. Since there could be stateful controllers that use those in the previously picked widget (e.g. GtkEventControllerMotion), skipping those breaks their state. Ensure to send the relevant crossing events on every situation that changes the pointer focus, so these controllers get a fair opportunity to undo their state. Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/2877 --- gtk/gtkwindow.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 2c8c5502e8..7d7c4a312b 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -4968,6 +4968,9 @@ synthesize_focus_change_events (GtkWindow *window, GtkWidget *prev; gboolean seen_ancestor; + if (old_focus == new_focus) + return; + if (old_focus && new_focus) ancestor = gtk_widget_common_ancestor (old_focus, new_focus); else @@ -6455,7 +6458,12 @@ gtk_window_update_pointer_focus_on_state_change (GtkWindow *window, else if (focus->target == widget || gtk_widget_is_ancestor (focus->target, widget)) { + GtkWidget *old_target; + + old_target = g_object_ref (focus->target); gtk_pointer_focus_repick_target (focus); + synthesize_focus_change_events (window, old_target, focus->target, GTK_CROSSING_POINTER); + g_object_unref (old_target); } gtk_pointer_focus_unref (focus); -- 2.30.2