Commit 650ace88ca524b6f7139b6048baec0d7ac733bd7

Alex Szpakowski 2014-11-20T17:19:26

Fixed mismatching orientations for the window width and height on iOS when the window is created or the app is brought to the foreground, when SDL_HINT_ORIENTATIONS or SDL_WINDOW_FULLSCREEN is used.

diff --git a/src/video/uikit/SDL_uikitviewcontroller.m b/src/video/uikit/SDL_uikitviewcontroller.m
index 0a9fbab..de5b300 100644
--- a/src/video/uikit/SDL_uikitviewcontroller.m
+++ b/src/video/uikit/SDL_uikitviewcontroller.m
@@ -62,44 +62,7 @@
 
 - (NSUInteger)supportedInterfaceOrientations
 {
-    NSUInteger orientationMask = 0;
-    const char *hint = SDL_GetHint(SDL_HINT_ORIENTATIONS);
-
-    if (hint != NULL) {
-        NSArray *orientations = [@(hint) componentsSeparatedByString:@" "];
-
-        if ([orientations containsObject:@"LandscapeLeft"]) {
-            orientationMask |= UIInterfaceOrientationMaskLandscapeLeft;
-        }
-        if ([orientations containsObject:@"LandscapeRight"]) {
-            orientationMask |= UIInterfaceOrientationMaskLandscapeRight;
-        }
-        if ([orientations containsObject:@"Portrait"]) {
-            orientationMask |= UIInterfaceOrientationMaskPortrait;
-        }
-        if ([orientations containsObject:@"PortraitUpsideDown"]) {
-            orientationMask |= UIInterfaceOrientationMaskPortraitUpsideDown;
-        }
-    }
-
-    if (orientationMask == 0 && (window->flags & SDL_WINDOW_RESIZABLE)) {
-        orientationMask = UIInterfaceOrientationMaskAll;  /* any orientation is okay. */
-    }
-
-    if (orientationMask == 0) {
-        if (window->w >= window->h) {
-            orientationMask |= UIInterfaceOrientationMaskLandscape;
-        }
-        if (window->h >= window->w) {
-            orientationMask |= (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
-        }
-    }
-
-    /* Don't allow upside-down orientation on the phone, so answering calls is in the natural orientation */
-    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
-        orientationMask &= ~UIInterfaceOrientationMaskPortraitUpsideDown;
-    }
-    return orientationMask;
+    return UIKit_GetSupportedOrientations(window);
 }
 
 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient
@@ -119,7 +82,7 @@
 
 - (UIStatusBarStyle)preferredStatusBarStyle
 {
-    /* We assume most games don't have a bright white background. */
+    /* We assume most SDL apps don't have a bright white background. */
     return UIStatusBarStyleLightContent;
 }
 
diff --git a/src/video/uikit/SDL_uikitwindow.h b/src/video/uikit/SDL_uikitwindow.h
index 17e9e1b..c279d0f 100644
--- a/src/video/uikit/SDL_uikitwindow.h
+++ b/src/video/uikit/SDL_uikitwindow.h
@@ -36,6 +36,8 @@ extern void UIKit_DestroyWindow(_THIS, SDL_Window * window);
 extern SDL_bool UIKit_GetWindowWMInfo(_THIS, SDL_Window * window,
                                       struct SDL_SysWMinfo * info);
 
+extern NSUInteger UIKit_GetSupportedOrientations(SDL_Window * window);
+
 @class UIWindow;
 
 @interface SDL_uikitwindow : UIWindow
diff --git a/src/video/uikit/SDL_uikitwindow.m b/src/video/uikit/SDL_uikitwindow.m
index a250ca5..0c2f120 100644
--- a/src/video/uikit/SDL_uikitwindow.m
+++ b/src/video/uikit/SDL_uikitwindow.m
@@ -80,9 +80,6 @@ static int SetupWindowData(_THIS, SDL_Window *window, SDL_uikitwindow *uiwindow,
 
     /* Fill in the SDL window with the window data */
     {
-        window->x = 0;
-        window->y = 0;
-
         CGRect frame = UIKit_ComputeViewFrame(window, displaydata.uiscreen);
 
         /* Get frame dimensions */
@@ -96,6 +93,8 @@ static int SetupWindowData(_THIS, SDL_Window *window, SDL_uikitwindow *uiwindow,
             height = temp;
         }
 
+        window->x = 0;
+        window->y = 0;
         window->w = width;
         window->h = height;
     }
@@ -182,21 +181,32 @@ UIKit_CreateWindow(_THIS, SDL_Window *window)
         }
 
         if (data.uiscreen == [UIScreen mainScreen]) {
+            NSUInteger orientations = UIKit_GetSupportedOrientations(window);
+            UIApplication *app = [UIApplication sharedApplication];
+
             if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
-                [UIApplication sharedApplication].statusBarHidden = YES;
+                app.statusBarHidden = YES;
             } else {
-                [UIApplication sharedApplication].statusBarHidden = NO;
+                app.statusBarHidden = NO;
             }
