[gtk+/client-side-windows: 225/284] Use the common pointer grab code instead of tracking it ourselves



commit 152614966f90a47dc268b2f3e8935a909eb08061
Author: Richard Hult <richard imendio com>
Date:   Mon Feb 2 14:11:46 2009 +0100

    Use the common pointer grab code instead of tracking it ourselves
---
 gdk/quartz/gdkevents-quartz.c |  220 +++++++----------------------------------
 gdk/quartz/gdkwindow-quartz.c |    6 +-
 2 files changed, 40 insertions(+), 186 deletions(-)

diff --git a/gdk/quartz/gdkevents-quartz.c b/gdk/quartz/gdkevents-quartz.c
index 3a8d324..03e2256 100644
--- a/gdk/quartz/gdkevents-quartz.c
+++ b/gdk/quartz/gdkevents-quartz.c
@@ -39,11 +39,6 @@ static GdkWindow   *current_mouse_window;
 /* This is the window corresponding to the key window */
 static GdkWindow   *current_keyboard_window;
 
-/* This is the pointer grab window */
-GdkWindow          *_gdk_quartz_pointer_grab_window;
-static gboolean     pointer_grab_owner_events;
-static GdkEventMask pointer_grab_event_mask;
-
 /* This is the keyboard grab window */
 GdkWindow *         _gdk_quartz_keyboard_grab_window;
 static gboolean     keyboard_grab_owner_events;
@@ -185,42 +180,11 @@ gdk_display_keyboard_ungrab (GdkDisplay *display,
   _gdk_quartz_keyboard_grab_window = NULL;
 }
 
-static void
-pointer_ungrab_internal (void)
-{
-  if (!_gdk_quartz_pointer_grab_window)
-    return;
-
-  g_object_unref (_gdk_quartz_pointer_grab_window);
-  _gdk_quartz_pointer_grab_window = NULL;
-
-  pointer_grab_owner_events = FALSE;
-  pointer_grab_event_mask = 0;
-
-  /* FIXME: Send crossing events */
-}
-
 void
 gdk_display_pointer_ungrab (GdkDisplay *display,
 			    guint32     time)
 {
-  pointer_ungrab_internal ();
-}
-
-static GdkGrabStatus
-pointer_grab_internal (GdkWindow    *window,
-		       gboolean	     owner_events,
-		       GdkEventMask  event_mask,
-		       GdkWindow    *confine_to,
-		       GdkCursor    *cursor)
-{
-  /* FIXME: Send crossing events */
-  
-  _gdk_quartz_pointer_grab_window = g_object_ref (window);
-  pointer_grab_owner_events = owner_events;
-  pointer_grab_event_mask = event_mask;
-
-  return GDK_GRAB_SUCCESS;
+  _gdk_display_unset_has_pointer_grab (display, FALSE, FALSE, time);
 }
 
 GdkGrabStatus
@@ -238,31 +202,22 @@ gdk_pointer_grab (GdkWindow    *window,
 
   toplevel = gdk_window_get_toplevel (window);
 
-  /* TODO: What do we do for offscreens and their children? We need to proxy the grab somehow */
-  if (!GDK_IS_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl))
-    return GDK_GRAB_SUCCESS;
-
-  if (_gdk_quartz_pointer_grab_window)
-    {
-      if (_gdk_quartz_pointer_grab_window != window)
-        generate_grab_broken_event (_gdk_quartz_pointer_grab_window,
-                                    FALSE,
-                                    window);
-
-      pointer_ungrab_internal ();
-    }
+  _gdk_display_set_has_pointer_grab (_gdk_display,
+                                     window,
+                                     toplevel,
+                                     owner_events,
+                                     event_mask,
+                                     0,
+                                     time,
+                                     FALSE);
 
-  return pointer_grab_internal (window, owner_events, event_mask, 
-				confine_to, cursor);
+  return GDK_GRAB_SUCCESS;
 }
 
-/* This is used to break any grabs in the case where we have to due to
- * the grab emulation. Instead of enforcing the desktop wide grab, we
- * break it when the app loses focus for example.
- */
 static void
-break_all_grabs (void)
+break_all_grabs (guint32 time)
 {
+  /*
   if (_gdk_quartz_keyboard_grab_window)
     {
       generate_grab_broken_event (_gdk_quartz_keyboard_grab_window,
@@ -271,13 +226,14 @@ break_all_grabs (void)
       g_object_unref (_gdk_quartz_keyboard_grab_window);
       _gdk_quartz_keyboard_grab_window = NULL;
     }
-
-  if (_gdk_quartz_pointer_grab_window)
+  */
+  if (_gdk_display->pointer_grab.window)
     {
-      generate_grab_broken_event (_gdk_quartz_pointer_grab_window,
-                                  FALSE,
-                                  NULL);
-      pointer_ungrab_internal ();
+      g_print ("break all grabs\n");
+      _gdk_display_unset_has_pointer_grab (_gdk_display,
+                                           _gdk_display->pointer_grab.implicit,
+                                           FALSE,
+                                           time);
     }
 }
 
