[gtk+] gdk: Drop generation of synthesized crossing events on grabs



commit 3e1f6721709c60dd17dd41c0aeeb5b80abcd8b21
Author: Carlos Garnacho <carlosg gnome org>
Date:   Fri Sep 15 18:31:18 2017 +0200

    gdk: Drop generation of synthesized crossing events on grabs
    
    GDK just needs to care about toplevels nowadays, which means these events
    are already delivered from the windowing. We don't need to generate
    intra-window crossing events ourselves.

 gdk/gdkdisplay.c |  117 +------------------
 gdk/gdkwindow.c  |  350 ------------------------------------------------------
 2 files changed, 1 insertions(+), 466 deletions(-)
---
diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c
index bdc9dab..a4a75bc 100644
--- a/gdk/gdkdisplay.c
+++ b/gdk/gdkdisplay.c
@@ -806,97 +806,6 @@ _gdk_display_end_touch_grab (GdkDisplay       *display,
   return FALSE;
 }
 
-/* _gdk_synthesize_crossing_events only works inside one toplevel.
-   This function splits things into two calls if needed, converting the
-   coordinates to the right toplevel */
-static void
-synthesize_crossing_events (GdkDisplay      *display,
-                            GdkDevice       *device,
-                            GdkDevice       *source_device,
-                           GdkWindow       *src_window,
-                           GdkWindow       *dest_window,
-                           GdkCrossingMode  crossing_mode,
-                           guint32          time,
-                           gulong           serial)
-{
-  GdkWindow *src_toplevel, *dest_toplevel;
-  GdkModifierType state;
-  double x, y;
-
-  if (src_window)
-    src_toplevel = gdk_window_get_toplevel (src_window);
-  else
-    src_toplevel = NULL;
-  if (dest_window)
-    dest_toplevel = gdk_window_get_toplevel (dest_window);
-  else
-    dest_toplevel = NULL;
-
-  if (src_toplevel == NULL && dest_toplevel == NULL)
-    return;
-  
-  if (src_toplevel == NULL ||
-      src_toplevel == dest_toplevel)
-    {
-      /* Same toplevels */
-      gdk_window_get_device_position_double (dest_toplevel,
-                                             device,
-                                             &x, &y, &state);
-      _gdk_synthesize_crossing_events (display,
-                                      src_window,
-                                      dest_window,
-                                       device, source_device,
-                                      crossing_mode,
-                                      x, y, state,
-                                      time,
-                                      NULL,
-                                      serial, FALSE);
-    }
-  else if (dest_toplevel == NULL)
-    {
-      gdk_window_get_device_position_double (src_toplevel,
-                                             device,
-                                             &x, &y, &state);
-      _gdk_synthesize_crossing_events (display,
-                                       src_window,
-                                       NULL,
-                                       device, source_device,
-                                       crossing_mode,
-                                       x, y, state,
-                                       time,
-                                       NULL,
-                                       serial, FALSE);
-    }
-  else
-    {
-      /* Different toplevels */
-      gdk_window_get_device_position_double (src_toplevel,
-                                             device,
-                                             &x, &y, &state);
-      _gdk_synthesize_crossing_events (display,
-                                      src_window,
-                                      NULL,
-                                       device, source_device,
-                                      crossing_mode,
-                                      x, y, state,
-                                      time,
-                                      NULL,
-                                      serial, FALSE);
-      gdk_window_get_device_position_double (dest_toplevel,
-                                             device,
-                                             &x, &y, &state);
-      _gdk_synthesize_crossing_events (display,
-                                      NULL,
-                                      dest_window,
-                                       device, source_device,
-                                      crossing_mode,
-                                      x, y, state,
-                                      time,
-                                      NULL,
-                                      serial, FALSE);
-    }
-}
-
 static GdkWindow *
 get_current_toplevel (GdkDisplay      *display,
                       GdkDevice       *device,
@@ -932,7 +841,7 @@ switch_to_pointer_grab (GdkDisplay        *display,
                        guint32            time,
                        gulong             serial)
 {
-  GdkWindow *src_window, *pointer_window, *new_toplevel;
+  GdkWindow *pointer_window, *new_toplevel;
   GdkPointerWindowInfo *info;
   GList *old_grabs;
   GdkModifierType state;
@@ -946,26 +855,8 @@ switch_to_pointer_grab (GdkDisplay        *display,
   if (grab)
     {
       /* New grab is in effect */
-
-      /* We need to generate crossing events for the grab.
-       * However, there are never any crossing events for implicit grabs
-       * TODO: ... Actually, this could happen if the pointer window
-       *           doesn't have button mask so a parent gets the event...
-       */
       if (!grab->implicit)
        {
-         /* We send GRAB crossing events from the window under the pointer to the
-            grab window. Except if there is an old grab then we start from that */
-         if (last_grab)
-           src_window = last_grab->window;
-         else
-           src_window = info->window_under_pointer;
-
-         if (src_window != grab->window)
-            synthesize_crossing_events (display, device, source_device,
-                                        src_window, grab->window,
-                                        GDK_CROSSING_GRAB, time, serial);
-
          /* !owner_event Grabbing a window that we're not inside, current status is
             now NULL (i.e. outside grabbed window) */
          if (!grab->owner_events && info->window_under_pointer != grab->window)
@@ -1029,12 +920,6 @@ switch_to_pointer_grab (GdkDisplay        *display,
                                                 NULL, NULL);
             }
 
-         if (!info->need_touch_press_enter &&
-             pointer_window != last_grab->window)
-            synthesize_crossing_events (display, device, source_device,
-                                        last_grab->window, pointer_window,
-                                        GDK_CROSSING_UNGRAB, time, serial);
-
          /* We're now ungrabbed, update the window_under_pointer */
          _gdk_display_set_window_under_pointer (display, device, pointer_window);
        }
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index f9fab82..14bea5a 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -5466,37 +5466,6 @@ point_in_input_window (GdkWindow *window,
   return FALSE;
 }
 
-static void
-convert_toplevel_coords_to_window (GdkWindow *window,
-                                  gdouble    toplevel_x,
-                                  gdouble    toplevel_y,
-                                  gdouble   *window_x,
-                                  gdouble   *window_y)
-{
-  GdkWindow *parent;
-  gdouble x, y;
-  GList *children, *l;
-
-  x = toplevel_x;
-  y = toplevel_y;
-
-  children = NULL;
-  while ((parent = window->parent) != NULL &&
-        (parent->window_type != GDK_WINDOW_ROOT))
-    {
-      children = g_list_prepend (children, window);
-      window = parent;
-    }
-
-  for (l = children; l != NULL; l = l->next)
-    gdk_window_coords_from_parent (l->data, x, y, &x, &y);
-
-  g_list_free (children);
-
-  *window_x = x;
-  *window_y = y;
-}
-
 GdkWindow *
 _gdk_window_find_child_at (GdkWindow *window,
                           double     x,
@@ -5670,43 +5639,6 @@ gdk_window_get_support_multidevice (GdkWindow *window)
 
 /* send motion events if the right buttons are down */
 
-static GdkWindow *
-find_common_ancestor (GdkWindow *win1,
-                     GdkWindow *win2)
-{
-  GdkWindow *tmp;
-  GList *path1 = NULL, *path2 = NULL;
-  GList *list1, *list2;
-
-  tmp = win1;
-  while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
-    {
-      path1 = g_list_prepend (path1, tmp);
-      tmp = tmp->parent;
-    }
-
-  tmp = win2;
-  while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
-    {
-      path2 = g_list_prepend (path2, tmp);
-      tmp = tmp->parent;
-    }
-
-  list1 = path1;
-  list2 = path2;
-  tmp = NULL;
-  while (list1 && list2 && (list1->data == list2->data))
-    {
-      tmp = list1->data;
-      list1 = list1->next;
-      list2 = list2->next;
-    }
-  g_list_free (path1);
-  g_list_free (path2);
-
-  return tmp;
-}
-
 GdkEvent *
 _gdk_make_event (GdkWindow    *window,
                 GdkEventType  type,
@@ -5827,288 +5759,6 @@ _gdk_make_event (GdkWindow    *window,
   return event;
 }
 
-static void
-send_crossing_event (GdkDisplay                 *display,
-                    GdkWindow                  *toplevel,
-                    GdkWindow                  *window,
-                    GdkEventType                type,
-                    GdkCrossingMode             mode,
-                    GdkNotifyType               notify_type,
-                    GdkWindow                  *subwindow,
-                     GdkDevice                  *device,
-                     GdkDevice                  *source_device,
-                    gdouble                     toplevel_x,
-                    gdouble                     toplevel_y,
-                    GdkModifierType             mask,
-                    guint32                     time_,
-                    GdkEvent                   *event_in_queue,
-                    gulong                      serial)
-{
-  GdkEvent *event;
-  guint32 window_event_mask, type_event_mask;
-  GdkDeviceGrabInfo *grab;
-  GdkTouchGrabInfo *touch_grab = NULL;
-  GdkPointerWindowInfo *pointer_info;
-  gboolean block_event = FALSE;
-  GdkEventSequence *sequence;
-
-  grab = _gdk_display_has_device_grab (display, device, serial);
-  pointer_info = _gdk_display_get_pointer_info (display, device);
-
-  sequence = gdk_event_get_event_sequence (event_in_queue);
-  if (sequence)
-    touch_grab = _gdk_display_has_touch_grab (display, device, sequence, serial);
-
-  if (touch_grab)
-    {
-      if (window != touch_grab->window)
-        return;
-
-      window_event_mask = touch_grab->event_mask;
-    }
-  else if (grab != NULL &&
-           !grab->owner_events)
-    {
-      /* !owner_event => only report events wrt grab window, ignore rest */
-      if ((GdkWindow *)window != grab->window)
-       return;
-      window_event_mask = grab->event_mask;
-    }
-  else
-    window_event_mask = window->event_mask;
-
-  if (type == GDK_ENTER_NOTIFY &&
-      (pointer_info->need_touch_press_enter ||
-       (source_device &&
-        gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN)) &&
-      mode != GDK_CROSSING_TOUCH_BEGIN &&
-      mode != GDK_CROSSING_TOUCH_END)
-    {
-      pointer_info->need_touch_press_enter = TRUE;
-      block_event = TRUE;
-    }
-  else if (type == GDK_LEAVE_NOTIFY)
-    {
-      type_event_mask = GDK_LEAVE_NOTIFY_MASK;
-      window->devices_inside = g_list_remove (window->devices_inside, device);
-
-      if (!window->support_multidevice && window->devices_inside)
-        {
-          /* Block leave events unless it's the last pointer */
-          block_event = TRUE;
-        }
-    }
-  else
-    {
-      type_event_mask = GDK_ENTER_NOTIFY_MASK;
-
-      if (!window->support_multidevice && window->devices_inside)
-        {
-          /* Only emit enter events for the first device */
-          block_event = TRUE;
-        }
-
-      if (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER &&
-          gdk_device_get_mode (device) != GDK_MODE_DISABLED &&
-          !g_list_find (window->devices_inside, device))
-        window->devices_inside = g_list_prepend (window->devices_inside, device);
-    }
-
-  if (block_event)
-    return;
-
-  if (window_event_mask & type_event_mask)
-    {
-      event = _gdk_make_event ((GdkWindow *)window, type, event_in_queue, TRUE);
-      gdk_event_set_device (event, device);
-      gdk_event_set_seat (event, gdk_device_get_seat (device));
-
-      if (source_device)
-        gdk_event_set_source_device (event, source_device);
-
-      event->crossing.time = time_;
-      event->crossing.subwindow = subwindow;
-      if (subwindow)
-       g_object_ref (subwindow);
-      convert_toplevel_coords_to_window ((GdkWindow *)window,
-                                        toplevel_x, toplevel_y,
-                                        &event->crossing.x, &event->crossing.y);
-      event->crossing.x_root = toplevel_x + toplevel->x;
-      event->crossing.y_root = toplevel_y + toplevel->y;
-      event->crossing.mode = mode;
-      event->crossing.detail = notify_type;
-      event->crossing.focus = FALSE;
-      event->crossing.state = mask;
-    }
-}
-
-
-/* The coordinates are in the toplevel window that src/dest are in.
- * src and dest are always (if != NULL) in the same toplevel, as
- * we get a leave-notify and set the window_under_pointer to null
- * before crossing to another toplevel.
- */
-void
-_gdk_synthesize_crossing_events (GdkDisplay                 *display,
-                                GdkWindow                  *src,
-                                GdkWindow                  *dest,
-                                 GdkDevice                  *device,
-                                 GdkDevice                  *source_device,
-                                GdkCrossingMode             mode,
-                                double                      toplevel_x,
-                                double                      toplevel_y,
-                                GdkModifierType             mask,
-                                guint32                     time_,
-                                GdkEvent                   *event_in_queue,
-                                gulong                      serial,
-                                gboolean                    non_linear)
-{
-  GdkWindow *c;
-  GdkWindow *win, *last, *next;
-  GList *path, *list;
-  GdkWindow *a;
-  GdkWindow *b;
-  GdkWindow *toplevel;
-  GdkNotifyType notify_type;
-
-  /* TODO: Don't send events to toplevel, as we get those from the windowing system */
-
-  a = (src && GDK_IS_WINDOW (src)) ? src : NULL;
-  b = (dest && GDK_IS_WINDOW (dest)) ? dest : NULL;
-
-  if (src == dest)
-    return; /* No crossings generated between src and dest */
-
-  if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER)
-    {
-      if (a && gdk_window_get_device_events (src, device) == 0)
-        a = NULL;
-
-      if (b && gdk_window_get_device_events (dest, device) == 0)
-        b = NULL;
-    }
-
-  if (!a && !b)
-    return;
-
-  c = find_common_ancestor (a, b);
-
-  non_linear |= (c != a) && (c != b);
-
-  if (a) /* There might not be a source (i.e. if no previous pointer_in_window) */
-    {
-      toplevel = gdk_window_get_toplevel (a);
-
-      /* Traverse up from a to (excluding) c sending leave events */
-      if (non_linear)
-       notify_type = GDK_NOTIFY_NONLINEAR;
-      else if (c == a)
-       notify_type = GDK_NOTIFY_INFERIOR;
-      else
-       notify_type = GDK_NOTIFY_ANCESTOR;
-      send_crossing_event (display, toplevel,
-                          a, GDK_LEAVE_NOTIFY,
-                          mode,
-                          notify_type,
-                          NULL, device, source_device,
-                          toplevel_x, toplevel_y,
-                          mask, time_,
-                          event_in_queue,
-                          serial);
-
-      if (c != a)
-       {
-         if (non_linear)
-           notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
-         else
-           notify_type = GDK_NOTIFY_VIRTUAL;
-
-         last = a;
-         win = a->parent;
-         while (win != c && win->window_type != GDK_WINDOW_ROOT)
-           {
-             send_crossing_event (display, toplevel,
-                                  win, GDK_LEAVE_NOTIFY,
-                                  mode,
-                                  notify_type,
-                                  (GdkWindow *)last,
-                                  device, source_device,
-                                  toplevel_x, toplevel_y,
-                                  mask, time_,
-                                  event_in_queue,
-                                  serial);
-
-             last = win;
-             win = win->parent;
-           }
-       }
-    }
-
-  if (b) /* Might not be a dest, e.g. if we're moving out of the window */
-    {
-      toplevel = gdk_window_get_toplevel ((GdkWindow *)b);
-
-      /* Traverse down from c to b */
-      if (c != b)
-       {
-         path = NULL;
-         win = b->parent;
-         while (win != c && win->window_type != GDK_WINDOW_ROOT)
-           {
-             path = g_list_prepend (path, win);
-             win = win->parent;
-           }
-
-         if (non_linear)
-           notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
-         else
-           notify_type = GDK_NOTIFY_VIRTUAL;
-
-         list = path;
-         while (list)
-           {
-             win = list->data;
-             list = list->next;
-             if (list)
-               next = list->data;
-             else
-               next = b;
-
-             send_crossing_event (display, toplevel,
-                                  win, GDK_ENTER_NOTIFY,
-                                  mode,
-                                  notify_type,
-                                  (GdkWindow *)next,
-                                  device, source_device,
-                                  toplevel_x, toplevel_y,
-                                  mask, time_,
-                                  event_in_queue,
-                                  serial);
-           }
-         g_list_free (path);
-       }
-
-
-      if (non_linear)
-       notify_type = GDK_NOTIFY_NONLINEAR;
-      else if (c == a)
-       notify_type = GDK_NOTIFY_ANCESTOR;
-      else
-       notify_type = GDK_NOTIFY_INFERIOR;
-
-      send_crossing_event (display, toplevel,
-                          b, GDK_ENTER_NOTIFY,
-                          mode,
-                          notify_type,
-                          NULL,
-                           device, source_device,
-                          toplevel_x, toplevel_y,
-                          mask, time_,
-                          event_in_queue,
-                          serial);
-    }
-}
-
 void
 _gdk_display_set_window_under_pointer (GdkDisplay *display,
                                        GdkDevice  *device,


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