[gtk+/xi2: 1049/1239] Make keyboard and pointer grabs use the same infrastructure.



commit d24c20d639d71dacff83cd68af2708bfa25b0e07
Author: Carlos Garnacho <carlos gnome org>
Date:   Sat Sep 5 15:15:26 2009 +0200

    Make keyboard and pointer grabs use the same infrastructure.
    
    Now keyboard grabs also use the GdkDeviceGrabInfo machinery. Actual
    keyboard grabbing is now handled by the GdkDevice code.

 gdk/gdk.symbols                 |    9 +++-
 gdk/gdkdisplay.c                |  101 ++++++++++++++++++++++----------------
 gdk/gdkdisplay.h                |    1 -
 gdk/gdkinternals.h              |    8 ---
 gdk/gdkwindow.c                 |   97 +++++++++++++++++++++++++++++++-----
 gdk/x11/gdkdevicemanager-core.c |   32 +++++++-----
 gdk/x11/gdkdevicemanager-xi2.c  |   31 +++++++-----
 gdk/x11/gdkdisplay-x11.c        |   30 -----------
 gdk/x11/gdkevents-x11.c         |    2 +
 gdk/x11/gdkmain-x11.c           |  104 +++++---------------------------------
 10 files changed, 202 insertions(+), 213 deletions(-)
---
diff --git a/gdk/gdk.symbols b/gdk/gdk.symbols
index bcfe0c3..40c03d8 100644
--- a/gdk/gdk.symbols
+++ b/gdk/gdk.symbols
@@ -68,7 +68,6 @@ gdk_get_display
 gdk_get_use_xshm
 gdk_set_use_xshm
 #endif
-gdk_keyboard_grab
 #endif
 #endif
 
@@ -174,6 +173,12 @@ gdk_screen_height_mm G_GNUC_CONST
 #endif
 #endif
 
+#if IN_HEADER(__GDK_H__)
+#if IN_FILE(__GDK_WINDOW_C__)
+gdk_keyboard_grab
+#endif
+#endif
+
 #if IN_HEADER(__GDK_PROPERTY_H__)
 #if IN_FILE(__GDK_SELECTION_C__)
 gdk_string_to_compound_text
@@ -416,6 +421,7 @@ gdk_display_get_event
 gdk_display_get_pointer
 gdk_display_get_type G_GNUC_CONST
 gdk_display_get_window_at_pointer
+gdk_display_keyboard_ungrab
 gdk_display_peek_event
 gdk_display_pointer_ungrab
 gdk_display_put_event
@@ -455,7 +461,6 @@ gdk_display_get_name
 gdk_display_get_n_screens
 gdk_display_get_screen
 gdk_display_device_ungrab
-gdk_display_keyboard_ungrab
 gdk_display_open
 gdk_display_request_selection_notification
 gdk_display_store_clipboard
diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c
index 09a2004..ede927e 100644
--- a/gdk/gdkdisplay.c
+++ b/gdk/gdkdisplay.c
@@ -427,6 +427,43 @@ gdk_pointer_is_grabbed (void)
 }
 
 /**
+ * gdk_display_keyboard_ungrab:
+ * @display: a #GdkDisplay.
+ * @time_: a timestap (e.g #GDK_CURRENT_TIME).
+ *
+ * Release any keyboard grab
+ *
+ * Since: 2.2
+ */
+void
+gdk_display_keyboard_ungrab (GdkDisplay *display,
+			     guint32     time)
+{
+  GdkDeviceManager *device_manager;
+  GList *devices, *dev;
+  GdkDevice *device;
+
+  g_return_if_fail (GDK_IS_DISPLAY (display));
+
+  device_manager = gdk_device_manager_get_for_display (display);
+  devices = gdk_device_manager_get_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
+
+  /* FIXME: Should this be generic to all backends? */
+  /* FIXME: What happens with extended devices? */
+  for (dev = devices; dev; dev = dev->next)
+    {
+      device = dev->data;
+
+      if (device->source != GDK_SOURCE_KEYBOARD)
+        continue;
+
+      gdk_display_device_ungrab (display, device, time);
+    }
+
+  g_list_free (devices);
+}
+
+/**
  * gdk_keyboard_ungrab:
  * @time_: a timestamp from a #GdkEvent, or %GDK_CURRENT_TIME if no
  *        timestamp is available.
@@ -971,7 +1008,6 @@ gdk_set_pointer_hooks (const GdkPointerHooks *new_hooks)
 static void
 generate_grab_broken_event (GdkWindow *window,
                             GdkDevice *device,
-			    gboolean   keyboard,
 			    gboolean   implicit,
 			    GdkWindow *grab_window)
 {
@@ -983,7 +1019,7 @@ generate_grab_broken_event (GdkWindow *window,
       event.type = GDK_GRAB_BROKEN;
       event.grab_broken.window = window;
       event.grab_broken.send_event = 0;
-      event.grab_broken.keyboard = keyboard;
+      event.grab_broken.keyboard = (device->source == GDK_SOURCE_KEYBOARD) ? TRUE : FALSE;
       event.grab_broken.implicit = implicit;
       event.grab_broken.grab_window = grab_window;
       event.grab_broken.device = device;
@@ -1299,7 +1335,7 @@ switch_to_pointer_grab (GdkDisplay        *display,
 	  if (last_grab->implicit_ungrab)
 	    generate_grab_broken_event (last_grab->window,
                                         device,
-					FALSE, TRUE,
+					TRUE,
 					NULL);
 	}
     }
@@ -1334,7 +1370,10 @@ _gdk_display_device_grab_update (GdkDisplay *display,
 	     its the currently active one or scheduled to be active */
 
 	  if (!current_grab->activated)
-	    switch_to_pointer_grab (display, device, current_grab, NULL, time, current_serial);
+            {
+              if (device->source != GDK_SOURCE_KEYBOARD)
+                switch_to_pointer_grab (display, device, current_grab, NULL, time, current_serial);
+            }
 
 	  break;
 	}
@@ -1353,16 +1392,17 @@ _gdk_display_device_grab_update (GdkDisplay *display,
 	  current_grab->window != next_grab->window)
 	generate_grab_broken_event (GDK_WINDOW (current_grab->window),
                                     device,
-				    FALSE, current_grab->implicit,
+				    current_grab->implicit,
 				    next_grab? next_grab->window : NULL);
 
       /* Remove old grab */
       grabs = g_list_delete_link (grabs, grabs);
       g_hash_table_insert (display->device_grabs, device, grabs);
 
-      switch_to_pointer_grab (display, device,
-			      next_grab, current_grab,
-			      time, current_serial);
+      if (device->source != GDK_SOURCE_KEYBOARD)
+        switch_to_pointer_grab (display, device,
+                                next_grab, current_grab,
+                                time, current_serial);
 
       free_device_grab (current_grab);
     }
@@ -1489,38 +1529,6 @@ _gdk_display_check_grab_ownership (GdkDisplay *display,
   return TRUE;
 }
 
-void
-_gdk_display_set_has_keyboard_grab (GdkDisplay *display,
-				    GdkWindow *window,
-				    GdkWindow *native_window,
-				    gboolean owner_events,
-				    unsigned long serial,
-				    guint32 time)
-{
-  if (display->keyboard_grab.window != NULL &&
-      display->keyboard_grab.window != window)
-    generate_grab_broken_event (display->keyboard_grab.window,
-                                display->core_pointer, /* FIXME: which event? core pointer not, clearly */
-				TRUE, FALSE, window);
-
-  display->keyboard_grab.window = window;
-  display->keyboard_grab.native_window = native_window;
-  display->keyboard_grab.owner_events = owner_events;
-  display->keyboard_grab.serial = serial;
-  display->keyboard_grab.time = time;
-}
-
-void
-_gdk_display_unset_has_keyboard_grab (GdkDisplay *display,
-				      gboolean implicit)
-{
-  if (implicit)
-    generate_grab_broken_event (display->keyboard_grab.window,
-                                display->core_pointer, /* FIXME: which device? core pointer not, clearly */
-				TRUE, FALSE, NULL);
-  display->keyboard_grab.window = NULL;  
-}
-
 GdkPointerWindowInfo *
 _gdk_display_get_pointer_info (GdkDisplay *display,
                                GdkDevice  *device)
