From 75145ea023bc52f667f62625f0b00dcdc71cfb03 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 12 Nov 2013 01:52:54 -0800 Subject: [PATCH] Added a hint SDL_HINT_VIDEO_FULLSCREEN_SPACES to specify that windows go fullscreen into their own spaces on Mac OS X. --- include/SDL_hints.h | 10 ++++ src/video/SDL_video.c | 17 +++++- src/video/cocoa/SDL_cocoawindow.h | 3 +- src/video/cocoa/SDL_cocoawindow.m | 92 +++++++++++++++---------------- 4 files changed, 72 insertions(+), 50 deletions(-) diff --git a/include/SDL_hints.h b/include/SDL_hints.h index 8e561fb31..763154f3a 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -178,6 +178,16 @@ extern "C" { */ #define SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS "SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS" +/** + * \brief Set whether windows go fullscreen in their own spaces on Mac OS X + * + * This variable can be set to the following values: + * "0" - Fullscreen windows will use the classic fullscreen mode + * "1" - Fullscreen windows will use fullscreen spaces + * + * By default SDL will use the classic fullscreen mode. + */ +#define SDL_HINT_VIDEO_FULLSCREEN_SPACES "SDL_VIDEO_FULLSCREEN_SPACES" /** * \brief A variable controlling whether the idle timer is disabled on iOS. diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 0f0b3e6f7..2042d07e1 100755 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -112,6 +112,13 @@ static SDL_VideoDevice *_this = NULL; return retval; \ } + +#ifdef __MACOSX__ +/* Support for Mac OS X fullscreen spaces */ +extern SDL_bool Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state); +#endif + + /* Support for framebuffer emulation using an accelerated renderer */ #define SDL_WINDOWTEXTUREDATA "_SDL_WindowTextureData" @@ -1080,9 +1087,17 @@ SDL_RestoreMousePosition(SDL_Window *window) static void SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen) { - SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); + SDL_VideoDisplay *display; SDL_Window *other; +#ifdef __MACOSX__ + if (Cocoa_SetWindowFullscreenSpace(window, fullscreen)) { + return; + } +#endif + + display = SDL_GetDisplayForWindow(window); + if (fullscreen) { /* Hide any other fullscreen windows */ if (display->fullscreen_window && diff --git a/src/video/cocoa/SDL_cocoawindow.h b/src/video/cocoa/SDL_cocoawindow.h index 39992a4bd..44eb96936 100644 --- a/src/video/cocoa/SDL_cocoawindow.h +++ b/src/video/cocoa/SDL_cocoawindow.h @@ -49,7 +49,8 @@ typedef enum -(void) pauseVisibleObservation; -(void) resumeVisibleObservation; -(BOOL) setFullscreenSpace:(BOOL) state; --(BOOL) isInFullscreenTransition; +-(BOOL) isInFullscreenSpace; +-(BOOL) isInFullscreenSpaceTransition; -(void) addPendingWindowOperation:(PendingWindowOperation) operation; -(void) close; diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index 54bb94e29..182e634e5 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -189,9 +189,7 @@ GetWindowStyle(SDL_Window * window) #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 SDL_Window *window = _data->window; NSWindow *nswindow = _data->nswindow; - BOOL canSetSpace = NO; - /* Make sure the window supports switching to fullscreen spaces */ if (![nswindow respondsToSelector: @selector(collectionBehavior)]) { return NO; } @@ -199,22 +197,6 @@ GetWindowStyle(SDL_Window * window) return NO; } - pendingWindowOperation = PENDING_OPERATION_NONE; - - /* We can enter fullscreen spaces for "fullscreen desktop" */ - if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { - canSetSpace = YES; - } - - /* We can always leave fullscreen spaces */ - if (!state && isFullscreenSpace) { - canSetSpace = YES; - } - - if (!canSetSpace) { - return NO; - } - if (state == isFullscreenSpace) { return YES; } @@ -227,6 +209,14 @@ GetWindowStyle(SDL_Window * window) } return YES; } + inFullscreenTransition = YES; + + /* Update the flags here so the state change is available immediately */ + if (state) { + window->flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; + } else { + window->flags &= ~SDL_WINDOW_FULLSCREEN_DESKTOP; + } [nswindow performSelectorOnMainThread: @selector(toggleFullScreen:) withObject:nswindow waitUntilDone:NO]; return YES; @@ -235,7 +225,12 @@ GetWindowStyle(SDL_Window * window) #endif /* SDK >= 10.7 */ } --(BOOL) isInFullscreenTransition +-(BOOL) isInFullscreenSpace +{ + return isFullscreenSpace; +} + +-(BOOL) isInFullscreenSpaceTransition { return inFullscreenTransition; } @@ -429,13 +424,8 @@ GetWindowStyle(SDL_Window * window) SDL_Window *window = _data->window; NSWindow *nswindow = _data->nswindow; - if (!(window->flags & SDL_WINDOW_RESIZABLE)) { - if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { - [nswindow setStyleMask:(NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask)]; - } else { - [nswindow setStyleMask:NSBorderlessWindowMask]; - } - } + window->flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; + [nswindow setStyleMask:(NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask)]; isFullscreenSpace = YES; inFullscreenTransition = YES; @@ -444,7 +434,6 @@ GetWindowStyle(SDL_Window * window) - (void)windowDidEnterFullScreen:(NSNotification *)aNotification { SDL_Window *window = _data->window; - NSWindow *nswindow = _data->nswindow; inFullscreenTransition = NO; @@ -467,12 +456,8 @@ GetWindowStyle(SDL_Window * window) SDL_Window *window = _data->window; NSWindow *nswindow = _data->nswindow; - if (!(window->flags & SDL_WINDOW_RESIZABLE)) { - Uint32 flags = window->flags; - window->flags &= ~SDL_WINDOW_FULLSCREEN_DESKTOP; - [nswindow setStyleMask:GetWindowStyle(window)]; - window->flags = flags; - } + window->flags &= ~SDL_WINDOW_FULLSCREEN_DESKTOP; + [nswindow setStyleMask:GetWindowStyle(window)]; isFullscreenSpace = NO; inFullscreenTransition = YES; @@ -925,7 +910,10 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window) [nswindow setBackgroundColor:[NSColor blackColor]]; #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 if ([nswindow respondsToSelector:@selector(setCollectionBehavior:)]) { - [nswindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; + const char *hint = SDL_GetHint(SDL_HINT_VIDEO_FULLSCREEN_SPACES); + if (hint && SDL_atoi(hint) > 0) { + [nswindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; + } } #endif @@ -1139,7 +1127,7 @@ Cocoa_MinimizeWindow(_THIS, SDL_Window * window) SDL_WindowData *data = (SDL_WindowData *) window->driverdata; NSWindow *nswindow = data->nswindow; - if ([data->listener isInFullscreenTransition]) { + if ([data->listener isInFullscreenSpaceTransition]) { [data->listener addPendingWindowOperation:PENDING_OPERATION_MINIMIZE]; } else { [nswindow miniaturize:nil]; @@ -1196,9 +1184,10 @@ Cocoa_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) } -static void -Cocoa_SetWindowFullscreen_OldStyle(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen) +void +Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; SDL_WindowData *data = (SDL_WindowData *) window->driverdata; NSWindow *nswindow = data->nswindow; NSRect rect; @@ -1272,17 +1261,6 @@ Cocoa_SetWindowFullscreen_OldStyle(_THIS, SDL_Window * window, SDL_VideoDisplay } ScheduleContextUpdates(data); -} - -void -Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - - if (![data->listener setFullscreenSpace:(fullscreen ? YES : NO)]) { - Cocoa_SetWindowFullscreen_OldStyle(_this, window, display, fullscreen); - } [pool release]; } @@ -1404,6 +1382,24 @@ Cocoa_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) } } +SDL_bool +Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state) +{ + SDL_bool succeeded = SDL_FALSE; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + + if ([data->listener setFullscreenSpace:(state ? YES : NO)]) { + succeeded = SDL_TRUE; + } + + [pool release]; +#endif /* SDK 10.7+ */ + + return succeeded; +} + #endif /* SDL_VIDEO_DRIVER_COCOA */ /* vi: set ts=4 sw=4 expandtab: */