@@ -323,37 +279,6 @@ gdk_event_apply_filters (NSEvent *nsevent,
   return GDK_FILTER_CONTINUE;
 }
 
-/* Checks if the passed in window is interested in the event mask, and
- * if so, it's returned. If not, the event can be propagated through
- * its ancestors until one with the right event mask is found, up to
- * the nearest toplevel.
- */
-static GdkWindow *
-find_window_interested_in_event_mask (GdkWindow    *window, 
-				      GdkEventMask  event_mask,
-				      gboolean      propagate)
-{
-  GdkWindowObject *private;
-
-  private = GDK_WINDOW_OBJECT (window);
-  while (private)
-    {
-      if (private->event_mask & event_mask)
-	return (GdkWindow *)private;
-
-      if (!propagate)
-	return NULL;
-
-      /* Don't traverse beyond toplevels. */
-      if (GDK_WINDOW_TYPE (private) != GDK_WINDOW_CHILD)
-	break;
-
-      private = private->parent;
-    }
-
-  return NULL;
-}
-
 static guint32
 get_time_from_ns_event (NSEvent *event)
 {
@@ -569,8 +494,8 @@ _gdk_quartz_events_get_mouse_window (gboolean consider_grabs)
   if (!consider_grabs)
     return current_mouse_window;
 
-  if (_gdk_quartz_pointer_grab_window && !pointer_grab_owner_events)
-    return _gdk_quartz_pointer_grab_window;
+  if (_gdk_display->pointer_grab.window && !_gdk_display->pointer_grab.owner_events)
+    return _gdk_display->pointer_grab.window;
   
   return current_mouse_window;
 }
@@ -724,65 +649,6 @@ get_converted_window_coordinates (GdkWindow *in_window,
                                        out_x, out_y);
 }
 
-/* Given a mouse NSEvent (must be a mouse event for a GDK window),
- * finds the subwindow over which the pointer is located. Returns
- * coordinates relative to the found window. If no window is found,
- * returns the root window, and root window coordinates.
- */
-static GdkWindow *
-find_mouse_window_for_ns_event (NSEvent *nsevent,
-                                gint    *x_ret,
-                                gint    *y_ret)
-{
-  GdkWindow *event_toplevel;
-  GdkWindowImplQuartz *impl;
-  GdkWindowObject *private;
-  GdkWindow *mouse_toplevel;
-  GdkWindow *mouse_window;
-  NSPoint point;
-  gint x_tmp, y_tmp;
-
-  event_toplevel = [(GdkQuartzView *)[[nsevent window] contentView] gdkWindow];
-  impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (event_toplevel)->impl);
-  private = GDK_WINDOW_OBJECT (event_toplevel);
-  point = [nsevent locationInWindow];
-
-  x_tmp = point.x;
-  y_tmp = private->height - point.y;
-
-  mouse_toplevel = gdk_window_get_toplevel (current_mouse_window);
-
-  get_converted_window_coordinates (event_toplevel,
-                                    x_tmp, y_tmp,
-                                    mouse_toplevel,
-                                    &x_tmp, &y_tmp);
-
-  mouse_window = _gdk_quartz_window_find_child (mouse_toplevel, x_tmp, y_tmp);
-  if (mouse_window && mouse_window != mouse_toplevel)
-    {
-      get_child_coordinates_from_ancestor (mouse_toplevel,
-                                           x_tmp, y_tmp,
-                                           mouse_window,
-                                           &x_tmp, &y_tmp);
-    }
-  else if (!mouse_window)
-    {
-      /* This happens for events on the window title buttons and the
-       * desktop, treat those as being on the root window.
-       */
-      get_converted_window_coordinates (mouse_toplevel,
-                                        x_tmp, y_tmp,
-                                        _gdk_root,
-                                        &x_tmp, &y_tmp);
-      mouse_window = _gdk_root;
-    }
-
-  *x_ret = x_tmp;
-  *y_ret = y_tmp;
-
-  return mouse_window;
-}
-
 /* Trigger crossing events if necessary. This is used when showing a new
  * window, since the tracking rect API doesn't work reliably when a window
  * shows up under the mouse cursor. It's done by finding the topmost window
@@ -921,9 +787,9 @@ find_window_for_ns_event (NSEvent *nsevent,
     case NSRightMouseDragged:
     case NSOtherMouseDragged:
       {
-	GdkWindow *mouse_window;
-	GdkEventMask event_mask;
-	GdkWindow *real_window;
+	GdkDisplay *display;
+
+        display = gdk_drawable_get_display (toplevel);
 
 	/* From the docs for XGrabPointer:
 	 *
@@ -937,49 +803,36 @@ find_window_for_ns_event (NSEvent *nsevent,
 	 * This means we first try the owner, then the grab window,
 	 * then give up.
 	 */
