Skip to content

Commit

Permalink
Patch from Christian Walther
Browse files Browse the repository at this point in the history
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
  • Loading branch information
slouken committed Jul 15, 2007
1 parent e1cd8a3 commit 632e5cf
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 43 deletions.
31 changes: 7 additions & 24 deletions src/video/quartz/SDL_QuartzEvents.m
Expand Up @@ -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 */
Expand Down Expand Up @@ -623,22 +624,9 @@ static void QZ_GetMouseLocation (_THIS, NSPoint *p) {

void QZ_DoActivate (_THIS) {

BOOL isInGameWin = QZ_IsMouseInWindow (this);
SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS | (QZ_IsMouseInWindow (this) ? SDL_APPMOUSEFOCUS : 0));

SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS | (isInGameWin ? 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 ) {
Expand All @@ -665,9 +653,7 @@ void QZ_DoDeactivate (_THIS) {
/* 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,
Expand Down Expand Up @@ -904,6 +890,7 @@ but not as a result of the warp (so it's in the right direction).
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
Expand All @@ -920,18 +907,14 @@ disassociated from the mouse (and therefore
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);
Expand Down
2 changes: 0 additions & 2 deletions src/video/quartz/SDL_QuartzVideo.h
Expand Up @@ -224,8 +224,6 @@ SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
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);
Expand Down
1 change: 1 addition & 0 deletions src/video/quartz/SDL_QuartzVideo.m
Expand Up @@ -756,6 +756,7 @@ other blitting while waiting on the VBL (and hence results in higher framerates)
}
[ 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 {
Expand Down
27 changes: 27 additions & 0 deletions src/video/quartz/SDL_QuartzWM.h
@@ -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);
40 changes: 23 additions & 17 deletions src/video/quartz/SDL_QuartzWM.m
Expand Up @@ -22,12 +22,9 @@
#include "SDL_config.h"

#include "SDL_QuartzVideo.h"
#include "SDL_QuartzWM.h"


struct WMcursor {
NSCursor *nscursor;
};

void QZ_FreeWMCursor (_THIS, WMcursor *cursor) {

if ( cursor != NULL ) {
Expand Down Expand Up @@ -90,18 +87,21 @@ void QZ_FreeWMCursor (_THIS, WMcursor *cursor) {
return(NULL);
}

void QZ_ShowMouse (_THIS, NSCursor *cursor) {
if (!cursor_visible) {
[ NSCursor unhide ];
cursor_visible = YES;
}
[ cursor set ];
}
void QZ_UpdateCursor (_THIS) {
BOOL state;

void QZ_HideMouse (_THIS) {
if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS) && cursor_visible) {
[ NSCursor hide ];
cursor_visible = NO;
if (cursor_should_be_visible || !(SDL_GetAppState() & SDL_APPMOUSEFOCUS)) {
state = YES;
} else {
state = NO;
}
if (state != cursor_visible) {
if (state) {
[ NSCursor unhide ];
} else {
[ NSCursor hide ];
}
cursor_visible = state;
}
}

Expand All @@ -117,18 +117,24 @@ BOOL QZ_IsMouseInWindow (_THIS) {
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;
Expand Down
4 changes: 4 additions & 0 deletions src/video/quartz/SDL_QuartzWindow.h
Expand Up @@ -37,3 +37,7 @@
- (BOOL)windowShouldClose:(id)sender;
@end

/* Subclass of NSView to set cursor rectangle */
@interface SDL_QuartzView : NSView
- (void)resetCursorRects;
@end
13 changes: 13 additions & 0 deletions src/video/quartz/SDL_QuartzWindow.m
Expand Up @@ -22,6 +22,7 @@
#include "SDL_config.h"

#include "SDL_QuartzVideo.h"
#include "SDL_QuartzWM.h"
#include "SDL_QuartzWindow.h"

/*
Expand Down Expand Up @@ -217,3 +218,15 @@ - (void)windowDidResignKey:(NSNotification *)aNotification
}

@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

0 comments on commit 632e5cf

Please sign in to comment.