@@ -1578,14 +1586,21 @@ gdk_keyboard_grab_info_libgtk_only (GdkDisplay *display,
 				    GdkWindow **grab_window,
 				    gboolean   *owner_events)
 {
+  GdkDeviceGrabInfo *info;
+
+  /* FIXME: merge this and the pointer function */
   g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
 
-  if (display->keyboard_grab.window)
+  /* FIXME: which device? */
+  info = _gdk_display_get_last_device_grab (display,
+                                            gdk_device_get_relative (display->core_pointer));
+
+  if (info)
     {
       if (grab_window)
-        *grab_window = display->keyboard_grab.window;
+        *grab_window = info->window;
       if (owner_events)
-        *owner_events = display->keyboard_grab.owner_events;
+        *owner_events = info->owner_events;
 
       return TRUE;
     }
diff --git a/gdk/gdkdisplay.h b/gdk/gdkdisplay.h
index c75f15f..d629d20 100644
--- a/gdk/gdkdisplay.h
+++ b/gdk/gdkdisplay.h
@@ -103,7 +103,6 @@ struct _GdkDisplay
   guint double_click_distance;	/* Maximum distance between clicks in pixels */
 
   GHashTable *device_grabs;
-  GdkKeyboardGrabInfo keyboard_grab;
 
   gulong motion_hint_serial; /* 0 == didn't deliver hinted motion event */
 
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index 18601c8..2fb237d 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -618,14 +618,6 @@ gboolean _gdk_display_end_device_grab  (GdkDisplay *display,
 gboolean _gdk_display_check_grab_ownership (GdkDisplay *display,
                                             GdkDevice  *device,
                                             gulong      serial);
-void _gdk_display_set_has_keyboard_grab (GdkDisplay *display,
-					 GdkWindow *window,
-					 GdkWindow *native_window,
-					 gboolean owner_events,
-					 unsigned long serial,
-					 guint32 time);
-void _gdk_display_unset_has_keyboard_grab (GdkDisplay *display,
-					   gboolean implicit);
 void _gdk_display_enable_motion_hints     (GdkDisplay *display);
 
 GdkPointerWindowInfo * _gdk_display_get_pointer_info (GdkDisplay *display,
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 5f13646..6ff17be 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -6445,18 +6445,12 @@ gdk_window_hide (GdkWindow *window)
                                         TRUE))
 	gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME);
 
-      if (display->keyboard_grab.window != NULL)
-	{
-	  if (is_parent_of (window, display->keyboard_grab.window))
-	    {
-	      /* Call this ourselves, even though gdk_display_keyboard_ungrab
-		 does so too, since we want to pass implicit == TRUE so the
-		 broken grab event is generated */
-	      _gdk_display_unset_has_keyboard_grab (display,
-						    TRUE);
-	      gdk_display_keyboard_ungrab (display, GDK_CURRENT_TIME);
-	    }
-	}
+      if (_gdk_display_end_device_grab (display,
+                                        gdk_device_get_relative (display->core_pointer),
+                                        _gdk_windowing_window_get_next_serial (display),
+                                        window,
+                                        TRUE))
+        gdk_display_keyboard_ungrab (display, GDK_CURRENT_TIME);
 
       private->state = GDK_WINDOW_STATE_WITHDRAWN;
     }
@@ -9353,6 +9347,85 @@ gdk_pointer_grab (GdkWindow *	  window,
   return res;
 }
 