-	if (0 && _gdk_quartz_pointer_grab_window) /* FIXME: Implement grabs? */
+	if (display->pointer_grab.window)
 	  {
-	    if (pointer_grab_owner_events)
-	      {
-                mouse_window = find_mouse_window_for_ns_event (nsevent, x, y);
-		event_mask = get_event_mask_from_ns_event (nsevent);
-		real_window = find_window_interested_in_event_mask (mouse_window, event_mask, TRUE);
-		
-		if (mouse_window && real_window && mouse_window != real_window)
-		  get_ancestor_coordinates_from_child (mouse_window,
-						       *x, *y,
-						       real_window,
-						       x, y);
-
-		if (real_window)
-		  return real_window;
-	      }
+	    if (display->pointer_grab.owner_events)
+              return toplevel;
 
 	    /* Finally check the grab window. */
-	    if (pointer_grab_event_mask & get_event_mask_from_ns_event (nsevent))
+	    if (display->pointer_grab.event_mask & get_event_mask_from_ns_event (nsevent))
 	      {
-                GdkWindow *event_toplevel;
 		GdkWindow *grab_toplevel;
 		NSPoint point;
 		int x_tmp, y_tmp;
 
-                event_toplevel = [(GdkQuartzView *)[[nsevent window] contentView] gdkWindow];
-		grab_toplevel = gdk_window_get_toplevel (_gdk_quartz_pointer_grab_window);
+		grab_toplevel = gdk_window_get_toplevel (display->pointer_grab.window);
 		point = [nsevent locationInWindow];
 
 		x_tmp = point.x;
 		y_tmp = GDK_WINDOW_OBJECT (grab_toplevel)->height - point.y;
 
+                /* FIXME: Would be better and easier to use cocoa to convert. */
+
                 /* Translate the coordinates so they are relative to
                  * the grab window instead of the event toplevel for
                  * the cases where they are not the same.
                  */
-                get_converted_window_coordinates (event_toplevel,
+                get_converted_window_coordinates (toplevel,
                                                   x_tmp, y_tmp,
-                                                  _gdk_quartz_pointer_grab_window,
+                                                  grab_toplevel,
                                                   x, y);
 
-		return _gdk_quartz_pointer_grab_window;
+		return grab_toplevel;
 	      }
 
 	    return NULL;
@@ -1009,6 +862,7 @@ find_window_for_ns_event (NSEvent *nsevent,
     case NSKeyUp:
     case NSFlagsChanged:
       {
+        /* FIXME: Use common code here instead. */
 	if (_gdk_quartz_keyboard_grab_window && !keyboard_grab_owner_events)
 	  return _gdk_quartz_keyboard_grab_window;
 
@@ -1428,7 +1282,7 @@ gdk_event_translate (GdkEvent *event,
   if (event_type == NSAppKitDefined)
     {
       if ([nsevent subtype] == NSApplicationDeactivatedEventType)
-        break_all_grabs ();
+        break_all_grabs (get_time_from_ns_event (nsevent));
 
       /* This could potentially be used to break grabs when clicking
        * on the title. The subtype 20 is undocumented so it's probably
@@ -1492,7 +1346,7 @@ gdk_event_translate (GdkEvent *event,
    */
   if ([(GdkQuartzWindow *)nswindow isInMove])
     {
-      break_all_grabs ();
+      break_all_grabs (get_time_from_ns_event (nsevent));
       return FALSE;
     }
 
diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c
index c91d06a..66a488d 100644
--- a/gdk/quartz/gdkwindow-quartz.c
+++ b/gdk/quartz/gdkwindow-quartz.c
@@ -953,7 +953,7 @@ _gdk_quartz_window_destroy (GdkWindow *window,
   /* If the destroyed window was targeted for a pointer or keyboard
    * grab, release the grab.
    */
-  if (window == _gdk_quartz_pointer_grab_window)
+  if (window == _gdk_display->pointer_grab.window)
     gdk_pointer_ungrab (0);
 
   if (window == _gdk_quartz_keyboard_grab_window)
@@ -1122,7 +1122,7 @@ gdk_window_quartz_hide (GdkWindow *window)
       [impl->view setHidden:YES];
     }
 
-  if (window == _gdk_quartz_pointer_grab_window)
+  if (window == _gdk_display->pointer_grab.window)
     gdk_pointer_ungrab (0);
 
   if (window == _gdk_quartz_keyboard_grab_window)
@@ -1788,7 +1788,7 @@ _gdk_windowing_window_get_pointer (GdkDisplay      *display,
       x_tmp = point.x;
       y_tmp = private->height - point.y;
 
-      window = toplevel;
+      window = (GdkWindow *)toplevel;
     }
 
   found_window = _gdk_quartz_window_find_child (window, x_tmp, y_tmp);



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