Fixed bug 4255 - SDL_GetGlobalMouseState() returns incorrect Y on secondary display
authorSam Lantinga <slouken@libsdl.org>
Fri, 04 Jan 2019 22:09:38 -0800
changeset 1250474e8ace1b2c3
parent 12503 806492103856
child 12505 b5f8e6c420c2
Fixed bug 4255 - SDL_GetGlobalMouseState() returns incorrect Y on secondary display

Julian Raschke

I use an open Mac laptop with an additional external monitor. The coordinate spaces from SDL_GetGlobalMouseState() and SDL_GetWindowPosition() match on the primary display, but not on the secondary display.

Cocoa window coordinates are vertically flipped in relation to the primary display:

https://github.com/spurious/SDL-mirror/blob/release-2.0.8/src/video/cocoa/SDL_cocoawindow.m#L219-L222

However, Cocoa_GetGlobalMouseState inverts the cursor Y coordinate per-display:

https://github.com/spurious/SDL-mirror/blob/release-2.0.8/src/video/cocoa/SDL_cocoamouse.m#L320-L323

Suggested fix: Replace the for-loop with this simpler calculation:

*x = (int) cocoaLocation.x;
*y = (int) (CGDisplayPixelsHigh(kCGDirectMainDisplay) - cocoaLocation.y);
src/video/cocoa/SDL_cocoamouse.m
     1.1 --- a/src/video/cocoa/SDL_cocoamouse.m	Fri Jan 04 22:01:14 2019 -0800
     1.2 +++ b/src/video/cocoa/SDL_cocoamouse.m	Fri Jan 04 22:09:38 2019 -0800
     1.3 @@ -315,14 +315,8 @@
     1.4      const NSPoint cocoaLocation = [NSEvent mouseLocation];
     1.5      Uint32 retval = 0;
     1.6  
     1.7 -    for (NSScreen *screen in [NSScreen screens]) {
     1.8 -        NSRect frame = [screen frame];
     1.9 -        if (NSMouseInRect(cocoaLocation, frame, NO)) {
    1.10 -            *x = (int) cocoaLocation.x;
    1.11 -            *y = (int) ((frame.origin.y + frame.size.height) - cocoaLocation.y);
    1.12 -            break;
    1.13 -        }
    1.14 -    }
    1.15 +    *x = (int) cocoaLocation.x;
    1.16 +    *y = (int) (CGDisplayPixelsHigh(kCGDirectMainDisplay) - cocoaLocation.y);
    1.17  
    1.18      retval |= (cocoaButtons & (1 << 0)) ? SDL_BUTTON_LMASK : 0;
    1.19      retval |= (cocoaButtons & (1 << 1)) ? SDL_BUTTON_RMASK : 0;