Patch from Christian Walther SDL-1.2
authorSam Lantinga <slouken@libsdl.org>
Sun, 15 Jul 2007 15:58:00 +0000
branchSDL-1.2
changeset 4070 b8f2db95145e
parent 4069 f19931785c42
child 4071 3d9040dcc47e
Patch from Christian Walther Yes, the idea to use a cursor rectangle instead of [NSCursor set] has occurred to me too, and it does seem to be the most elegant way. Here's my attempt at an implementation
src/video/quartz/SDL_QuartzEvents.m
src/video/quartz/SDL_QuartzVideo.h
src/video/quartz/SDL_QuartzVideo.m
src/video/quartz/SDL_QuartzWM.h
src/video/quartz/SDL_QuartzWM.m
src/video/quartz/SDL_QuartzWindow.h
src/video/quartz/SDL_QuartzWindow.m
--- a/src/video/quartz/SDL_QuartzEvents.m	Sun Jul 15 14:14:45 2007 +0000
+++ b/src/video/quartz/SDL_QuartzEvents.m	Sun Jul 15 15:58:00 2007 +0000
@@ -22,6 +22,7 @@
 #include "SDL_config.h"
 
 #include "SDL_QuartzVideo.h"
+#include "SDL_QuartzWM.h"
 
 #include <IOKit/IOMessage.h> /* For wake from sleep detection */
 #include <IOKit/pwr_mgt/IOPMLib.h> /* For wake from sleep detection */
@@ -623,22 +624,9 @@
 
 void QZ_DoActivate (_THIS) {
 
-    BOOL isInGameWin = QZ_IsMouseInWindow (this);
-
-    SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS | (isInGameWin ? SDL_APPMOUSEFOCUS : 0));
+    SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS | (QZ_IsMouseInWindow (this) ? SDL_APPMOUSEFOCUS : 0));
 
