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
This commit is contained in:
Carlos Garnacho 2022-08-05 16:39:56 +02:00
parent c77b98d716
commit adba0b972e

View File

@ -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);