[gtk/wip/matthiasc/focus2: 44/50] Share crossing and focus change event code



commit fa9911a956fd0c4a8eee4edf196e417d9ed5c481
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Mar 6 22:25:31 2019 -0500

    Share crossing and focus change event code
    
    Make a single function that can emit both
    enter/leave and focus change events.

 gtk/gtkmain.c | 96 +++++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 61 insertions(+), 35 deletions(-)
---
diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c
index be19d7389c..3f8e50c288 100644
--- a/gtk/gtkmain.c
+++ b/gtk/gtkmain.c
@@ -1413,55 +1413,57 @@ synth_crossing (GtkWidget       *widget,
                 GdkCrossingMode  crossing_mode)
 {
   GdkEvent *event;
-  gdouble x, y;
+  GtkStateFlags flags;
+
+  if (gdk_event_get_event_type (source) == GDK_FOCUS_CHANGE)
+    {
+      event = gdk_event_new (GDK_FOCUS_CHANGE);
+      event->focus_change.in = enter;
+      event->focus_change.mode = crossing_mode;
+      event->focus_change.detail = notify_type;
+
+      flags = GTK_STATE_FLAG_FOCUSED;
+      if (!GTK_IS_WINDOW (toplevel) || gtk_window_get_focus_visible (GTK_WINDOW (toplevel)))
+        flags |= GTK_STATE_FLAG_FOCUS_VISIBLE;
+    }
+  else
+    {
+      gdouble x, y;
+      event = gdk_event_new (enter ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY);
+      if (other_widget)
+        event->crossing.child_surface = g_object_ref (gtk_widget_get_surface (other_widget));
+      gdk_event_get_coords (source, &x, &y);
+      event->crossing.x = x;
+      event->crossing.y = y;
+      event->crossing.mode = crossing_mode;
+      event->crossing.detail = notify_type;
+
+      flags = GTK_STATE_FLAG_PRELIGHT;
+    }
 
-  event = gdk_event_new (enter ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY);
   gdk_event_set_user_data (event, G_OBJECT (widget));
   gdk_event_set_device (event, gdk_event_get_device (source));
   gdk_event_set_source_device (event, gdk_event_get_source_device (source));
 
   event->any.surface = g_object_ref (gtk_widget_get_surface (toplevel));
-  if (other_widget)
-    event->crossing.child_surface = g_object_ref (gtk_widget_get_surface (other_widget));
 
   if (enter)
-    gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_PRELIGHT, FALSE);
+    gtk_widget_set_state_flags (widget, flags, FALSE);
   else
-    gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_PRELIGHT);
-
-  gdk_event_get_coords (source, &x, &y);
-  event->crossing.x = x;
-  event->crossing.y = y;
-  event->crossing.mode = crossing_mode;
-  event->crossing.detail = notify_type;
+    gtk_widget_unset_state_flags (widget, flags);
 
+  if (gdk_event_get_event_type (source) == GDK_FOCUS_CHANGE)
+    {
+      if (notify_type == GDK_NOTIFY_ANCESTOR ||
+          notify_type == GDK_NOTIFY_INFERIOR ||
+          notify_type == GDK_NOTIFY_NONLINEAR)
+        gtk_widget_set_has_focus (widget, enter);
+    }
+    
   gtk_widget_event (widget, event);
   g_object_unref (event);
 }
 
-static GtkWidget *
-update_pointer_focus_state (GtkWindow *toplevel,
-                            GdkEvent  *event,
-                            GtkWidget *new_target)
-{
-  GtkWidget *old_target = NULL;
-  GdkEventSequence *sequence;
-  GdkDevice *device;
-  gdouble x, y;
-
-  device = gdk_event_get_device (event);
-  sequence = gdk_event_get_event_sequence (event);
-  old_target = gtk_window_lookup_pointer_focus_widget (toplevel, device, sequence);
-  if (old_target == new_target)
-    return old_target;
-
-  gdk_event_get_coords (event, &x, &y);
-  gtk_window_update_pointer_focus (toplevel, device, sequence,
-                                   new_target, x, y);
-
-  return old_target;
-}
-
 static void
 gtk_synthesize_crossing_events (GtkWindow       *toplevel,
                                 GtkWidget       *old_target,
@@ -1528,6 +1530,30 @@ gtk_synthesize_crossing_events (GtkWindow       *toplevel,
     }
 }
 
+
+static GtkWidget *
+update_pointer_focus_state (GtkWindow *toplevel,
+                            GdkEvent  *event,
+                            GtkWidget *new_target)
+{
+  GtkWidget *old_target = NULL;
+  GdkEventSequence *sequence;
+  GdkDevice *device;
+  gdouble x, y;
+
+  device = gdk_event_get_device (event);
+  sequence = gdk_event_get_event_sequence (event);
+  old_target = gtk_window_lookup_pointer_focus_widget (toplevel, device, sequence);
+  if (old_target == new_target)
+    return old_target;
+
+  gdk_event_get_coords (event, &x, &y);
+  gtk_window_update_pointer_focus (toplevel, device, sequence,
+                                   new_target, x, y);
+
+  return old_target;
+}
+
 static gboolean
 is_pointing_event (GdkEvent *event)
 {


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