SDL OSX implementation must account for the fact that going fullscreen can fail. improve the logic around retrying, make a few attempts before failing.
authorSam Lantinga <slouken@libsdl.org>
Mon, 09 Nov 2015 08:54:49 -0800
changeset 9904 e9b49510e51b
parent 9903 2bbb11de1e60
child 9905 fcf85090f816
SDL OSX implementation must account for the fact that going fullscreen can fail. improve the logic around retrying, make a few attempts before failing.
src/video/SDL_video.c
src/video/cocoa/SDL_cocoawindow.m
--- a/src/video/SDL_video.c	Mon Nov 09 08:54:42 2015 -0800
+++ b/src/video/SDL_video.c	Mon Nov 09 08:54:49 2015 -0800
@@ -1140,7 +1140,9 @@
 #ifdef __MACOSX__
     /* If we're switching between a fullscreen Space and "normal" fullscreen, we need to get back to normal first. */
     if (fullscreen && ((window->last_fullscreen_flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN_DESKTOP) && ((window->flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN)) {
-        Cocoa_SetWindowFullscreenSpace(window, SDL_FALSE);
+        if (!Cocoa_SetWindowFullscreenSpace(window, SDL_FALSE)) {
+            return -1;
+        }
     } else if (fullscreen && ((window->last_fullscreen_flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN) && ((window->flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN_DESKTOP)) {
         display = SDL_GetDisplayForWindow(window);
         SDL_SetDisplayModeForDisplay(display, NULL);
@@ -1150,6 +1152,9 @@
     }
 
     if (Cocoa_SetWindowFullscreenSpace(window, fullscreen)) {
+        if (Cocoa_IsWindowInFullscreenSpace(window) != fullscreen) {
+            return -1;
+        }
         window->last_fullscreen_flags = window->flags;
         return 0;
     }
--- a/src/video/cocoa/SDL_cocoawindow.m	Mon Nov 09 08:54:42 2015 -0800
+++ b/src/video/cocoa/SDL_cocoawindow.m	Mon Nov 09 08:54:49 2015 -0800
@@ -646,9 +646,6 @@
 
     isFullscreenSpace = NO;
     inFullscreenTransition = NO;
-
-    /* Try again? Not sure what else to do, the application wants to be fullscreen. */
-    [self setFullscreenSpace:YES];
 }
 
 - (void)windowDidEnterFullScreen:(NSNotification *)aNotification
@@ -693,9 +690,6 @@
     
     isFullscreenSpace = YES;
     inFullscreenTransition = NO;
-
-    /* Try again? Not sure what else to do, the application wants to be non-fullscreen. */
-    [self setFullscreenSpace:NO];
 }
 
 - (void)windowDidExitFullScreen:(NSNotification *)aNotification
@@ -1704,21 +1698,30 @@
     SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
 
     if ([data->listener setFullscreenSpace:(state ? YES : NO)]) {
+        const int maxattempts = 3;
+        int attempt = 0;
+        while (++attempt <= maxattempts) {
+            /* Wait for the transition to complete, so application changes
+             take effect properly (e.g. setting the window size, etc.)
+             */
+            const int limit = 10000;
+            int count = 0;
+            while ([data->listener isInFullscreenSpaceTransition]) {
+                if ( ++count == limit ) {
+                    /* Uh oh, transition isn't completing. Should we assert? */
+                    break;
+                }
+                SDL_Delay(1);
+                SDL_PumpEvents();
+            }
+            if ([data->listener isInFullscreenSpace] == (state ? YES : NO))
+                break;
+            /* Try again, the last attempt was interrupted by user gestures */
+            if (![data->listener setFullscreenSpace:(state ? YES : NO)])
+                break; /* ??? */
+        }
+        /* Return TRUE to prevent non-space fullscreen logic from running */
         succeeded = SDL_TRUE;
-
-        /* Wait for the transition to complete, so application changes
-           take effect properly (e.g. setting the window size, etc.)
-         */
-        const int limit = 10000;
-        int count = 0;
-        while ([data->listener isInFullscreenSpaceTransition]) {
-            if ( ++count == limit ) {
-                /* Uh oh, transition isn't completing. Should we assert? */
-                break;
-            }
-            SDL_Delay(1);
-            SDL_PumpEvents();
-        }
     }
 
     return succeeded;