-        }
 
-        if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
-            if (window->w > window->h) {
-                if (!UIKit_IsDisplayLandscape(data.uiscreen)) {
-                    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
+            /* Make sure the screen is using a supported orientation. We do it
+             * now so that SetupWindowData assigns the properly oriented width
+             * and height to the window's w and h variables.
+             */
+            if (UIKit_IsDisplayLandscape(data.uiscreen)) {
+                if (!(orientations & UIInterfaceOrientationMaskLandscape)) {
+                    [app setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
                 }
-            } else if (window->w < window->h) {
-                if (UIKit_IsDisplayLandscape(data.uiscreen)) {
-                    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
+            } else {
+                if (!(orientations & (UIInterfaceOrientationMaskPortrait|UIInterfaceOrientationMaskPortraitUpsideDown))) {
+                    UIInterfaceOrientation orient = UIInterfaceOrientationLandscapeLeft;
+
+                    if (orientations & UIInterfaceOrientationMaskLandscapeRight) {
+                        orient = UIInterfaceOrientationLandscapeRight;
+                    }
+
+                    [app setStatusBarOrientation:orient animated:NO];
                 }
             }
         }
@@ -228,7 +238,6 @@ UIKit_ShowWindow(_THIS, SDL_Window * window)
 {
     @autoreleasepool {
         UIWindow *uiwindow = ((__bridge SDL_WindowData *) window->driverdata).uiwindow;
-
         [uiwindow makeKeyAndVisible];
     }
 }
@@ -238,7 +247,6 @@ UIKit_HideWindow(_THIS, SDL_Window * window)
 {
     @autoreleasepool {
         UIWindow *uiwindow = ((__bridge SDL_WindowData *) window->driverdata).uiwindow;
-
         uiwindow.hidden = YES;
     }
 }
@@ -341,6 +349,53 @@ UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
     }
 }
 
+NSUInteger
+UIKit_GetSupportedOrientations(SDL_Window * window)
+{
+    const char *hint = SDL_GetHint(SDL_HINT_ORIENTATIONS);
+    NSUInteger orientationMask = 0;
+
+    @autoreleasepool {
+        if (hint != NULL) {
+            NSArray *orientations = [@(hint) componentsSeparatedByString:@" "];
+
+            if ([orientations containsObject:@"LandscapeLeft"]) {
+                orientationMask |= UIInterfaceOrientationMaskLandscapeLeft;
+            }
+            if ([orientations containsObject:@"LandscapeRight"]) {
+                orientationMask |= UIInterfaceOrientationMaskLandscapeRight;
+            }
+            if ([orientations containsObject:@"Portrait"]) {
+                orientationMask |= UIInterfaceOrientationMaskPortrait;
+            }
+            if ([orientations containsObject:@"PortraitUpsideDown"]) {
+                orientationMask |= UIInterfaceOrientationMaskPortraitUpsideDown;
+            }
+        }
+
+        if (orientationMask == 0 && (window->flags & SDL_WINDOW_RESIZABLE)) {
+            /* any orientation is okay. */
+            orientationMask = UIInterfaceOrientationMaskAll;
+        }
+
+        if (orientationMask == 0) {
+            if (window->w >= window->h) {
+                orientationMask |= UIInterfaceOrientationMaskLandscape;
+            }
+            if (window->h >= window->w) {
+                orientationMask |= (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
+            }
+        }
+
+        /* Don't allow upside-down orientation on the phone, so answering calls is in the natural orientation */
+        if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
+            orientationMask &= ~UIInterfaceOrientationMaskPortraitUpsideDown;
+        }
+    }
+
+    return orientationMask;
+}
+
 int
 SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam)
 {