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.

This commit is contained in:
Alex Szpakowski 2014-11-20 17:19:26 -04:00
parent 0b02de757d
commit 650ace88ca
3 changed files with 77 additions and 57 deletions

View File

@ -62,44 +62,7 @@
- (NSUInteger)supportedInterfaceOrientations - (NSUInteger)supportedInterfaceOrientations
{ {
NSUInteger orientationMask = 0; return UIKit_GetSupportedOrientations(window);
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;
} }
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient
@ -119,7 +82,7 @@
- (UIStatusBarStyle)preferredStatusBarStyle - (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; return UIStatusBarStyleLightContent;
} }

View File

@ -36,6 +36,8 @@ extern void UIKit_DestroyWindow(_THIS, SDL_Window * window);
extern SDL_bool UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, extern SDL_bool UIKit_GetWindowWMInfo(_THIS, SDL_Window * window,
struct SDL_SysWMinfo * info); struct SDL_SysWMinfo * info);
extern NSUInteger UIKit_GetSupportedOrientations(SDL_Window * window);
@class UIWindow; @class UIWindow;
@interface SDL_uikitwindow : UIWindow @interface SDL_uikitwindow : UIWindow

View File

@ -80,9 +80,6 @@ static int SetupWindowData(_THIS, SDL_Window *window, SDL_uikitwindow *uiwindow,
/* Fill in the SDL window with the window data */ /* Fill in the SDL window with the window data */
{ {
window->x = 0;
window->y = 0;
CGRect frame = UIKit_ComputeViewFrame(window, displaydata.uiscreen); CGRect frame = UIKit_ComputeViewFrame(window, displaydata.uiscreen);
/* Get frame dimensions */ /* Get frame dimensions */
@ -96,6 +93,8 @@ static int SetupWindowData(_THIS, SDL_Window *window, SDL_uikitwindow *uiwindow,
height = temp; height = temp;
} }
window->x = 0;
window->y = 0;
window->w = width; window->w = width;
window->h = height; window->h = height;
} }
@ -182,21 +181,32 @@ UIKit_CreateWindow(_THIS, SDL_Window *window)
} }
if (data.uiscreen == [UIScreen mainScreen]) { if (data.uiscreen == [UIScreen mainScreen]) {
if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) { NSUInteger orientations = UIKit_GetSupportedOrientations(window);
[UIApplication sharedApplication].statusBarHidden = YES; UIApplication *app = [UIApplication sharedApplication];
} else {
[UIApplication sharedApplication].statusBarHidden = NO;
}
}
if (!(window->flags & SDL_WINDOW_RESIZABLE)) { if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
if (window->w > window->h) { app.statusBarHidden = YES;
if (!UIKit_IsDisplayLandscape(data.uiscreen)) { } else {
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO]; app.statusBarHidden = 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) { } else {
if (UIKit_IsDisplayLandscape(data.uiscreen)) { if (!(orientations & (UIInterfaceOrientationMaskPortrait|UIInterfaceOrientationMaskPortraitUpsideDown))) {
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO]; UIInterfaceOrientation orient = UIInterfaceOrientationLandscapeLeft;
if (orientations & UIInterfaceOrientationMaskLandscapeRight) {
orient = UIInterfaceOrientationLandscapeRight;
}
[app setStatusBarOrientation:orient animated:NO];
} }
} }
} }
@ -228,7 +238,6 @@ UIKit_ShowWindow(_THIS, SDL_Window * window)
{ {
@autoreleasepool { @autoreleasepool {
UIWindow *uiwindow = ((__bridge SDL_WindowData *) window->driverdata).uiwindow; UIWindow *uiwindow = ((__bridge SDL_WindowData *) window->driverdata).uiwindow;
[uiwindow makeKeyAndVisible]; [uiwindow makeKeyAndVisible];
} }
} }
@ -238,7 +247,6 @@ UIKit_HideWindow(_THIS, SDL_Window * window)
{ {
@autoreleasepool { @autoreleasepool {
UIWindow *uiwindow = ((__bridge SDL_WindowData *) window->driverdata).uiwindow; UIWindow *uiwindow = ((__bridge SDL_WindowData *) window->driverdata).uiwindow;
uiwindow.hidden = YES; 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 int
SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam) SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam)
{ {