SDL: Workaround for views being in portrait instead of landscape mode on iOS 16

From a40b7cde10e434f861ae5683a4619efbad6210b7 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Mon, 14 Nov 2022 13:03:52 -0800
Subject: [PATCH] Workaround for views being in portrait instead of landscape
 mode on iOS 16

Fixes https://github.com/libsdl-org/SDL/issues/6289
---
 src/video/uikit/SDL_uikitmetalview.m | 12 ++++++++++++
 src/video/uikit/SDL_uikitview.h      |  2 ++
 src/video/uikit/SDL_uikitview.m      | 25 ++++++++++++++++++++++++-
 3 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/src/video/uikit/SDL_uikitmetalview.m b/src/video/uikit/SDL_uikitmetalview.m
index 8bc3380955e8..af6eb0cd3ebe 100644
--- a/src/video/uikit/SDL_uikitmetalview.m
+++ b/src/video/uikit/SDL_uikitmetalview.m
@@ -69,6 +69,18 @@ - (void)updateDrawableSize
     CGSize size = self.bounds.size;
     size.width *= self.layer.contentsScale;
     size.height *= self.layer.contentsScale;
+
+    /* Make sure the width/height are oriented correctly
+     *
+     * This works around an issue in iOS 16 where the bounds come back in portrait mode
+     * instead of landscape until the event loop runs.
+     */
+    if ([self shouldSwapDimensions:(size.width >= size.height)]) {
+        CGFloat temp = size.width;
+        size.width = size.height;
+        size.height = temp;
+    }
+
     ((CAMetalLayer *)self.layer).drawableSize = size;
 }
 
diff --git a/src/video/uikit/SDL_uikitview.h b/src/video/uikit/SDL_uikitview.h
index dcd63c7a5645..5369bb212455 100644
--- a/src/video/uikit/SDL_uikitview.h
+++ b/src/video/uikit/SDL_uikitview.h
@@ -35,6 +35,8 @@
 
 - (void)setSDLWindow:(SDL_Window *)window;
 
+- (BOOL)shouldSwapDimensions:(BOOL)portrait;
+
 #if !TARGET_OS_TV && defined(__IPHONE_13_4)
 - (UIPointerRegion *)pointerInteraction:(UIPointerInteraction *)interaction regionForRequest:(UIPointerRegionRequest *)request defaultRegion:(UIPointerRegion *)defaultRegion API_AVAILABLE(ios(13.4));
 - (UIPointerStyle *)pointerInteraction:(UIPointerInteraction *)interaction styleForRegion:(UIPointerRegion *)region  API_AVAILABLE(ios(13.4));
diff --git a/src/video/uikit/SDL_uikitview.m b/src/video/uikit/SDL_uikitview.m
index 8c48cfa503b9..50d7393e7f30 100644
--- a/src/video/uikit/SDL_uikitview.m
+++ b/src/video/uikit/SDL_uikitview.m
@@ -120,6 +120,8 @@ - (void)setSDLWindow:(SDL_Window *)window
         [data.uiwindow layoutIfNeeded];
     }
 
+    sdlwindow = window;
+
     /* Add ourself to the new window. */
     if (window) {
         data = (__bridge SDL_WindowData *) window->driverdata;
@@ -144,8 +146,29 @@ - (void)setSDLWindow:(SDL_Window *)window
          * layout now to immediately update the bounds. */
         [data.uiwindow layoutIfNeeded];
     }
+}
 
-    sdlwindow = window;
+- (BOOL)shouldSwapDimensions:(BOOL)landscape
+{
+#if !TARGET_OS_TV
+    if (sdlwindow) {
+        SDL_VideoDisplay *display = SDL_GetDisplayForWindow(sdlwindow);
+        SDL_DisplayData *displaydata = (__bridge SDL_DisplayData *) display->driverdata;
+
+        if (displaydata.uiscreen == [UIScreen mainScreen]) {
+            NSUInteger orients = UIKit_GetSupportedOrientations(sdlwindow);
+            BOOL supportsLandscape = (orients & UIInterfaceOrientationMaskLandscape) != 0;
+            BOOL supportsPortrait = (orients & (UIInterfaceOrientationMaskPortrait|UIInterfaceOrientationMaskPortraitUpsideDown)) != 0;
+
+            /* Make sure the width/height are oriented correctly */
+            if ((landscape && !supportsLandscape) || (!landscape && !supportsPortrait)) {
+                return YES;
+            }
+        }
+    }
+#endif /* !TARGET_OS_TV */
+
+    return NO;
 }
 
 #if !TARGET_OS_TV && defined(__IPHONE_13_4)