From 1f148f2bd6a57f4b64cb6d82d53c30599646b379 Mon Sep 17 00:00:00 2001 From: Noel Cower Date: Tue, 16 Apr 2013 16:35:14 -0600 Subject: [PATCH 1/3] Keep cursor centered in window while captured. Previously, cmd-tabbing out would result in the cursor position maybe ending up outside the window, so if one cmd-tabbed back in with the cursor still outside, any click would go outside the window and cause it to lose focus. Not really a good thing. So, this is a bit of a hack, but it works. --- src/cocoa_window.m | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 6e781723..76f0811d 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -48,6 +48,16 @@ @implementation GLFWWindowDelegate +static void resetMouseCursor(_GLFWwindow *window) +{ + if (window->cursorMode == GLFW_CURSOR_CAPTURED) + { + int width, height; + _glfwPlatformGetWindowSize(window, &width, &height); + _glfwPlatformSetCursorPos(window, width / 2, height / 2); + } +} + - (id)initWithGlfwWindow:(_GLFWwindow *)initWindow { self = [super init]; @@ -70,6 +80,8 @@ int width, height; _glfwPlatformGetWindowSize(window, &width, &height); _glfwInputWindowSize(window, width, height); + + resetMouseCursor(window); } - (void)windowDidMove:(NSNotification *)notification @@ -79,6 +91,8 @@ int x, y; _glfwPlatformGetWindowPos(window, &x, &y); _glfwInputWindowPos(window, x, y); + + resetMouseCursor(window); } - (void)windowDidMiniaturize:(NSNotification *)notification @@ -94,6 +108,8 @@ - (void)windowDidBecomeKey:(NSNotification *)notification { _glfwInputWindowFocus(window, GL_TRUE); + + resetMouseCursor(window); } - (void)windowDidResignKey:(NSNotification *)notification From 1ba8fd05c043ec33e05dd49bcfbfa779dd4a36b6 Mon Sep 17 00:00:00 2001 From: Noel Cower Date: Tue, 16 Apr 2013 16:37:06 -0600 Subject: [PATCH 2/3] Add GLFW_CURSOR_HIDDEN. Uses addCursorRect:cursor: as discussed.. well, too long ago. Anyhow, this will effectively hide the cursor while it is inside a window with GLFW_CURSOR_HIDDEN or GLFW_CURSOR_CAPTURED enabled. This shouldn't mess up cursor retain counts either, unlike previous uses of the hide/unhide methods on NSCursor. It does allocate a small, single-pixel image for an invisible cursor, as well as the cursor itself, but that shouldn't be too much trouble. --- src/cocoa_window.m | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 76f0811d..53681199 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -309,6 +309,8 @@ static int convertMacKeyCode(unsigned int macKeyCode) // Content view class for the GLFW window //------------------------------------------------------------------------ +static NSCursor *emptyCursor = nil; + @interface GLFWContentView : NSView { _GLFWwindow* window; @@ -321,6 +323,16 @@ static int convertMacKeyCode(unsigned int macKeyCode) @implementation GLFWContentView ++ (void)initialize +{ + if (self == [GLFWContentView class]) + { + NSImage *emptyImage = [[NSImage alloc] initWithSize:NSMakeSize(1, 1)]; + emptyCursor = [[NSCursor alloc] initWithImage:emptyImage hotSpot:NSZeroPoint]; + [emptyImage release]; + } +} + - (id)initWithGlfwWindow:(_GLFWwindow *)initWindow { self = [super init]; @@ -494,6 +506,11 @@ static int convertMacKeyCode(unsigned int macKeyCode) _glfwInputScroll(window, deltaX, deltaY); } +- (void)resetCursorRects +{ + [self addCursorRect:[self bounds] cursor:emptyCursor]; +} + @end @@ -929,16 +946,21 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) { + // Unhide the cursor if the last mode was CAPTURED. + if (window->cursorMode == GLFW_CURSOR_CAPTURED) { + CGAssociateMouseAndMouseCursorPosition(true); + } + switch (mode) { case GLFW_CURSOR_NORMAL: - [NSCursor unhide]; - CGAssociateMouseAndMouseCursorPosition(true); + [window->ns.object disableCursorRects]; break; case GLFW_CURSOR_HIDDEN: + [window->ns.object enableCursorRects]; break; case GLFW_CURSOR_CAPTURED: - [NSCursor hide]; + [window->ns.object enableCursorRects]; CGAssociateMouseAndMouseCursorPosition(false); break; } From 662958ef119c940f25ff1c5bd823e457727c9a49 Mon Sep 17 00:00:00 2001 From: Noel Cower Date: Tue, 16 Apr 2013 16:49:43 -0600 Subject: [PATCH 3/3] Make resetMouseCursor consistent with setCursorMode --- src/cocoa_window.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 53681199..eb545250 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -54,7 +54,7 @@ static void resetMouseCursor(_GLFWwindow *window) { int width, height; _glfwPlatformGetWindowSize(window, &width, &height); - _glfwPlatformSetCursorPos(window, width / 2, height / 2); + _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0); } }