Patch from Christian Walther SDL-1.2
authorSam Lantinga <slouken@libsdl.org>
Sun, 15 Jul 2007 15:58:00 +0000
branchSDL-1.2
changeset 4070b8f2db95145e
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
     1.1 --- a/src/video/quartz/SDL_QuartzEvents.m	Sun Jul 15 14:14:45 2007 +0000
     1.2 +++ b/src/video/quartz/SDL_QuartzEvents.m	Sun Jul 15 15:58:00 2007 +0000
     1.3 @@ -22,6 +22,7 @@
     1.4  #include "SDL_config.h"
     1.5  
     1.6  #include "SDL_QuartzVideo.h"
     1.7 +#include "SDL_QuartzWM.h"
     1.8  
     1.9  #include <IOKit/IOMessage.h> /* For wake from sleep detection */
    1.10  #include <IOKit/pwr_mgt/IOPMLib.h> /* For wake from sleep detection */
    1.11 @@ -623,22 +624,9 @@
    1.12  
    1.13  void QZ_DoActivate (_THIS) {
    1.14  
    1.15 -    BOOL isInGameWin = QZ_IsMouseInWindow (this);
    1.16 +    SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS | (QZ_IsMouseInWindow (this) ? SDL_APPMOUSEFOCUS : 0));
    1.17  
    1.18 -    SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS | (isInGameWin ? SDL_APPMOUSEFOCUS : 0));
    1.19 -
    1.20 -    /* Reset the cursor state */
    1.21 -    /* FIXME: This doesn't currently work...
    1.22 -       Apparently you can't set the cursor inside windowDidBecomeKey
    1.23 -     */
    1.24 -    if ( isInGameWin ) {
    1.25 -        if (cursor_should_be_visible)
    1.26 -            SDL_SetCursor (NULL);
    1.27 -        else
    1.28 -            QZ_HideMouse (this);
    1.29 -    } else {
    1.30 -        QZ_ShowMouse (this, [NSCursor arrowCursor]);
    1.31 -    }
    1.32 +    QZ_UpdateCursor(this);
    1.33  
    1.34      /* Regrab input, only if it was previously grabbed */
    1.35      if ( current_grab_mode == SDL_GRAB_ON ) {
    1.36 @@ -665,9 +653,7 @@
    1.37      /* Reassociate mouse and cursor */
    1.38      CGAssociateMouseAndMouseCursorPosition (1);
    1.39  
    1.40 -    /* Show the cursor if it was hidden by SDL_ShowCursor() */
    1.41 -    if (!cursor_should_be_visible)
    1.42 -        QZ_ShowMouse (this, [NSCursor arrowCursor]);
    1.43 +    QZ_UpdateCursor(this);
    1.44  }
    1.45  
    1.46  void QZ_SleepNotificationHandler (void * refcon,
    1.47 @@ -904,6 +890,7 @@
    1.48                      if ( !isInGameWin && (SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
    1.49                      
    1.50                          SDL_PrivateAppActive (0, SDL_APPMOUSEFOCUS);
    1.51 +
    1.52                          if (grab_state == QZ_INVISIBLE_GRAB)
    1.53                              /*The cursor has left the window even though it is
    1.54                                disassociated from the mouse (and therefore
    1.55 @@ -920,18 +907,14 @@
    1.56                                to the user that the grab is broken.*/
    1.57                              CGAssociateMouseAndMouseCursorPosition (1);
    1.58  
    1.59 -                        QZ_ShowMouse (this, [NSCursor arrowCursor]);
    1.60 +                        QZ_UpdateCursor(this);
    1.61                      }
    1.62                      else
    1.63                      if ( isInGameWin && (SDL_GetAppState() & (SDL_APPMOUSEFOCUS | SDL_APPINPUTFOCUS)) == SDL_APPINPUTFOCUS ) {
    1.64                      
    1.65                          SDL_PrivateAppActive (1, SDL_APPMOUSEFOCUS);
    1.66  
    1.67 -                        if (cursor_should_be_visible) {
    1.68 -                            SDL_SetCursor (NULL);
    1.69 -                        } else {
    1.70 -                            QZ_HideMouse (this);
    1.71 -                        }
    1.72 +                        QZ_UpdateCursor(this);
    1.73  
    1.74                          if (grab_state == QZ_INVISIBLE_GRAB) { /*see comment above*/
    1.75                              QZ_PrivateWarpCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2);
     2.1 --- a/src/video/quartz/SDL_QuartzVideo.h	Sun Jul 15 14:14:45 2007 +0000
     2.2 +++ b/src/video/quartz/SDL_QuartzVideo.h	Sun Jul 15 15:58:00 2007 +0000
     2.3 @@ -224,8 +224,6 @@
     2.4  void         QZ_PrivateWarpCursor (_THIS, int x, int y);
     2.5  void         QZ_ChangeGrabState (_THIS, int action);
     2.6  void         QZ_RegisterForSleepNotifications (_THIS);
     2.7 -void         QZ_ShowMouse (_THIS, NSCursor *cursor);
     2.8 -void         QZ_HideMouse (_THIS);
     2.9  void         QZ_PrivateGlobalToLocal (_THIS, NSPoint *p);
    2.10  void         QZ_PrivateCocoaToSDL (_THIS, NSPoint *p);
    2.11  BOOL         QZ_IsMouseInWindow (_THIS);
     3.1 --- a/src/video/quartz/SDL_QuartzVideo.m	Sun Jul 15 14:14:45 2007 +0000
     3.2 +++ b/src/video/quartz/SDL_QuartzVideo.m	Sun Jul 15 15:58:00 2007 +0000
     3.3 @@ -756,6 +756,7 @@
     3.4          }
     3.5          [ qz_window setDelegate:
     3.6              [ [ [ SDL_QuartzWindowDelegate alloc ] init ] autorelease ] ];
     3.7 +        [ qz_window setContentView: [ [ [ SDL_QuartzView alloc ] init ] autorelease ] ];
     3.8      }
     3.9      /* We already have a window, just change its size */
    3.10      else {
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/video/quartz/SDL_QuartzWM.h	Sun Jul 15 15:58:00 2007 +0000
     4.3 @@ -0,0 +1,27 @@
     4.4 +/*
     4.5 +    SDL - Simple DirectMedia Layer
     4.6 +    Copyright (C) 1997-2003  Sam Lantinga
     4.7 +
     4.8 +    This library is free software; you can redistribute it and/or
     4.9 +    modify it under the terms of the GNU Library General Public
    4.10 +    License as published by the Free Software Foundation; either
    4.11 +    version 2 of the License, or (at your option) any later version.
    4.12 +
    4.13 +    This library is distributed in the hope that it will be useful,
    4.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    4.16 +    Library General Public License for more details.
    4.17 +
    4.18 +    You should have received a copy of the GNU Library General Public
    4.19 +    License along with this library; if not, write to the Free
    4.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    4.21 +
    4.22 +    Sam Lantinga
    4.23 +    slouken@libsdl.org
    4.24 +*/
    4.25 +
    4.26 +struct WMcursor {
    4.27 +    NSCursor *nscursor;
    4.28 +};
    4.29 +
    4.30 +void QZ_UpdateCursor(_THIS);
     5.1 --- a/src/video/quartz/SDL_QuartzWM.m	Sun Jul 15 14:14:45 2007 +0000
     5.2 +++ b/src/video/quartz/SDL_QuartzWM.m	Sun Jul 15 15:58:00 2007 +0000
     5.3 @@ -22,12 +22,9 @@
     5.4  #include "SDL_config.h"
     5.5  
     5.6  #include "SDL_QuartzVideo.h"
     5.7 +#include "SDL_QuartzWM.h"
     5.8  
     5.9  
    5.10 -struct WMcursor {
    5.11 -    NSCursor *nscursor;
    5.12 -};
    5.13 -
    5.14  void QZ_FreeWMCursor     (_THIS, WMcursor *cursor) { 
    5.15  
    5.16      if ( cursor != NULL ) {
    5.17 @@ -90,18 +87,21 @@
    5.18      return(NULL);
    5.19  }
    5.20  
    5.21 -void QZ_ShowMouse (_THIS, NSCursor *cursor) {
    5.22 -    if (!cursor_visible) {
    5.23 -        [ NSCursor unhide ];
    5.24 -        cursor_visible = YES;
    5.25 +void QZ_UpdateCursor (_THIS) {
    5.26 +    BOOL state;
    5.27 +
    5.28 +    if (cursor_should_be_visible || !(SDL_GetAppState() & SDL_APPMOUSEFOCUS)) {
    5.29 +        state = YES;
    5.30 +    } else {
    5.31 +        state = NO;
    5.32      }
    5.33 -    [ cursor set ];
    5.34 -}
    5.35 -
    5.36 -void QZ_HideMouse (_THIS) {
    5.37 -    if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS) && cursor_visible) {
    5.38 -        [ NSCursor hide ];
    5.39 -        cursor_visible = NO;
    5.40 +    if (state != cursor_visible) {
    5.41 +        if (state) {
    5.42 +            [ NSCursor unhide ];
    5.43 +        } else {
    5.44 +            [ NSCursor hide ];
    5.45 +        }
    5.46 +        cursor_visible = state;
    5.47      }
    5.48  }
    5.49  
    5.50 @@ -117,18 +117,24 @@
    5.51  int QZ_ShowWMCursor (_THIS, WMcursor *cursor) { 
    5.52  
    5.53      if ( cursor == NULL) {
    5.54 -        QZ_HideMouse (this);
    5.55          if ( cursor_should_be_visible ) {
    5.56              cursor_should_be_visible = NO;
    5.57              QZ_ChangeGrabState (this, QZ_HIDECURSOR);
    5.58          }
    5.59 +        QZ_UpdateCursor(this);
    5.60      }
    5.61      else {
    5.62 -        QZ_ShowMouse (this, cursor->nscursor);
    5.63 +        if (qz_window ==nil || (mode_flags & SDL_FULLSCREEN)) {
    5.64 +            [ cursor->nscursor set ];
    5.65 +        }
    5.66 +        else {
    5.67 +            [ qz_window invalidateCursorRectsForView: [ qz_window contentView ] ];
    5.68 +        }
    5.69          if ( ! cursor_should_be_visible ) {
    5.70              cursor_should_be_visible = YES;
    5.71              QZ_ChangeGrabState (this, QZ_SHOWCURSOR);
    5.72          }
    5.73 +        QZ_UpdateCursor(this);
    5.74      }
    5.75  
    5.76      return 1;
     6.1 --- a/src/video/quartz/SDL_QuartzWindow.h	Sun Jul 15 14:14:45 2007 +0000
     6.2 +++ b/src/video/quartz/SDL_QuartzWindow.h	Sun Jul 15 15:58:00 2007 +0000
     6.3 @@ -37,3 +37,7 @@
     6.4  - (BOOL)windowShouldClose:(id)sender;
     6.5  @end
     6.6  
     6.7 +/* Subclass of NSView to set cursor rectangle */
     6.8 +@interface SDL_QuartzView : NSView
     6.9 +- (void)resetCursorRects;
    6.10 +@end
     7.1 --- a/src/video/quartz/SDL_QuartzWindow.m	Sun Jul 15 14:14:45 2007 +0000
     7.2 +++ b/src/video/quartz/SDL_QuartzWindow.m	Sun Jul 15 15:58:00 2007 +0000
     7.3 @@ -22,6 +22,7 @@
     7.4  #include "SDL_config.h"
     7.5  
     7.6  #include "SDL_QuartzVideo.h"
     7.7 +#include "SDL_QuartzWM.h"
     7.8  #include "SDL_QuartzWindow.h"
     7.9  
    7.10  /*
    7.11 @@ -217,3 +218,15 @@
    7.12  }
    7.13  
    7.14  @end
    7.15 +
    7.16 +@implementation SDL_QuartzView
    7.17 +
    7.18 +- (void)resetCursorRects
    7.19 +{
    7.20 +    SDL_Cursor *sdlc = SDL_GetCursor();
    7.21 +    if (sdlc != NULL && sdlc->wm_cursor != NULL) {
    7.22 +        [self addCursorRect: [self visibleRect] cursor: sdlc->wm_cursor->nscursor];
    7.23 +    }
    7.24 +}
    7.25 +
    7.26 +@end