[gtk/wip/carlosg/fixes: 7/8] gtkwindow: Synthesize pointer crossing events on state changes




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


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