Cocoa: Fix coordinate transformations

Window relative mouse locations provided via NSWindow and NSEvent are
based at 0,1 while screen relative locations use 0,0.  Incorrect
handling of this had crept into other coordinate transformations.  Note
that most of these errors canceled each other out, so the reported
positions of windows, monitors and work areas are unaffected.  This
corrects the cursor position for glfwGetCursorPos and glfwSetCursorPos.

Fixes #1461.
This commit is contained in:
Camilla Löwy 2019-04-10 21:19:40 +02:00 committed by Camilla Löwy
parent d0b7f539e2
commit 3c3981a4f0
3 changed files with 18 additions and 15 deletions

View File

@ -290,6 +290,8 @@ information on what to include when reporting a bug.
- [Cocoa] Bugfix: OpenGL swap interval was ignored for occluded windows (#680)
- [Cocoa] Bugfix: OpenGL swap interval was ignored on early macOS 10.14
(#1337,#1417,#1435)
- [Cocoa] Bugfix: The y-coordinate was incorrect for `glfwGetCursorPos` and
`glfwSetCursorPos` (#1461)
- [WGL] Added support for `WGL_EXT_colorspace` for OpenGL ES contexts
- [WGL] Added support for `WGL_ARB_create_context_no_error`
- [GLX] Added support for `GLX_ARB_create_context_no_error`

View File

@ -430,7 +430,7 @@ void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
if (xpos)
*xpos = frameRect.origin.x;
if (ypos)
*ypos = _glfwTransformYNS(frameRect.origin.y + frameRect.size.height);
*ypos = _glfwTransformYNS(frameRect.origin.y + frameRect.size.height - 1);
if (width)
*width = frameRect.size.width;
if (height)

View File

@ -130,7 +130,7 @@ static void acquireMonitor(_GLFWwindow* window)
_glfwSetVideoModeNS(window->monitor, &window->videoMode);
const CGRect bounds = CGDisplayBounds(window->monitor->ns.displayID);
const NSRect frame = NSMakeRect(bounds.origin.x,
_glfwTransformYNS(bounds.origin.y + bounds.size.height),
_glfwTransformYNS(bounds.origin.y + bounds.size.height - 1),
bounds.size.width,
bounds.size.height);
@ -445,6 +445,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
else
{
const NSRect contentRect = [window->ns.view frame];
// NOTE: The returned location uses base 0,1 not 0,0
const NSPoint pos = [event locationInWindow];
_glfwInputCursorPos(window, pos.x, contentRect.size.height - pos.y);
@ -634,9 +635,9 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
const NSRect contentRect = [window->ns.view frame];
_glfwInputCursorPos(window,
[sender draggingLocation].x,
contentRect.size.height - [sender draggingLocation].y);
// NOTE: The returned location uses base 0,1 not 0,0
const NSPoint pos = [sender draggingLocation];
_glfwInputCursorPos(window, pos.x, contentRect.size.height - pos.y);
NSPasteboard* pasteboard = [sender draggingPasteboard];
NSDictionary* options = @{NSPasteboardURLReadingFileURLsOnlyKey:@YES};
@ -713,10 +714,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (NSRect)firstRectForCharacterRange:(NSRange)range
actualRange:(NSRangePointer)actualRange
{
int xpos, ypos;
_glfwPlatformGetWindowPos(window, &xpos, &ypos);
const NSRect contentRect = [window->ns.view frame];
return NSMakeRect(xpos, _glfwTransformYNS(ypos + contentRect.size.height), 0.0, 0.0);
const NSRect frame = [window->ns.view frame];
return NSMakeRect(frame.origin.x, frame.origin.y, 0.0, 0.0);
}
- (void)insertText:(id)string replacementRange:(NSRange)replacementRange
@ -878,7 +877,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
//
float _glfwTransformYNS(float y)
{
return CGDisplayBounds(CGMainDisplayID()).size.height - y;
return CGDisplayBounds(CGMainDisplayID()).size.height - y - 1;
}
@ -993,7 +992,7 @@ void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
if (xpos)
*xpos = contentRect.origin.x;
if (ypos)
*ypos = _glfwTransformYNS(contentRect.origin.y + contentRect.size.height);
*ypos = _glfwTransformYNS(contentRect.origin.y + contentRect.size.height - 1);
} // autoreleasepool
}
@ -1003,7 +1002,7 @@ void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y)
@autoreleasepool {
const NSRect contentRect = [window->ns.view frame];
const NSRect dummyRect = NSMakeRect(x, _glfwTransformYNS(y + contentRect.size.height), 0, 0);
const NSRect dummyRect = NSMakeRect(x, _glfwTransformYNS(y + contentRect.size.height - 1), 0, 0);
const NSRect frameRect = [window->ns.object frameRectForContentRect:dummyRect];
[window->ns.object setFrameOrigin:frameRect.origin];
@ -1198,7 +1197,7 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
else
{
const NSRect contentRect =
NSMakeRect(xpos, _glfwTransformYNS(ypos + height), width, height);
NSMakeRect(xpos, _glfwTransformYNS(ypos + height - 1), width, height);
const NSRect frameRect =
[window->ns.object frameRectForContentRect:contentRect
styleMask:getStyleMask(window)];
@ -1232,7 +1231,7 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
}
else
{
NSRect contentRect = NSMakeRect(xpos, _glfwTransformYNS(ypos + height),
NSRect contentRect = NSMakeRect(xpos, _glfwTransformYNS(ypos + height - 1),
width, height);
NSRect frameRect = [window->ns.object frameRectForContentRect:contentRect
styleMask:styleMask];
@ -1451,12 +1450,13 @@ void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
@autoreleasepool {
const NSRect contentRect = [window->ns.view frame];
// NOTE: The returned location uses base 0,1 not 0,0
const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream];
if (xpos)
*xpos = pos.x;
if (ypos)
*ypos = contentRect.size.height - pos.y - 1;
*ypos = contentRect.size.height - pos.y;
} // autoreleasepool
}
@ -1468,6 +1468,7 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
updateCursorImage(window);
const NSRect contentRect = [window->ns.view frame];
// NOTE: The returned location uses base 0,1 not 0,0
const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream];
window->ns.cursorWarpDeltaX += x - pos.x;