From 650ace88ca524b6f7139b6048baec0d7ac733bd7 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Thu, 20 Nov 2014 17:19:26 -0400 Subject: [PATCH] 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. --- src/video/uikit/SDL_uikitviewcontroller.m | 41 +---------- src/video/uikit/SDL_uikitwindow.h | 2 + src/video/uikit/SDL_uikitwindow.m | 85 +++++++++++++++++++---- 3 files changed, 74 insertions(+), 54 deletions(-) diff --git a/src/video/uikit/SDL_uikitviewcontroller.m b/src/video/uikit/SDL_uikitviewcontroller.m index 0a9fbab4a8158..de5b3008c9642 100644 --- a/src/video/uikit/SDL_uikitviewcontroller.m +++ b/src/video/uikit/SDL_uikitviewcontroller.m @@ -62,44 +62,7 @@ - (void)viewDidLayoutSubviews - (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 @@ - (BOOL)prefersStatusBarHidden - (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 17e9e1bb45dca..c279d0f6f895b 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 a250ca5c7cf82..0c2f12017a828 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 @@ static int SetupWindowData(_THIS, SDL_Window *window, SDL_uikitwindow *uiwindow, } 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 @@ static int SetupWindowData(_THIS, SDL_Window *window, SDL_uikitwindow *uiwindow, { @autoreleasepool { UIWindow *uiwindow = ((__bridge SDL_WindowData *) window->driverdata).uiwindow; - [uiwindow makeKeyAndVisible]; } } @@ -238,7 +247,6 @@ static int SetupWindowData(_THIS, SDL_Window *window, SDL_uikitwindow *uiwindow, { @autoreleasepool { UIWindow *uiwindow = ((__bridge SDL_WindowData *) window->driverdata).uiwindow; - uiwindow.hidden = YES; } } @@ -341,6 +349,53 @@ static int SetupWindowData(_THIS, SDL_Window *window, SDL_uikitwindow *uiwindow, } } +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) {