From 85c34e9a39c6351301c6ec7dde6d0319a25feaba Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 1 Feb 2018 15:21:01 -0800 Subject: [PATCH] Added SDL_HINT_IOS_HIDE_HOME_INDICATOR to determine how the home indicator on the iPhone X is handled. This variable can be set to the following values: "0" - The indicator bar is not hidden (default for windowed applications) "1" - The indicator bar is hidden and is shown when the screen is touched (useful for movie playback applications) "2" - The indicator bar is dim and the first swipe makes it visible and the second swipe performs the "home" action (default for fullscreen applications) --- include/SDL_hints.h | 13 +++++- src/video/uikit/SDL_uikitmessagebox.m | 12 +++++ src/video/uikit/SDL_uikitviewcontroller.h | 4 ++ src/video/uikit/SDL_uikitviewcontroller.m | 57 ++++++++++++++++++++++- 4 files changed, 84 insertions(+), 2 deletions(-) diff --git a/include/SDL_hints.h b/include/SDL_hints.h index e9a0e7c874fff..8c0d72204a7a2 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -365,6 +365,17 @@ extern "C" { */ #define SDL_HINT_APPLE_TV_REMOTE_SWIPES_AS_ARROW_KEYS "SDL_APPLE_TV_REMOTE_SWIPES_AS_ARROW_KEYS" +/** + * \brief A variable controlling whether the home indicator bar on iPhone X + * should be hidden. + * + * This variable can be set to the following values: + * "0" - The indicator bar is not hidden (default for windowed applications) + * "1" - The indicator bar is hidden and is shown when the screen is touched (useful for movie playback applications) + * "2" - The indicator bar is dim and the first swipe makes it visible and the second swipe performs the "home" action (default for fullscreen applications) + */ +#define SDL_HINT_IOS_HIDE_HOME_INDICATOR "SDL_IOS_HIDE_HOME_INDICATOR" + /** * \brief A variable controlling whether the Android / iOS built-in * accelerometer should be listed as a joystick device, rather than listing @@ -775,7 +786,7 @@ extern "C" { * "0" - SDL will generate a window-close event when it sees Alt+F4. * "1" - SDL will only do normal key handling for Alt+F4. */ -#define SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4 "SDL_WINDOWS_NO_CLOSE_ON_ALT_F4" +#define SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4 "SDL_WINDOWS_NO_CLOSE_ON_ALT_F4" /** * \brief Prevent SDL from using version 4 of the bitmap header when saving BMPs. diff --git a/src/video/uikit/SDL_uikitmessagebox.m b/src/video/uikit/SDL_uikitmessagebox.m index d97ff25040b78..7950c8e69c635 100644 --- a/src/video/uikit/SDL_uikitmessagebox.m +++ b/src/video/uikit/SDL_uikitmessagebox.m @@ -109,6 +109,18 @@ alertwindow.hidden = YES; } + /* Force the main SDL window to re-evaluate home indicator state */ + SDL_Window *focus = SDL_GetFocusWindow(); + if (focus) { + SDL_WindowData *data = (__bridge SDL_WindowData *) focus->driverdata; + if (data != nil) { + if (@available(iOS 11.0, *)) { + [data.viewcontroller performSelectorOnMainThread:@selector(setNeedsUpdateOfHomeIndicatorAutoHidden) withObject:nil waitUntilDone:NO]; + [data.viewcontroller performSelectorOnMainThread:@selector(setNeedsUpdateOfScreenEdgesDeferringSystemGestures) withObject:nil waitUntilDone:NO]; + } + } + } + *buttonid = messageboxdata->buttons[clickedindex].buttonid; return YES; #else diff --git a/src/video/uikit/SDL_uikitviewcontroller.h b/src/video/uikit/SDL_uikitviewcontroller.h index 47b17400473ce..fffb142230d4a 100644 --- a/src/video/uikit/SDL_uikitviewcontroller.h +++ b/src/video/uikit/SDL_uikitviewcontroller.h @@ -58,6 +58,10 @@ #if !TARGET_OS_TV - (NSUInteger)supportedInterfaceOrientations; - (BOOL)prefersStatusBarHidden; +- (BOOL)prefersHomeIndicatorAutoHidden; +- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures; + +@property (nonatomic, assign) int homeIndicatorHidden; #endif #if SDL_IPHONE_KEYBOARD diff --git a/src/video/uikit/SDL_uikitviewcontroller.m b/src/video/uikit/SDL_uikitviewcontroller.m index eb8130d00271b..9ee70e8ea9e98 100644 --- a/src/video/uikit/SDL_uikitviewcontroller.m +++ b/src/video/uikit/SDL_uikitviewcontroller.m @@ -50,6 +50,21 @@ } #endif +#if !TARGET_OS_TV +static void SDLCALL +SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + @autoreleasepool { + SDL_uikitviewcontroller *viewcontroller = (__bridge SDL_uikitviewcontroller *) userdata; + viewcontroller.homeIndicatorHidden = (hint && *hint) ? SDL_atoi(hint) : -1; + if (@available(iOS 11.0, *)) { + [viewcontroller setNeedsUpdateOfHomeIndicatorAutoHidden]; + [viewcontroller setNeedsUpdateOfScreenEdgesDeferringSystemGestures]; + } + } +} +#endif + @implementation SDL_uikitviewcontroller { CADisplayLink *displayLink; int animationInterval; @@ -79,7 +94,13 @@ - (instancetype)initWithSDLWindow:(SDL_Window *)_window SDL_AppleTVControllerUIHintChanged, (__bridge void *) self); #endif + +#if !TARGET_OS_TV + SDL_AddHintCallback(SDL_HINT_IOS_HIDE_HOME_INDICATOR, + SDL_HideHomeIndicatorHintChanged, + (__bridge void *) self); } +#endif return self; } @@ -94,6 +115,12 @@ - (void)dealloc SDL_AppleTVControllerUIHintChanged, (__bridge void *) self); #endif + +#if !TARGET_OS_TV + SDL_DelHintCallback(SDL_HINT_IOS_HIDE_HOME_INDICATOR, + SDL_HideHomeIndicatorHintChanged, + (__bridge void *) self); +#endif } - (void)setAnimationCallback:(int)interval @@ -179,7 +206,35 @@ - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient - (BOOL)prefersStatusBarHidden { - return (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) != 0; + BOOL hidden = (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) != 0; + return hidden; +} + +- (BOOL)prefersHomeIndicatorAutoHidden +{ + BOOL hidden = NO; + if (self.homeIndicatorHidden == 1) { + hidden = YES; + } + return hidden; +} + +- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures +{ + if (self.homeIndicatorHidden >= 0) { + if (self.homeIndicatorHidden == 2) { + return UIRectEdgeAll; + } else { + return UIRectEdgeNone; + } + } + + /* By default, fullscreen and borderless windows get all screen gestures */ + if ((window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) != 0) { + return UIRectEdgeAll; + } else { + return UIRectEdgeNone; + } } #endif