]> Pileus Git - ~andy/gtk/blobdiff - gdk/quartz/gdkevents-quartz.c
Merge branch 'master' into client-side-windows
[~andy/gtk] / gdk / quartz / gdkevents-quartz.c
index ad30e4b74e237147054d1b768f1a84b791260be0..db73a11c321f4bb954c99e5f252b497f5bbf4743 100644 (file)
@@ -418,6 +418,33 @@ _gdk_quartz_events_send_map_event (GdkWindow *window)
     }
 }
 
+static GdkWindow *
+find_toplevel_under_pointer (GdkDisplay *display,
+                             NSPoint     screen_point,
+                             gint       *x,
+                             gint       *y)
+{
+  GdkWindow *toplevel;
+
+  toplevel = display->pointer_info.toplevel_under_pointer;
+  if (toplevel)
+    {
+      GdkWindowObject *private;
+      NSWindow *nswindow;
+      NSPoint point;
+
+      private = (GdkWindowObject *)toplevel;
+      nswindow = ((GdkWindowImplQuartz *)private->impl)->toplevel;
+
+      point = [nswindow convertScreenToBase:screen_point];
+
+      *x = point.x;
+      *y = private->height - point.y;
+    }
+
+  return toplevel;
+}
+
 /* This function finds the correct window to send an event to, taking
  * into account grabs, event propagation, and event masks.
  */
@@ -492,20 +519,17 @@ find_window_for_ns_event (NSEvent *nsevent,
                  * reported with respect to the key window, which could be
                  * wrong.
                  */
-                if (display->pointer_info.toplevel_under_pointer)
-                  {
-                    GdkWindowObject *pointer_private;
-                    NSWindow *pointer_nswindow;
-
-                    toplevel = display->pointer_info.toplevel_under_pointer;
-                    pointer_private = (GdkWindowObject *)toplevel;
-                    pointer_nswindow = ((GdkWindowImplQuartz *)pointer_private->impl)->toplevel;
-
-                    point = [pointer_nswindow convertScreenToBase:screen_point];
+                GdkWindow *toplevel_under_pointer;
+                gint x_tmp, y_tmp;
 
-                    /* Note: x_root and y_root are already right. */
-                    *x = point.x;
-                    *y = pointer_private->height - point.y;
+                toplevel_under_pointer = find_toplevel_under_pointer (display,
+                                                                      screen_point,
+                                                                      &x_tmp, &y_tmp);
+                if (toplevel_under_pointer)
+                  {
+                    toplevel = toplevel_under_pointer;
+                    *x = x_tmp;
+                    *y = y_tmp;
                   }
 
                 return toplevel;
@@ -535,6 +559,8 @@ find_window_for_ns_event (NSEvent *nsevent,
        else 
          {
            /* The non-grabbed case. */
+            GdkWindow *toplevel_under_pointer;
+            gint x_tmp, y_tmp;
 
             /* Ignore all events but mouse moved that might be on the title
              * bar (above the content view). The reason is that otherwise
@@ -547,6 +573,19 @@ find_window_for_ns_event (NSEvent *nsevent,
 
             /* FIXME: Also need to leave resize events to cocoa somehow? */
 
+            /* As for owner events, we need to use the toplevel under the
+             * pointer, not the window from the NSEvent.
+             */
+            toplevel_under_pointer = find_toplevel_under_pointer (display,
+                                                                  screen_point,
+                                                                  &x_tmp, &y_tmp);
+            if (toplevel_under_pointer)
+              {
+                toplevel = toplevel_under_pointer;
+                *x = x_tmp;
+                *y = y_tmp;
+              }
+
             return toplevel;
          }
       }
@@ -1001,9 +1040,10 @@ gdk_event_translate (GdkEvent *event,
        }
     }
 
-  /* If the app is not active, or the window (when not grabbed) is not
-   * active, leave the event to AppKit so the window gets focused correctly
-   * and don't do click-through (so we behave like most native apps).
+  /* If the app is not active leave the event to AppKit so the window gets
+   * focused correctly and don't do click-through (so we behave like most
+   * native apps). If the app is active, we focus the window and then handle
+   * the event, also to match native apps.
    */
   if ((event_type == NSRightMouseDown ||
        event_type == NSOtherMouseDown ||
@@ -1018,7 +1058,13 @@ gdk_event_translate (GdkEvent *event,
           return FALSE;
         }
       else if (![impl->toplevel isKeyWindow])
-        return FALSE;
+        {
+          GdkPointerGrabInfo *grab;
+
+          grab = _gdk_display_get_last_pointer_grab (_gdk_display);
+          if (!grab)
+            [impl->toplevel makeKeyWindow];
+        }
     }
 
   current_event_mask = get_event_mask_from_ns_event (nsevent);