Commit 75145ea023bc52f667f62625f0b00dcdc71cfb03

Sam Lantinga 2013-11-12T01:52:54

Added a hint SDL_HINT_VIDEO_FULLSCREEN_SPACES to specify that windows go fullscreen into their own spaces on Mac OS X.

diff --git a/include/SDL_hints.h b/include/SDL_hints.h
index 8e561fb..763154f 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 0f0b3e6..2042d07 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 39992a4..44eb969 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 54bb94e..182e634 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: */