[gtk+/client-side-windows: 216/284] Return ignoring of native grab/ungrab events when we don't have a grab



commit 20c81eca6a53e6f4694f7d0805208527a3385d9c
Author: Alexander Larsson <alexl redhat com>
Date:   Tue Feb 3 20:15:19 2009 +0100

    Return ignoring of native grab/ungrab events when we don't have a grab
    
    It turns out we really have to ignore grab/ungrab events or we'll
    report double crossing events when we grab or ungrab.
    
    However, we also can't ignore crossing events from grabs from other clients
    as that leads to missed enter/leave events on e.g. alt-tab in metacity.
    
    Fortunately we now track grabs very precisely, so we know with certainty
    whether we have a grab at the time (serial) of the native crossing events,
    and only if we do we ignore them.
---
 gdk/gdkwindow.c |   27 +++++++++++++++++++++++++++
 1 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 9b18240..dfa1214 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -8647,6 +8647,32 @@ _gdk_windowing_got_event (GdkDisplay *display,
       return;
     }
 
+  if ((event->type == GDK_ENTER_NOTIFY ||
+       event->type == GDK_LEAVE_NOTIFY) &&
+      (event->crossing.mode == GDK_CROSSING_GRAB ||
+       event->crossing.mode == GDK_CROSSING_UNGRAB) &&
+      _gdk_display_has_pointer_grab (display, serial))
+    {
+      /* We synthesize all crossing events due to grabs outselves,
+       * so we ignore the native ones when we already have a grab.
+       * Otherwise we would send multiple events when this app grabs
+       * We want to handle grabs from other clients though. */
+
+      /* We ended up in this window after some (perhaps other clients)
+	 grab, so update the toplevel_under_window state */
+      if (is_toplevel &&
+	  event->type == GDK_ENTER_NOTIFY &&
+	  event->crossing.mode == GDK_CROSSING_UNGRAB)
+	{
+	  if (display->pointer_info.toplevel_under_pointer)
+	    g_object_unref (display->pointer_info.toplevel_under_pointer);
+	  display->pointer_info.toplevel_under_pointer = g_object_ref (event_window);
+	}
+      
+      unlink_event = TRUE;
+      goto out;
+    }
+  
   /* Track toplevel_under_pointer */
   if (is_toplevel)
     {
@@ -8707,6 +8733,7 @@ _gdk_windowing_got_event (GdkDisplay *display,
 	}
     }
 
+ out:
   if (unlink_event)
     {
       _gdk_event_queue_remove_link (display, event_link);



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