-    /* Reset the cursor state */
-    /* FIXME: This doesn't currently work...
-       Apparently you can't set the cursor inside windowDidBecomeKey
-     */
-    if ( isInGameWin ) {
-        if (cursor_should_be_visible)
-            SDL_SetCursor (NULL);
-        else
-            QZ_HideMouse (this);
-    } else {
-        QZ_ShowMouse (this, [NSCursor arrowCursor]);
-    }
+    QZ_UpdateCursor(this);
 
     /* Regrab input, only if it was previously grabbed */
     if ( current_grab_mode == SDL_GRAB_ON ) {
@@ -665,9 +653,7 @@
     /* Reassociate mouse and cursor */
     CGAssociateMouseAndMouseCursorPosition (1);
 
-    /* Show the cursor if it was hidden by SDL_ShowCursor() */
-    if (!cursor_should_be_visible)
-        QZ_ShowMouse (this, [NSCursor arrowCursor]);
+    QZ_UpdateCursor(this);
 }
 
 void QZ_SleepNotificationHandler (void * refcon,
@@ -904,6 +890,7 @@
                     if ( !isInGameWin && (SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
                     
                         SDL_PrivateAppActive (0, SDL_APPMOUSEFOCUS);
+
                         if (grab_state == QZ_INVISIBLE_GRAB)
                             /*The cursor has left the window even though it is
                               disassociated from the mouse (and therefore
@@ -920,18 +907,14 @@
                               to the user that the grab is broken.*/
                             CGAssociateMouseAndMouseCursorPosition (1);
 
-                        QZ_ShowMouse (this, [NSCursor arrowCursor]);
+                        QZ_UpdateCursor(this);
                     }
                     else
                     if ( isInGameWin && (SDL_GetAppState() & (SDL_APPMOUSEFOCUS | SDL_APPINPUTFOCUS)) == SDL_APPINPUTFOCUS ) {
                     
                         SDL_PrivateAppActive (1, SDL_APPMOUSEFOCUS);
 
-                        if (cursor_should_be_visible) {
-                            SDL_SetCursor (NULL);
-                        } else {
-                            QZ_HideMouse (this);
-                        }
+                        QZ_UpdateCursor(this);
 
                         if (grab_state == QZ_INVISIBLE_GRAB) { /*see comment above*/
                             QZ_PrivateWarpCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2);
--- a/src/video/quartz/SDL_QuartzVideo.h	Sun Jul 15 14:14:45 2007 +0000
+++ b/src/video/quartz/SDL_QuartzVideo.h	Sun Jul 15 15:58:00 2007 +0000
@@ -224,8 +224,6 @@
 void         QZ_PrivateWarpCursor (_THIS, int x, int y);
 void         QZ_ChangeGrabState (_THIS, int action);
 void         QZ_RegisterForSleepNotifications (_THIS);
-void         QZ_ShowMouse (_THIS, NSCursor *cursor);
-void         QZ_HideMouse (_THIS);
 void         QZ_PrivateGlobalToLocal (_THIS, NSPoint *p);
 void         QZ_PrivateCocoaToSDL (_THIS, NSPoint *p);
 BOOL         QZ_IsMouseInWindow (_THIS);
--- a/src/video/quartz/SDL_QuartzVideo.m	Sun Jul 15 14:14:45 2007 +0000
+++ b/src/video/quartz/SDL_QuartzVideo.m	Sun Jul 15 15:58:00 2007 +0000
@@ -756,6 +756,7 @@
         }
         [ qz_window setDelegate:
             [ [ [ SDL_QuartzWindowDelegate alloc ] init ] autorelease ] ];
+        [ qz_window setContentView: [ [ [ SDL_QuartzView alloc ] init ] autorelease ] ];
     }
     /* We already have a window, just change its size */
     else {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/quartz/SDL_QuartzWM.h	Sun Jul 15 15:58:00 2007 +0000
@@ -0,0 +1,27 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2003  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+struct WMcursor {
+    NSCursor *nscursor;
+};
+
+void QZ_UpdateCursor(_THIS);
--- a/src/video/quartz/SDL_QuartzWM.m	Sun Jul 15 14:14:45 2007 +0000
+++ b/src/video/quartz/SDL_QuartzWM.m	Sun Jul 15 15:58:00 2007 +0000
@@ -22,11 +22,8 @@
 #include "SDL_config.h"
 
 #include "SDL_QuartzVideo.h"
-
+#include "SDL_QuartzWM.h"
 
-struct WMcursor {
-    NSCursor *nscursor;
-};
 
 void QZ_FreeWMCursor     (_THIS, WMcursor *cursor) { 
 
@@ -90,18 +87,21 @@
     return(NULL);
 }
 
-void QZ_ShowMouse (_THIS, NSCursor *cursor) {
-    if (!cursor_visible) {
-        [ NSCursor unhide ];
-        cursor_visible = YES;
+void QZ_UpdateCursor (_THIS) {
+    BOOL state;
+
+    if (cursor_should_be_visible || !(SDL_GetAppState() & SDL_APPMOUSEFOCUS)) {
+        state = YES;
+    } else {
+        state = NO;
     }
-    [ cursor set ];
-}
-
-void QZ_HideMouse (_THIS) {
-    if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS) && cursor_visible) {
-        [ NSCursor hide ];
-        cursor_visible = NO;
+    if (state != cursor_visible) {
+        if (state) {
+            [ NSCursor unhide ];
+        } else {
+            [ NSCursor hide ];
+        }
+        cursor_visible = state;
     }
 }
 
@@ -117,18 +117,24 @@
 int QZ_ShowWMCursor (_THIS, WMcursor *cursor) { 
 
     if ( cursor == NULL) {
-        QZ_HideMouse (this);
         if ( cursor_should_be_visible ) {
             cursor_should_be_visible = NO;
             QZ_ChangeGrabState (this, QZ_HIDECURSOR);
         }
+        QZ_UpdateCursor(this);
     }
     else {
-        QZ_ShowMouse (this, cursor->nscursor);
+        if (qz_window ==nil || (mode_flags & SDL_FULLSCREEN)) {
+            [ cursor->nscursor set ];
+        }
+        else {
+            [ qz_window invalidateCursorRectsForView: [ qz_window contentView ] ];
+        }
         if ( ! cursor_should_be_visible ) {
             cursor_should_be_visible = YES;
             QZ_ChangeGrabState (this, QZ_SHOWCURSOR);
         }
+        QZ_UpdateCursor(this);
     }
 
     return 1;
--- a/src/video/quartz/SDL_QuartzWindow.h	Sun Jul 15 14:14:45 2007 +0000
+++ b/src/video/quartz/SDL_QuartzWindow.h	Sun Jul 15 15:58:00 2007 +0000
@@ -37,3 +37,7 @@
 - (BOOL)windowShouldClose:(id)sender;
 @end
 
+/* Subclass of NSView to set cursor rectangle */
+@interface SDL_QuartzView : NSView
+- (void)resetCursorRects;
+@end
--- a/src/video/quartz/SDL_QuartzWindow.m	Sun Jul 15 14:14:45 2007 +0000
+++ b/src/video/quartz/SDL_QuartzWindow.m	Sun Jul 15 15:58:00 2007 +0000
@@ -22,6 +22,7 @@
 #include "SDL_config.h"
 
 #include "SDL_QuartzVideo.h"
+#include "SDL_QuartzWM.h"
 #include "SDL_QuartzWindow.h"
 
 /*
@@ -217,3 +218,15 @@
 }
 
 @end
+
+@implementation SDL_QuartzView
+
+- (void)resetCursorRects
+{
+    SDL_Cursor *sdlc = SDL_GetCursor();
+    if (sdlc != NULL && sdlc->wm_cursor != NULL) {
+        [self addCursorRect: [self visibleRect] cursor: sdlc->wm_cursor->nscursor];
+    }
+}
+
+@end