From 546c794321b70e112324e164b5b8c3c5576bab62 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 19 Sep 2013 01:05:51 +0200 Subject: [PATCH] Fixed OS X cursor bugs #3, #72 and #88. --- README.md | 3 ++ src/cocoa_window.m | 72 +++++++++++++++++++--------------------------- 2 files changed, 33 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index c9d60fcc..bd56c176 100644 --- a/README.md +++ b/README.md @@ -206,6 +206,9 @@ See the [GLFW documentation](http://www.glfw.org/docs/latest/). - [Win32] Bugfix: `_WIN32_WINNT` was not set to Windows XP or later - [Win32] Bugfix: Legacy MinGW needs `WINVER` and `UNICODE` before `stddef.h` + - [Cocoa] Bugfix: Cursor was not visible in normal mode in full screen + - [Cocoa] Bugfix: Cursor was not actually hidden in hidden mode + - [Cocoa] Bugfix: Cursor modes were not applied to inactive windows - [X11] Bugfix: Events for mouse buttons 4 and above were not reported - [X11] Bugfix: CMake 2.8.7 does not set `X11_Xinput_LIB` even when found diff --git a/src/cocoa_window.m b/src/cocoa_window.m index a7dbe1db..b1b324d7 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -30,6 +30,25 @@ #include +// Center the cursor in the view of the window +// +static void centerCursor(_GLFWwindow *window) +{ + int width, height; + _glfwPlatformGetWindowSize(window, &width, &height); + _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0); +} + +// Update the cursor to match the specified cursor mode +// +static void setModeCursor(_GLFWwindow* window, int mode) +{ + if (mode == GLFW_CURSOR_NORMAL) + [[NSCursor arrowCursor] set]; + else + [(NSCursor*) _glfw.ns.cursor set]; +} + // Enter fullscreen mode // static void enterFullscreenMode(_GLFWwindow* window) @@ -94,13 +113,6 @@ static NSRect convertRectToBacking(_GLFWwindow* window, NSRect contentRect) @implementation GLFWWindowDelegate -static void centerCursor(_GLFWwindow *window) -{ - int width, height; - _glfwPlatformGetWindowSize(window, &width, &height); - _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0); -} - - (id)initWithGlfwWindow:(_GLFWwindow *)initWindow { self = [super init]; @@ -159,14 +171,13 @@ static void centerCursor(_GLFWwindow *window) - (void)windowDidBecomeKey:(NSNotification *)notification { _glfwInputWindowFocus(window, GL_TRUE); - - if (window->cursorMode == GLFW_CURSOR_DISABLED) - centerCursor(window); + _glfwPlatformSetCursorMode(window, window->cursorMode); } - (void)windowDidResignKey:(NSNotification *)notification { _glfwInputWindowFocus(window, GL_FALSE); + _glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL); } @end @@ -445,6 +456,11 @@ static int translateKey(unsigned int key) return YES; } +- (void)cursorUpdate:(NSEvent *)event +{ + setModeCursor(window, window->cursorMode); +} + - (void)mouseDown:(NSEvent *)event { _glfwInputMouseClick(window, @@ -548,7 +564,8 @@ static int translateKey(unsigned int key) } NSTrackingAreaOptions options = NSTrackingMouseEnteredAndExited | - NSTrackingActiveAlways | + NSTrackingActiveInKeyWindow | + NSTrackingCursorUpdate | NSTrackingInVisibleRect; trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] @@ -625,12 +642,6 @@ static int translateKey(unsigned int key) _glfwInputScroll(window, deltaX, deltaY); } -- (void)resetCursorRects -{ - [self discardCursorRects]; - [self addCursorRect:[self bounds] cursor:_glfw.ns.cursor]; -} - @end @@ -848,7 +859,6 @@ static GLboolean createWindow(_GLFWwindow* window, [window->ns.object setContentView:window->ns.view]; [window->ns.object setDelegate:window->ns.delegate]; [window->ns.object setAcceptsMouseMovedEvents:YES]; - [window->ns.object disableCursorRects]; [window->ns.object center]; #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 @@ -1058,37 +1068,15 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) { - if (mode == GLFW_CURSOR_HIDDEN) - { - [window->ns.object enableCursorRects]; - [window->ns.object invalidateCursorRectsForView:window->ns.view]; - } - else - { - [window->ns.object disableCursorRects]; - [window->ns.object invalidateCursorRectsForView:window->ns.view]; - } + setModeCursor(window, mode); if (mode == GLFW_CURSOR_DISABLED) { CGAssociateMouseAndMouseCursorPosition(false); - - if (!_glfw.ns.cursorHidden) - { - [NSCursor hide]; - _glfw.ns.cursorHidden = GL_TRUE; - } + centerCursor(window); } else - { CGAssociateMouseAndMouseCursorPosition(true); - - if (_glfw.ns.cursorHidden) - { - [NSCursor unhide]; - _glfw.ns.cursorHidden = GL_FALSE; - } - } }