[gtk/gtk-4-6: 7/15] gtkwindow: Synthesize pointer crossing events on state changes




commit dd82df9e32dfc8f1fb13c1cfc8111c41bb6d501a
Author: Carlos Garnacho <carlosg gnome org>
Date:   Fri Aug 5 16:39:56 2022 +0200

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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]