From ab1301de8a5230bcb9df401f313504704d71458d Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 29 Jul 2014 08:35:56 -0700 Subject: [PATCH 1/2] Fix cursor behavior on OSX Don't implement resetCursorRects: this occasionally hides the cursor since an empty cursor is assigned to the window rectangle. Implementing this method is not required since OS displays the window cursor correctly by default. Don't reset cursor mode when window loses focus: once again, OS handles this correctly, and this means that the window cursor state is restored when window gains focus again. --- src/cocoa_window.m | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 0eff37ac2..ceac4d98e 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -197,8 +197,6 @@ static NSRect convertRectToBacking(_GLFWwindow* window, NSRect contentRect) - (void)windowDidResignKey:(NSNotification *)notification { _glfwInputWindowFocus(window, GL_FALSE); - window->cursorMode = GLFW_CURSOR_NORMAL; - _glfwPlatformApplyCursorMode(window); } @end @@ -675,14 +673,6 @@ static int translateKey(unsigned int key) _glfwInputScroll(window, deltaX, deltaY); } -- (void)resetCursorRects -{ - // This makes the cursor dissapear when the window is - // resized or received a drag operation - [self discardCursorRects]; - [self addCursorRect:[self bounds] cursor:_glfw.ns.cursor]; -} - - (NSDragOperation)draggingEntered:(id )sender { if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) From 737e58768d4e198813b738ec3f7ed12b7f1f1dd1 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 30 Jul 2014 19:57:43 -0700 Subject: [PATCH 2/2] Fix changing cursor while it's outside the window We need to invoke both [NSCursor set] and [NSView addCursorRect]. First call is responsible for changing the cursor if it's inside the view; second call is responsible for keeping the cursor the same if it's outside. --- src/cocoa_window.m | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index ceac4d98e..8e952bc55 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -39,19 +39,31 @@ static void centerCursor(_GLFWwindow *window) _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0); } -// Update the cursor to match the specified cursor mode +// Get the cursor object that window uses in the specified cursor mode // -static void setModeCursor(_GLFWwindow* window) +static NSCursor* getModeCursor(_GLFWwindow* window) { if (window->cursorMode == GLFW_CURSOR_NORMAL) { if (window->cursor) - [(NSCursor*) window->cursor->ns.object set]; + return (NSCursor*) window->cursor->ns.object; else - [[NSCursor arrowCursor] set]; + return [NSCursor arrowCursor]; } else - [(NSCursor*) _glfw.ns.cursor set]; + return (NSCursor*) _glfw.ns.cursor; +} + +// Update the cursor to match the specified cursor mode +// +static void updateModeCursor(_GLFWwindow* window) +{ + // This is required for the cursor to update if cursor is inside the window + NSCursor* cursor = getModeCursor(window); + [cursor set]; + + // This is required for the cursor to update if cursor is outside the window + [window->ns.object invalidateCursorRectsForView:window->ns.view]; } // Enter fullscreen mode @@ -478,7 +490,7 @@ static int translateKey(unsigned int key) - (void)cursorUpdate:(NSEvent *)event { - setModeCursor(window); + updateModeCursor(window); } - (void)mouseDown:(NSEvent *)event @@ -673,6 +685,13 @@ static int translateKey(unsigned int key) _glfwInputScroll(window, deltaX, deltaY); } +- (void)resetCursorRects +{ + NSCursor* cursor = getModeCursor(window); + + [self addCursorRect:[self bounds] cursor:cursor]; +} + - (NSDragOperation)draggingEntered:(id )sender { if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) @@ -1191,7 +1210,7 @@ void _glfwPlatformPostEmptyEvent(void) void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) { - setModeCursor(window); + updateModeCursor(window); if (window->monitor) { @@ -1211,7 +1230,7 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) void _glfwPlatformApplyCursorMode(_GLFWwindow* window) { - setModeCursor(window); + updateModeCursor(window); if (window->cursorMode == GLFW_CURSOR_DISABLED) {