+GdkGrabStatus
+gdk_keyboard_grab (GdkWindow *window,
+		   gboolean   owner_events,
+		   guint32    time)
+{
+  GdkWindow *native;
+  GdkDisplay *display;
+  GdkDeviceManager *device_manager;
+  GdkDevice *device;
+  GdkGrabStatus res = 0;
+  gulong serial;
+  GList *devices, *dev;
+
+  g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
+
+  /* Non-viewable client side window => fail */
+  if (!_gdk_window_has_impl (window) &&
+      !gdk_window_is_viewable (window))
+    return GDK_GRAB_NOT_VIEWABLE;
+
+  if (_gdk_native_windows)
+    native = window;
+  else
+    native = gdk_window_get_toplevel (window);
+
+  while (gdk_window_is_offscreen ((GdkWindowObject *)native))
+    {
+      native = gdk_offscreen_window_get_embedder (native);
+
+      if (native == NULL ||
+	  (!_gdk_window_has_impl (native) &&
+	   !gdk_window_is_viewable (native)))
+	return GDK_GRAB_NOT_VIEWABLE;
+
+      native = gdk_window_get_toplevel (native);
+    }
+
+  display = gdk_drawable_get_display (window);
+
+  serial = _gdk_windowing_window_get_next_serial (display);
+  device_manager = gdk_device_manager_get_for_display (display);
+  devices = gdk_device_manager_get_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
+
+  /* FIXME: Should this be generic to all backends? */
+  /* FIXME: What happens with extended devices? */
+  for (dev = devices; dev; dev = dev->next)
+    {
+      device = dev->data;
+
+      if (device->source != GDK_SOURCE_KEYBOARD)
+        continue;
+
+      res = _gdk_windowing_device_grab (device,
+                                        window,
+                                        native,
+                                        owner_events, 0,
+                                        NULL,
+                                        NULL,
+                                        time);
+
+      if (res == GDK_GRAB_SUCCESS)
+        _gdk_display_add_device_grab (display,
+                                      device,
+                                      window,
+                                      native,
+                                      GDK_OWNERSHIP_NONE,
+                                      owner_events, 0,
+                                      serial,
+                                      time,
+                                      FALSE);
+    }
+
+  /* FIXME: handle errors when grabbing */
+
+  g_list_free (devices);
+
+  return res;
+}
+
 /**
  * gdk_window_geometry_changed:
  * @window: a #GdkWindow
diff --git a/gdk/x11/gdkdevicemanager-core.c b/gdk/x11/gdkdevicemanager-core.c
index 1177e05..dda714b 100644
--- a/gdk/x11/gdkdevicemanager-core.c
+++ b/gdk/x11/gdkdevicemanager-core.c
@@ -344,27 +344,31 @@ static GdkWindow *
 get_event_window (GdkEventTranslator *translator,
                   XEvent             *xevent)
 {
+  GdkDeviceManager *device_manager;
   GdkDisplay *display;
   GdkWindow *window;
 
-  display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (translator));
+  device_manager = GDK_DEVICE_MANAGER (translator);
+  display = gdk_device_manager_get_display (device_manager);
   window = gdk_window_lookup_for_display (display, xevent->xany.window);
 
   /* Apply keyboard grabs to non-native windows */
-  if (/* Is key event */
-      (xevent->type == KeyPress || xevent->type == KeyRelease) &&
-      /* And we have a grab */
-      display->keyboard_grab.window != NULL &&
-      (
-       /* The window is not a descendant of the grabbed window */
-       !is_parent_of ((GdkWindow *)display->keyboard_grab.window, window) ||
-       /* Or owner event is false */
-       !display->keyboard_grab.owner_events
-       )
-      )
+  if (xevent->type == KeyPress || xevent->type == KeyRelease)
     {
-      /* Report key event against grab window */
-      return display->keyboard_grab.window;
+      GdkDeviceGrabInfo *info;
+      gulong serial;
+
+      serial = _gdk_windowing_window_get_next_serial (display);
+      info = _gdk_display_has_device_grab (display,
+                                           GDK_DEVICE_MANAGER_CORE (device_manager)->core_keyboard,
+                                           serial);
+      if (info &&
+          (!is_parent_of (info->window, window) ||
+           !info->owner_events))
+        {
+          /* Report key event against grab window */
+          window = info->window;
+        }
     }
 
   return window;
diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c
index 4cb0bac..a8f8829 100644
--- a/gdk/x11/gdkdevicemanager-xi2.c
+++ b/gdk/x11/gdkdevicemanager-xi2.c
@@ -710,20 +710,25 @@ get_event_window (GdkEventTranslator *translator,
         window = gdk_window_lookup_for_display (display, xev->event);
 
         /* Apply keyboard grabs to non-native windows */
-        if (/* Is key event */
-            (ev->evtype == XI_KeyPress || ev->evtype == XI_KeyRelease) &&
-            /* And we have a grab */
-            display->keyboard_grab.window != NULL &&
-            (
-             /* The window is not a descendant of the grabbed window */
-             !is_parent_of ((GdkWindow *)display->keyboard_grab.window, window) ||
-             /* Or owner event is false */
-             !display->keyboard_grab.owner_events
-             )
-            )
+        if (ev->evtype == XI_KeyPress || ev->evtype == XI_KeyRelease)
           {
-            /* Report key event against grab window */
-            window = display->keyboard_grab.window;
+            GdkDeviceGrabInfo *info;
+            GdkDevice *device;
+            gulong serial;
+
+            device = g_hash_table_lookup (GDK_DEVICE_MANAGER_XI2 (translator)->id_table,
+                                          GUINT_TO_POINTER (((XIDeviceEvent *) ev)->deviceid));
+
+            serial = _gdk_windowing_window_get_next_serial (display);
+            info = _gdk_display_has_device_grab (display, device, serial);
+
+            if (info &&
+                (!is_parent_of (info->window, window) ||
+                 !info->owner_events))
+              {
+                /* Report key event against grab window */
+                window = info->window;
+              }
           }
       }
       break;
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index 2af4ac5..aa0d0f8 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -1644,36 +1644,6 @@ gdk_display_device_ungrab (GdkDisplay *display,
 }
 
 /**
- * gdk_display_keyboard_ungrab:
- * @display: a #GdkDisplay.
- * @time_: a timestap (e.g #GDK_CURRENT_TIME).
- *
- * Release any keyboard grab
- *
- * Since: 2.2
- */
-void
-gdk_display_keyboard_ungrab (GdkDisplay *display,
-			     guint32     time)
-{
-  Display *xdisplay;
-  GdkDisplayX11 *display_x11;
-  
-  g_return_if_fail (GDK_IS_DISPLAY (display));
-
-  display_x11 = GDK_DISPLAY_X11 (display);
-  xdisplay = GDK_DISPLAY_XDISPLAY (display);
-  
-  XUngrabKeyboard (xdisplay, time);
-  XFlush (xdisplay);
-  
-  if (time == GDK_CURRENT_TIME || 
-      display->keyboard_grab.time == GDK_CURRENT_TIME ||
-      !XSERVER_TIME_IS_LATER (display->keyboard_grab.time, time))
-    _gdk_display_unset_has_keyboard_grab (display, FALSE);
-}
-
-/**
  * gdk_display_beep:
  * @display: a #GdkDisplay
  *
diff --git a/gdk/x11/gdkevents-x11.c b/gdk/x11/gdkevents-x11.c
index 15afac1..4b9602b 100644
--- a/gdk/x11/gdkevents-x11.c
+++ b/gdk/x11/gdkevents-x11.c
@@ -961,6 +961,7 @@ gdk_event_translate (GdkDisplay *display,
     
   if (window != NULL)
     {
+#if 0
       /* Apply keyboard grabs to non-native windows */
       if (/* Is key event */
 	  (xevent->type == KeyPress || xevent->type == KeyRelease) &&
@@ -978,6 +979,7 @@ gdk_event_translate (GdkDisplay *display,
           window = display->keyboard_grab.window;;
           window_private = (GdkWindowObject *) window;
         }
+#endif
 
       window_impl = GDK_WINDOW_IMPL_X11 (window_private->impl);
       
diff --git a/gdk/x11/gdkmain-x11.c b/gdk/x11/gdkmain-x11.c
index dc37100..6b1aa16 100644
--- a/gdk/x11/gdkmain-x11.c
+++ b/gdk/x11/gdkmain-x11.c
@@ -187,80 +187,6 @@ _gdk_windowing_device_grab (GdkDevice    *device,
   return status;
 }
 
-/*
- *--------------------------------------------------------------
- * gdk_keyboard_grab
- *
- *   Grabs the keyboard to a specific window
- *
- * Arguments:
- *   "window" is the window which will receive the grab
- *   "owner_events" specifies whether events will be reported as is,
- *     or relative to "window"
- *   "time" specifies the time
- *
- * Results:
- *
- * Side effects:
- *   requires a corresponding call to gdk_keyboard_ungrab
- *
- *--------------------------------------------------------------
- */
-
-GdkGrabStatus
-gdk_keyboard_grab (GdkWindow *	   window,
-		   gboolean	   owner_events,
-		   guint32	   time)
-{
-  gint return_val;
-  unsigned long serial;
-  GdkDisplay *display;
-  GdkDisplayX11 *display_x11;
-  GdkWindow *native;
-
-  g_return_val_if_fail (window != NULL, 0);
-  g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
-
-  native = gdk_window_get_toplevel (window);
-
-  /* TODO: What do we do for offscreens and  children? We need to proxy the grab somehow */
-  if (!GDK_IS_WINDOW_IMPL_X11 (GDK_WINDOW_OBJECT (native)->impl))
-    return GDK_GRAB_SUCCESS;
-
-  display = GDK_WINDOW_DISPLAY (native);
-  display_x11 = GDK_DISPLAY_X11 (display);
-
-  serial = NextRequest (GDK_WINDOW_XDISPLAY (native));
-
-  if (!GDK_WINDOW_DESTROYED (native))
-    {
-#ifdef G_ENABLE_DEBUG
-      if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
-	return_val = GrabSuccess;
-      else
-#endif
-	return_val = XGrabKeyboard (GDK_WINDOW_XDISPLAY (native),
-				    GDK_WINDOW_XID (native),
-				    owner_events,
-				    GrabModeAsync, GrabModeAsync,
-				    time);
-	if (G_UNLIKELY (!display_x11->trusted_client && 
-			return_val == AlreadyGrabbed))
-	  /* we can't grab the keyboard, but we can do a GTK-local grab */
-	  return_val = GrabSuccess;
-    }
-  else
-    return_val = AlreadyGrabbed;
-
-  if (return_val == GrabSuccess)
-    _gdk_display_set_has_keyboard_grab (display,
-					window,	native,
-					owner_events,
-					serial, time);
-
-  return gdk_x11_convert_grab_status (return_val);
-}
-
 /**
  * _gdk_xgrab_check_unmap:
  * @window: a #GdkWindow
@@ -280,18 +206,10 @@ _gdk_xgrab_check_unmap (GdkWindow *window,
   /* FIXME: which device? */
   _gdk_display_end_device_grab (display, display->core_pointer, serial, window, TRUE);
 
-  if (display->keyboard_grab.window &&
-      serial >= display->keyboard_grab.serial)
-    {
-      GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
-      GdkWindowObject *tmp = GDK_WINDOW_OBJECT (display->keyboard_grab.window);
-
-      while (tmp && tmp != private)
-	tmp = tmp->parent;
-
-      if (tmp)
-	_gdk_display_unset_has_keyboard_grab (display, TRUE);
-    }
+  /* FIXME: which keyb? */
+  _gdk_display_end_device_grab (display,
+                                gdk_device_get_relative (display->core_pointer),
+                                serial, window, TRUE);
 }
 
 /**
@@ -321,10 +239,16 @@ _gdk_xgrab_check_destroy (GdkWindow *window)
       grab->serial_end = grab->serial_start;
       grab->implicit_ungrab = TRUE;
     }
-  
-  if (window == display->keyboard_grab.native_window &&
-      display->keyboard_grab.window != NULL)
-    _gdk_display_unset_has_keyboard_grab (display, TRUE);
+
+  /* FIXME: which keyboard? */
+  grab = _gdk_display_get_last_device_grab (display,
+                                            gdk_device_get_relative (display->core_pointer));
+
+  if (grab && grab->native_window == window)
+    {
+      grab->serial_end = grab->serial_start;
+      grab->implicit_ungrab = TRUE;
+    }
 }
 
 void



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