diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index 9c047579f8..3e9642a3c0 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -2115,6 +2115,36 @@ static void Cocoa_SendMouseButtonClicks(SDL_Mouse *mouse, NSEvent *theEvent, SDL @end +static void Cocoa_UpdateMouseFocus() +{ + const NSPoint mouseLocation = [NSEvent mouseLocation]; + + // Find the topmost window under the pointer and send a motion event if it is an SDL window. + [NSApp enumerateWindowsWithOptions:NSWindowListOrderedFrontToBack + usingBlock:^(NSWindow *nswin, BOOL *stop) { + NSRect r = [nswin contentRectForFrameRect:[nswin frame]]; + if (NSPointInRect(mouseLocation, r)) { + SDL_VideoDevice *vid = SDL_GetVideoDevice(); + SDL_Window *sdlwindow; + for (sdlwindow = vid->windows; sdlwindow; sdlwindow = sdlwindow->next) { + if (nswin == ((__bridge SDL_CocoaWindowData *)sdlwindow->internal).nswindow) { + break; + } + } + *stop = YES; + if (sdlwindow) { + int wx, wy; + SDL_RelativeToGlobalForWindow(sdlwindow, sdlwindow->x, sdlwindow->y, &wx, &wy); + + // Calculate the cursor coordinates relative to the window. + const float dx = mouseLocation.x - wx; + const float dy = (CGDisplayPixelsHigh(kCGDirectMainDisplay) - mouseLocation.y) - wy; + SDL_SendMouseMotion(0, sdlwindow, SDL_GLOBAL_MOUSE_ID, false, dx, dy); + } + } + }]; +} + static bool SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, NSWindow *nswindow, NSView *nsview) { @autoreleasepool { @@ -2213,8 +2243,9 @@ static bool SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, NSWindow if (window->flags & SDL_WINDOW_TOOLTIP) { [nswindow setIgnoresMouseEvents:YES]; [nswindow setAcceptsMouseMovedEvents:NO]; - } else if (window->flags & SDL_WINDOW_POPUP_MENU) { + } else if ((window->flags & SDL_WINDOW_POPUP_MENU) && !(window->flags & SDL_WINDOW_HIDDEN)) { Cocoa_SetKeyboardFocus(window, window->parent == SDL_GetKeyboardFocus()); + Cocoa_UpdateMouseFocus(); } } @@ -2599,6 +2630,9 @@ void Cocoa_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window) [nswindow orderWindow:NSWindowBelow relativeTo:[[NSApp keyWindow] windowNumber]]; } } + } else if (window->flags & SDL_WINDOW_POPUP_MENU) { + Cocoa_SetKeyboardFocus(window, window->parent == SDL_GetKeyboardFocus()); + Cocoa_UpdateMouseFocus(); } } [nswindow setIsVisible:YES]; @@ -2646,6 +2680,7 @@ void Cocoa_HideWindow(SDL_VideoDevice *_this, SDL_Window *window) } Cocoa_SetKeyboardFocus(new_focus, set_focus); + Cocoa_UpdateMouseFocus(); } else if (window->parent && waskey) { /* Key status is not automatically set on the parent when a child is hidden. Check if the * child window was key, and set the first visible parent to be key if so.