소스 검색

Cocoa: deal with mouse focus when warping the cursor from outside a window.

Otherwise, you might not get appropriate mouse enter/leave events.

Better fix for Bugzilla #2984.
Ryan C. Gordon 10 년 전
부모
커밋
7619ad3430
1개의 변경된 파일26개의 추가작업 그리고 10개의 파일을 삭제
  1. 26 10
      src/video/cocoa/SDL_cocoamouse.m

+ 26 - 10
src/video/cocoa/SDL_cocoamouse.m

@@ -195,6 +195,21 @@ Cocoa_ShowCursor(SDL_Cursor * cursor)
     return 0;
 }}
 
+static SDL_Window *
+SDL_FindWindowAtPoint(const int x, const int y)
+{
+    const SDL_Point pt = { x, y };
+    SDL_Window *i;
+    for (i = SDL_GetVideoDevice()->windows; i; i = i->next) {
+        const SDL_Rect r = { i->x, i->y, i->w, i->h };
+        if (SDL_PointInRect(&pt, &r)) {
+            return i;
+        }
+    }
+
+    return NULL;
+}
+
 static void
 Cocoa_WarpMouseGlobal(int x, int y)
 {
@@ -207,7 +222,7 @@ Cocoa_WarpMouseGlobal(int x, int y)
             return;
         }
     }
-    CGPoint point = CGPointMake((float)x, (float)y);
+    const CGPoint point = CGPointMake((float)x, (float)y);
 
     Cocoa_HandleMouseWarp(point.x, point.y);
 
@@ -219,21 +234,22 @@ Cocoa_WarpMouseGlobal(int x, int y)
     CGWarpMouseCursorPosition(point);
     CGSetLocalEventsSuppressionInterval(0.25);
 
-    if (!mouse->relative_mode && mouse->focus) {
-        /* CGWarpMouseCursorPosition doesn't generate a window event, unlike our
-         * other implementations' APIs.
-         */
-        SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x - mouse->focus->x, y - mouse->focus->y);
+    /* CGWarpMouseCursorPosition doesn't generate a window event, unlike our
+     * other implementations' APIs. Send what's appropriate.
+     */
+    if (!mouse->relative_mode) {
+        SDL_Window *win = SDL_FindWindowAtPoint(x, y);
+        SDL_SetMouseFocus(win);
+        if (win) {
+            SDL_assert(win == mouse->focus);
+            SDL_SendMouseMotion(win, mouse->mouseID, 0, x - win->x, y - win->y);
+        }
     }
 }
 
 static void
 Cocoa_WarpMouse(SDL_Window * window, int x, int y)
 {
-    /* pretend we have the mouse focus, even if we don't, so
-        Cocoa_WarpMouseGlobal() will properly fake a mouse motion event. */
-    SDL_Mouse *mouse = SDL_GetMouse();
-    mouse->focus = window;
     Cocoa_WarpMouseGlobal(x + window->x, y + window->y);
 }