Mac: Use cursor rects instead of NSCursor hide/unhide.
This should hopefully fix a class of problems around cursor hiding not behaving correctly on Mac.
http://bugzilla.libsdl.org/show_bug.cgi?id=1824
1.1 --- a/src/video/cocoa/SDL_cocoamouse.h Mon May 06 23:02:37 2013 +0200
1.2 +++ b/src/video/cocoa/SDL_cocoamouse.h Tue May 07 16:52:39 2013 -0700
1.3 @@ -35,6 +35,10 @@
1.4 int deltaYOffset;
1.5 } SDL_MouseData;
1.6
1.7 +@interface NSCursor (InvisibleCursor)
1.8 ++ (NSCursor *)invisibleCursor;
1.9 +@end
1.10 +
1.11 #endif /* _SDL_cocoamouse_h */
1.12
1.13 /* vi: set ts=4 sw=4 expandtab: */
2.1 --- a/src/video/cocoa/SDL_cocoamouse.m Mon May 06 23:02:37 2013 +0200
2.2 +++ b/src/video/cocoa/SDL_cocoamouse.m Tue May 07 16:52:39 2013 -0700
2.3 @@ -28,6 +28,32 @@
2.4
2.5 #include "../../events/SDL_mouse_c.h"
2.6
2.7 +@implementation NSCursor (InvisibleCursor)
2.8 ++ (NSCursor *)invisibleCursor
2.9 +{
2.10 + static NSCursor *invisibleCursor = NULL;
2.11 + if (!invisibleCursor) {
2.12 + /* RAW 16x16 transparent GIF */
2.13 + static unsigned char cursorBytes[] = {
2.14 + 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x10, 0x00, 0x10, 0x00, 0x80,
2.15 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xF9, 0x04,
2.16 + 0x01, 0x00, 0x00, 0x01, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x10,
2.17 + 0x00, 0x10, 0x00, 0x00, 0x02, 0x0E, 0x8C, 0x8F, 0xA9, 0xCB, 0xED,
2.18 + 0x0F, 0xA3, 0x9C, 0xB4, 0xDA, 0x8B, 0xB3, 0x3E, 0x05, 0x00, 0x3B
2.19 + };
2.20 +
2.21 + NSData *cursorData = [NSData dataWithBytesNoCopy:&cursorBytes[0]
2.22 + length:sizeof(cursorBytes)
2.23 + freeWhenDone:NO];
2.24 + NSImage *cursorImage = [[[NSImage alloc] initWithData:cursorData] autorelease];
2.25 + invisibleCursor = [[NSCursor alloc] initWithImage:cursorImage
2.26 + hotSpot:NSZeroPoint];
2.27 + }
2.28 +
2.29 + return invisibleCursor;
2.30 +}
2.31 +@end
2.32 +
2.33
2.34 static SDL_Cursor *
2.35 Cocoa_CreateDefaultCursor()
2.36 @@ -153,30 +179,17 @@
2.37 static int
2.38 Cocoa_ShowCursor(SDL_Cursor * cursor)
2.39 {
2.40 - /* We need to track the previous state because hide and unhide calls need to
2.41 - * be matched, but ShowCursor calls don't.
2.42 - */
2.43 - static SDL_bool isShown = SDL_TRUE;
2.44 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
2.45
2.46 - if (cursor) {
2.47 - NSCursor *nscursor = (NSCursor *)cursor->driverdata;
2.48 -
2.49 - /* We're possibly executing from an event handler where this operation
2.50 - * is unsupported. This will execute it in the main Cocoa event loop
2.51 - * after this returns.
2.52 - */
2.53 - [nscursor performSelectorOnMainThread:@selector(set)
2.54 - withObject:nil
2.55 - waitUntilDone:NO];
2.56 -
2.57 - if (!isShown) {
2.58 - [NSCursor unhide];
2.59 - isShown = SDL_TRUE;
2.60 - }
2.61 - } else if (isShown) {
2.62 - [NSCursor hide];
2.63 - isShown = SDL_FALSE;
2.64 + SDL_VideoDevice *device = SDL_GetVideoDevice();
2.65 + SDL_Window *window = (device ? device->windows : NULL);
2.66 + for (; window != NULL; window = window->next) {
2.67 + SDL_WindowData *driverdata = (SDL_WindowData *)window->driverdata;
2.68 + if (driverdata) {
2.69 + [driverdata->nswindow performSelectorOnMainThread:@selector(invalidateCursorRectsForView:)
2.70 + withObject:[driverdata->nswindow contentView]
2.71 + waitUntilDone:NO];
2.72 + }
2.73 }
2.74
2.75 [pool release];
3.1 --- a/src/video/cocoa/SDL_cocoawindow.m Mon May 06 23:02:37 2013 +0200
3.2 +++ b/src/video/cocoa/SDL_cocoawindow.m Tue May 07 16:52:39 2013 -0700
3.3 @@ -254,7 +254,6 @@
3.4
3.5 if (x >= 0 && x < window->w && y >= 0 && y < window->h) {
3.6 SDL_SendMouseMotion(window, 0, 0, x, y);
3.7 - SDL_SetCursor(NULL);
3.8 }
3.9 }
3.10
3.11 @@ -520,6 +519,7 @@
3.12 @end
3.13
3.14 @interface SDLView : NSView
3.15 +
3.16 /* The default implementation doesn't pass rightMouseDown to responder chain */
3.17 - (void)rightMouseDown:(NSEvent *)theEvent;
3.18 @end
3.19 @@ -529,6 +529,20 @@
3.20 {
3.21 [[self nextResponder] rightMouseDown:theEvent];
3.22 }
3.23 +
3.24 +- (void)resetCursorRects
3.25 +{
3.26 + [super resetCursorRects];
3.27 + SDL_Mouse *mouse = SDL_GetMouse();
3.28 +
3.29 + if (mouse->cursor_shown && mouse->cur_cursor) {
3.30 + [self addCursorRect:[self bounds]
3.31 + cursor:mouse->cur_cursor->driverdata];
3.32 + } else {
3.33 + [self addCursorRect:[self bounds]
3.34 + cursor:[NSCursor invisibleCursor]];
3.35 + }
3.36 +}
3.37 @end
3.38
3.39 static unsigned int