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.
diff --git a/README.md b/README.md
index 8255d7d..d328b4b 100644
--- a/README.md
+++ b/README.md
@@ -290,6 +290,8 @@
 - [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`
diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m
index a513857..e06fc90 100644
--- a/src/cocoa_monitor.m
+++ b/src/cocoa_monitor.m
@@ -430,7 +430,7 @@
     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)
diff --git a/src/cocoa_window.m b/src/cocoa_window.m
index bf6f6f2..e8e40a5 100644
--- a/src/cocoa_window.m
+++ b/src/cocoa_window.m
@@ -130,7 +130,7 @@
     _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 @@
     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 @@
 - (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 @@
 - (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 @@
 //
 float _glfwTransformYNS(float y)
 {
-    return CGDisplayBounds(CGMainDisplayID()).size.height - y;
+    return CGDisplayBounds(CGMainDisplayID()).size.height - y - 1;
 }
 
 
@@ -993,7 +992,7 @@
     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 @@
     @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 @@
         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 @@
     }
     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 @@
     @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 @@
     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;