diff --git a/src/video/cocoa/SDL_cocoamouse.m b/src/video/cocoa/SDL_cocoamouse.m index 9c37c4728..3c0c47866 100644 --- a/src/video/cocoa/SDL_cocoamouse.m +++ b/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); }