From 31257842ec57b6d99d3329e15d177fe0dd5f6766 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Tue, 29 Jul 2014 00:05:48 -0300 Subject: [PATCH] Added support for SDL_SetWindowBordered on iOS. Worked around a bug with rotating the device on iOS 8. --- include/SDL_hints.h | 2 +- src/video/uikit/SDL_uikitappdelegate.m | 21 ++++--- src/video/uikit/SDL_uikitmessagebox.m | 2 +- src/video/uikit/SDL_uikitvideo.m | 3 +- src/video/uikit/SDL_uikitview.m | 17 ++---- src/video/uikit/SDL_uikitviewcontroller.m | 10 +--- src/video/uikit/SDL_uikitwindow.h | 7 ++- src/video/uikit/SDL_uikitwindow.m | 68 ++++++++++++++++------- 8 files changed, 79 insertions(+), 51 deletions(-) diff --git a/include/SDL_hints.h b/include/SDL_hints.h index 1c46515ed..92f31cdbc 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -346,7 +346,7 @@ extern "C" { /** - * \brief If set to 1, then do not allow high-DPI windows. ("Retina" on Mac) + * \brief If set to 1, then do not allow high-DPI windows. ("Retina" on Mac and iOS) */ #define SDL_HINT_VIDEO_HIGHDPI_DISABLED "SDL_VIDEO_HIGHDPI_DISABLED" diff --git a/src/video/uikit/SDL_uikitappdelegate.m b/src/video/uikit/SDL_uikitappdelegate.m index 8be3790ff..ed01b7077 100644 --- a/src/video/uikit/SDL_uikitappdelegate.m +++ b/src/video/uikit/SDL_uikitappdelegate.m @@ -244,22 +244,29 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa - (void)application:(UIApplication *)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation { - UIInterfaceOrientation orientation = application.statusBarOrientation; + BOOL isLandscape = UIInterfaceOrientationIsLandscape(application.statusBarOrientation); SDL_VideoDevice *_this = SDL_GetVideoDevice(); if (_this && _this->num_displays > 0) { - SDL_VideoDisplay *display = &_this->displays[0]; /* Main screen. */ - SDL_DisplayMode *mode = &display->desktop_mode; + SDL_DisplayMode *desktopmode = &_this->displays[0].desktop_mode; + SDL_DisplayMode *currentmode = &_this->displays[0].current_mode; /* The desktop display mode should be kept in sync with the screen * orientation so that updating a window's fullscreen state to * SDL_WINDOW_FULLSCREEN_DESKTOP keeps the window dimensions in the * correct orientation. */ - if (UIInterfaceOrientationIsLandscape(orientation) != (mode->w > mode->h)) { - int height = mode->w; - mode->w = mode->h; - mode->h = height; + if (isLandscape != (desktopmode->w > desktopmode->h)) { + int height = desktopmode->w; + desktopmode->w = desktopmode->h; + desktopmode->h = height; + } + + /* Same deal with the current mode + SDL_GetCurrentDisplayMode. */ + if (isLandscape != (currentmode->w > currentmode->h)) { + int height = currentmode->w; + currentmode->w = currentmode->h; + currentmode->h = height; } } } diff --git a/src/video/uikit/SDL_uikitmessagebox.m b/src/video/uikit/SDL_uikitmessagebox.m index 4a1d32b7b..1cb734428 100644 --- a/src/video/uikit/SDL_uikitmessagebox.m +++ b/src/video/uikit/SDL_uikitmessagebox.m @@ -32,7 +32,7 @@ static SDL_bool s_showingMessageBox = SDL_FALSE; @interface UIKit_UIAlertViewDelegate : NSObject -- (id)initWithButtonIndex:(int *)_buttonIndex; +- (id)initWithButtonIndex:(int *)buttonIndex; - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex; @end diff --git a/src/video/uikit/SDL_uikitvideo.m b/src/video/uikit/SDL_uikitvideo.m index 01783b248..5d4e81252 100644 --- a/src/video/uikit/SDL_uikitvideo.m +++ b/src/video/uikit/SDL_uikitvideo.m @@ -78,12 +78,11 @@ UIKit_CreateDevice(int devindex) device->ShowWindow = UIKit_ShowWindow; device->HideWindow = UIKit_HideWindow; device->RaiseWindow = UIKit_RaiseWindow; + device->SetWindowBordered = UIKit_SetWindowBordered; device->SetWindowFullscreen = UIKit_SetWindowFullscreen; device->DestroyWindow = UIKit_DestroyWindow; device->GetWindowWMInfo = UIKit_GetWindowWMInfo; - /* !!! FIXME: implement SetWindowBordered */ - #if SDL_IPHONE_KEYBOARD device->HasScreenKeyboardSupport = UIKit_HasScreenKeyboardSupport; device->ShowScreenKeyboard = UIKit_ShowScreenKeyboard; diff --git a/src/video/uikit/SDL_uikitview.m b/src/video/uikit/SDL_uikitview.m index 3a2676e17..620ea2864 100644 --- a/src/video/uikit/SDL_uikitview.m +++ b/src/video/uikit/SDL_uikitview.m @@ -51,23 +51,18 @@ void _uikit_keyboard_init(); } -- (void)dealloc -{ - [super dealloc]; -} - - (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame: frame]; - + if (self = [super initWithFrame: frame]) { #if SDL_IPHONE_KEYBOARD - [self initializeKeyboard]; + [self initializeKeyboard]; #endif - self.multipleTouchEnabled = YES; + self.multipleTouchEnabled = YES; - touchId = 1; - SDL_AddTouch(touchId, ""); + touchId = 1; + SDL_AddTouch(touchId, ""); + } return self; diff --git a/src/video/uikit/SDL_uikitviewcontroller.m b/src/video/uikit/SDL_uikitviewcontroller.m index c7b3d0934..9e5b02616 100644 --- a/src/video/uikit/SDL_uikitviewcontroller.m +++ b/src/video/uikit/SDL_uikitviewcontroller.m @@ -40,12 +40,9 @@ - (id)initWithSDLWindow:(SDL_Window *)_window { - self = [self init]; - if (self == nil) { - return nil; + if (self = [super initWithNibName:nil bundle:nil]) { + self.window = _window; } - self.window = _window; - return self; } @@ -56,8 +53,7 @@ - (void)viewDidLayoutSubviews { - SDL_WindowData *data = window->driverdata; - const CGSize size = data->view.bounds.size; + const CGSize size = self.view.bounds.size; int w = (int) size.width; int h = (int) size.height; diff --git a/src/video/uikit/SDL_uikitwindow.h b/src/video/uikit/SDL_uikitwindow.h index 494b028f3..f6d67f00a 100644 --- a/src/video/uikit/SDL_uikitwindow.h +++ b/src/video/uikit/SDL_uikitwindow.h @@ -32,6 +32,7 @@ extern int UIKit_CreateWindow(_THIS, SDL_Window * window); extern void UIKit_ShowWindow(_THIS, SDL_Window * window); extern void UIKit_HideWindow(_THIS, SDL_Window * window); extern void UIKit_RaiseWindow(_THIS, SDL_Window * window); +extern void UIKit_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); extern void UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern void UIKit_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, @@ -39,9 +40,13 @@ extern SDL_bool UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, @class UIWindow; +@interface SDL_uikitwindow : UIWindow + +@end + struct SDL_WindowData { - UIWindow *uiwindow; + SDL_uikitwindow *uiwindow; SDL_uikitopenglview *view; SDL_uikitviewcontroller *viewcontroller; }; diff --git a/src/video/uikit/SDL_uikitwindow.m b/src/video/uikit/SDL_uikitwindow.m index 02dafd6d9..7e3fac621 100644 --- a/src/video/uikit/SDL_uikitwindow.m +++ b/src/video/uikit/SDL_uikitwindow.m @@ -41,8 +41,23 @@ #include +@implementation SDL_uikitwindow -static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bool created) +- (void)layoutSubviews +{ + [super layoutSubviews]; + + /* This seems to be needed on iOS 8, otherwise the window's frame is put in + * an unexpected position when the screen or device is rotated. + * FIXME: is there a better solution to that problem than this ugly hack? + */ + self.frame = self.screen.bounds; +} + +@end + + +static int SetupWindowData(_THIS, SDL_Window *window, SDL_uikitwindow *uiwindow, SDL_bool created) { SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata; @@ -181,7 +196,7 @@ UIKit_CreateWindow(_THIS, SDL_Window *window) /* ignore the size user requested, and make a fullscreen window */ /* !!! FIXME: can we have a smaller view? */ - UIWindow *uiwindow = [[UIWindow alloc] initWithFrame:[data->uiscreen bounds]]; + SDL_uikitwindow *uiwindow = [[SDL_uikitwindow alloc] initWithFrame:data->uiscreen.bounds]; /* put the window on an external display if appropriate. This implicitly * does [uiwindow setframe:[uiscreen bounds]], so don't do it on the @@ -198,7 +213,6 @@ UIKit_CreateWindow(_THIS, SDL_Window *window) } return 1; - } void @@ -228,47 +242,59 @@ UIKit_RaiseWindow(_THIS, SDL_Window * window) _this->GL_MakeCurrent(_this, _this->current_glwin, _this->current_glctx); } -void -UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen) +static void +UIKit_UpdateWindowBorder(_THIS, SDL_Window * window) { - SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata; SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; SDL_uikitviewcontroller *viewcontroller = windowdata->viewcontroller; CGRect frame; - if (fullscreen || (window->flags & SDL_WINDOW_BORDERLESS)) { - [UIApplication sharedApplication].statusBarHidden = YES; - } else { - [UIApplication sharedApplication].statusBarHidden = NO; - } + if (windowdata->uiwindow.screen == [UIScreen mainScreen]) { + if (window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS)) { + [UIApplication sharedApplication].statusBarHidden = YES; + } else { + [UIApplication sharedApplication].statusBarHidden = NO; + } - /* iOS 7+ won't update the status bar until we tell it to. */ - if ([viewcontroller respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) { - [viewcontroller setNeedsStatusBarAppearanceUpdate]; + /* iOS 7+ won't update the status bar until we tell it to. */ + if ([viewcontroller respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) { + [viewcontroller setNeedsStatusBarAppearanceUpdate]; + } } /* Update the view's frame to account for the status bar change. */ - frame = UIKit_ComputeViewFrame(window, displaydata->uiscreen); + frame = UIKit_ComputeViewFrame(window, windowdata->uiwindow.screen); + windowdata->view.frame = frame; [windowdata->view setNeedsLayout]; [windowdata->view layoutIfNeeded]; /* Get frame dimensions */ - int width = (int) frame.size.width; + int width = (int) frame.size.width; int height = (int) frame.size.height; /* We can pick either width or height here and we'll rotate the - screen to match, so we pick the closest to what we wanted. + screen to match, so we pick the closest to what we wanted. */ if (window->w >= window->h) { - window->w = SDL_max(width, height); - window->h = SDL_min(width, height); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, SDL_max(width, height), SDL_min(width, height)); } else { - window->w = SDL_min(width, height); - window->h = SDL_max(width, height); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, SDL_min(width, height), SDL_max(width, height)); } } +void +UIKit_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) +{ + UIKit_UpdateWindowBorder(_this, window); +} + +void +UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen) +{ + UIKit_UpdateWindowBorder(_this, window); +} + void UIKit_DestroyWindow(_THIS, SDL_Window * window) {