From dd82df9e32dfc8f1fb13c1cfc8111c41bb6d501a 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 a658471c12..060f89140b 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -5012,6 +5012,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 @@ -6462,7 +6465,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);