Commit c6538cb977c693927f5d055794b03b897f366132

Ryan C. Gordon 2015-04-12T20:28:28

Merged.

diff --git a/src/video/uikit/SDL_uikitappdelegate.m b/src/video/uikit/SDL_uikitappdelegate.m
index 2ae6182..19f510e 100644
--- a/src/video/uikit/SDL_uikitappdelegate.m
+++ b/src/video/uikit/SDL_uikitappdelegate.m
@@ -115,9 +115,7 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
     return image;
 }
 
-@implementation SDLLaunchScreenController {
-    UIInterfaceOrientationMask supportedOrientations;
-}
+@implementation SDLLaunchScreenController
 
 - (instancetype)init
 {
@@ -127,18 +125,16 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
 
     NSBundle *bundle = [NSBundle mainBundle];
     NSString *screenname = [bundle objectForInfoDictionaryKey:@"UILaunchStoryboardName"];
-
-    /* Normally we don't want to rotate from the initial orientation. */
-    supportedOrientations = (1 << [UIApplication sharedApplication].statusBarOrientation);
+    BOOL atleastiOS8 = UIKit_IsSystemVersionAtLeast(8.0);
 
     /* Launch screens were added in iOS 8. Otherwise we use launch images. */
-    if (screenname && UIKit_IsSystemVersionAtLeast(8.0)) {
+    if (screenname && atleastiOS8) {
         @try {
             self.view = [bundle loadNibNamed:screenname owner:self options:nil][0];
         }
         @catch (NSException *exception) {
-            /* iOS displays a blank screen rather than falling back to an image,
-             * if a launch screen name is specified but it fails to load. */
+            /* If a launch screen name is specified but it fails to load, iOS
+             * displays a blank screen rather than falling back to an image. */
             return nil;
         }
     }
@@ -216,13 +212,37 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
         }
 
         if (image) {
-            if (image.size.width > image.size.height) {
-                supportedOrientations = UIInterfaceOrientationMaskLandscape;
-            } else {
-                supportedOrientations = UIInterfaceOrientationMaskPortrait;
+            UIImageView *view = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];
+            UIImageOrientation imageorient = UIImageOrientationUp;
+
+            /* Bugs observed / workaround tested in iOS 8.3, 7.1, and 6.1. */
+            if (UIInterfaceOrientationIsLandscape(curorient)) {
+                if (atleastiOS8 && image.size.width < image.size.height) {
+                    /* On iOS 8, portrait launch images displayed in forced-
+                     * landscape mode (e.g. a standard Default.png on an iPhone
+                     * when Info.plist only supports landscape orientations) need
+                     * to be rotated to display in the expected orientation. */
+                    if (curorient == UIInterfaceOrientationLandscapeLeft) {
+                        imageorient = UIImageOrientationRight;
+                    } else if (curorient == UIInterfaceOrientationLandscapeRight) {
+                        imageorient = UIImageOrientationLeft;
+                    }
+                } else if (!atleastiOS8 && image.size.width > image.size.height) {
+                    /* On iOS 7 and below, landscape launch images displayed in
+                     * landscape mode (e.g. landscape iPad launch images) need
+                     * to be rotated to display in the expected orientation. */
+                    if (curorient == UIInterfaceOrientationLandscapeLeft) {
+                        imageorient = UIImageOrientationLeft;
+                    } else if (curorient == UIInterfaceOrientationLandscapeRight) {
+                        imageorient = UIImageOrientationRight;
+                    }
+                }
             }
 
-            self.view = [[UIImageView alloc] initWithImage:image];
+            /* Create the properly oriented image. */
+            view.image = [[UIImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:imageorient];
+
+            self.view = view;
         }
     }
 
@@ -234,9 +254,18 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
     /* Do nothing. */
 }
 
+- (BOOL)shouldAutorotate
+{
+    /* If YES, the launch image will be incorrectly rotated in some cases. */
+    return NO;
+}
+
 - (NSUInteger)supportedInterfaceOrientations
 {
-    return supportedOrientations;
+    /* We keep the supported orientations unrestricted to avoid the case where
+     * there are no common orientations between the ones set in Info.plist and
+     * the ones set here (it will cause an exception in that case.) */
+    return UIInterfaceOrientationMaskAll;
 }
 
 @end
diff --git a/src/video/uikit/SDL_uikitview.m b/src/video/uikit/SDL_uikitview.m
index 8bd1f31..84d98fe 100644
--- a/src/video/uikit/SDL_uikitview.m
+++ b/src/video/uikit/SDL_uikitview.m
@@ -77,11 +77,8 @@
 
         data.viewcontroller.view = view;
 
-        if (data.uiwindow.rootViewController != data.viewcontroller) {
-            data.uiwindow.rootViewController = data.viewcontroller;
-        } else if (view) {
-            [data.uiwindow addSubview:view];
-        }
+        data.uiwindow.rootViewController = nil;
+        data.uiwindow.rootViewController = data.viewcontroller;
 
         [data.uiwindow layoutIfNeeded];
     }
@@ -96,13 +93,13 @@
         [data.viewcontroller.view removeFromSuperview];
         data.viewcontroller.view = self;
 
-        if (data.uiwindow.rootViewController != data.viewcontroller) {
-            /* The root view controller handles rotation and the status bar.
-             * Assigning it also adds the controller's view to the window. */
-            data.uiwindow.rootViewController = data.viewcontroller;
-        } else {
-            [data.uiwindow addSubview:self];
-        }
+        /* The root view controller handles rotation and the status bar.
+         * Assigning it also adds the controller's view to the window. We
+         * explicitly re-set it to make sure the view is properly attached to
+         * the window. Just adding the sub-view if the root view controller is
+         * already correct causes orientation issues on iOS 7 and below. */
+        data.uiwindow.rootViewController = nil;
+        data.uiwindow.rootViewController = data.viewcontroller;
 
         /* The view's bounds may not be correct until the next event cycle. That
          * might happen after the current dimensions are queried, so we force a