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
committed by Mat
parent 1a459c5dcd
commit dd82df9e32

View File

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