|
|
@@ -59,7 +59,15 @@ int SDL_RunApp(int argc, char *argv[], SDL_main_func mainFunction, void *reserve
|
|
|
|
|
|
// Give over control to run loop, SDLUIKitDelegate will handle most things from here
|
|
|
@autoreleasepool {
|
|
|
- UIApplicationMain(argc, argv, nil, [SDLUIKitDelegate getAppDelegateClassName]);
|
|
|
+ NSString *name = nil;
|
|
|
+
|
|
|
+ if (@available(iOS 13.0, tvOS 13.0, *)) {
|
|
|
+ name = [SDLUIKitSceneDelegate getSceneDelegateClassName];
|
|
|
+ }
|
|
|
+ if (!name) {
|
|
|
+ name = [SDLUIKitDelegate getAppDelegateClassName];
|
|
|
+ }
|
|
|
+ UIApplicationMain(argc, argv, nil, name);
|
|
|
}
|
|
|
|
|
|
// free the memory we used to hold copies of argc and argv
|
|
|
@@ -162,6 +170,7 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
|
|
@end
|
|
|
#endif // !SDL_PLATFORM_TVOS
|
|
|
|
|
|
+
|
|
|
@interface SDLLaunchScreenController ()
|
|
|
|
|
|
#ifndef SDL_PLATFORM_TVOS
|
|
|
@@ -343,7 +352,170 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
|
|
}
|
|
|
#endif // !SDL_PLATFORM_TVOS
|
|
|
|
|
|
-@end
|
|
|
+@end // SDLLaunchScreenController
|
|
|
+
|
|
|
+
|
|
|
+API_AVAILABLE(ios(13.0))
|
|
|
+@implementation SDLUIKitSceneDelegate
|
|
|
+{
|
|
|
+ UIWindow *launchWindow;
|
|
|
+}
|
|
|
+
|
|
|
++ (NSString *)getSceneDelegateClassName
|
|
|
+{
|
|
|
+ return @"SDLUIKitSceneDelegate";
|
|
|
+}
|
|
|
+
|
|
|
+- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions
|
|
|
+{
|
|
|
+ if (![scene isKindOfClass:[UIWindowScene class]]) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ UIWindowScene *windowScene = (UIWindowScene *)scene;
|
|
|
+ windowScene.delegate = self;
|
|
|
+
|
|
|
+ NSBundle *bundle = [NSBundle mainBundle];
|
|
|
+
|
|
|
+#ifdef SDL_IPHONE_LAUNCHSCREEN
|
|
|
+ UIViewController *vc = nil;
|
|
|
+ NSString *screenname = nil;
|
|
|
+
|
|
|
+#if !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS)
|
|
|
+ screenname = [bundle objectForInfoDictionaryKey:@"UILaunchStoryboardName"];
|
|
|
+
|
|
|
+ if (screenname) {
|
|
|
+ @try {
|
|
|
+ UIStoryboard *storyboard = [UIStoryboard storyboardWithName:screenname bundle:bundle];
|
|
|
+ __auto_type storyboardVc = [storyboard instantiateInitialViewController];
|
|
|
+ vc = [[SDLLaunchStoryboardViewController alloc] initWithStoryboardViewController:storyboardVc];
|
|
|
+ }
|
|
|
+ @catch (NSException *exception) {
|
|
|
+ // Do nothing (there's more code to execute below).
|
|
|
+ }
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+ if (vc == nil) {
|
|
|
+ vc = [[SDLLaunchScreenController alloc] initWithNibName:screenname bundle:bundle];
|
|
|
+ }
|
|
|
+
|
|
|
+ if (vc.view) {
|
|
|
+#ifdef SDL_PLATFORM_VISIONOS
|
|
|
+ CGRect viewFrame = CGRectMake(0, 0, SDL_XR_SCREENWIDTH, SDL_XR_SCREENHEIGHT);
|
|
|
+#else
|
|
|
+ CGRect viewFrame = windowScene.coordinateSpace.bounds;
|
|
|
+#endif
|
|
|
+ launchWindow = [[UIWindow alloc] initWithWindowScene:windowScene];
|
|
|
+ launchWindow.frame = viewFrame;
|
|
|
+
|
|
|
+ launchWindow.windowLevel = UIWindowLevelNormal + 1.0;
|
|
|
+ launchWindow.hidden = NO;
|
|
|
+ launchWindow.rootViewController = vc;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+ // Set working directory to resource path
|
|
|
+ [[NSFileManager defaultManager] changeCurrentDirectoryPath:[bundle resourcePath]];
|
|
|
+
|
|
|
+ // Handle any connection options (like opening URLs)
|
|
|
+ for (NSUserActivity *activity in connectionOptions.userActivities) {
|
|
|
+ if (activity.webpageURL) {
|
|
|
+ [self handleURL:activity.webpageURL];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (UIOpenURLContext *urlContext in connectionOptions.URLContexts) {
|
|
|
+ [self handleURL:urlContext.URL];
|
|
|
+ }
|
|
|
+
|
|
|
+ SDL_SetMainReady();
|
|
|
+ [self performSelector:@selector(postFinishLaunch) withObject:nil afterDelay:0.0];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts
|
|
|
+{
|
|
|
+ for (UIOpenURLContext *context in URLContexts) {
|
|
|
+ [self handleURL:context.URL];
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (void)sceneDidBecomeActive:(UIScene *)scene
|
|
|
+{
|
|
|
+ SDL_OnApplicationDidEnterForeground();
|
|
|
+}
|
|
|
+
|
|
|
+- (void)sceneWillResignActive:(UIScene *)scene
|
|
|
+{
|
|
|
+ SDL_OnApplicationWillEnterBackground();
|
|
|
+}
|
|
|
+
|
|
|
+- (void)sceneWillEnterForeground:(UIScene *)scene
|
|
|
+{
|
|
|
+ SDL_OnApplicationWillEnterForeground();
|
|
|
+}
|
|
|
+
|
|
|
+- (void)sceneDidEnterBackground:(UIScene *)scene
|
|
|
+{
|
|
|
+ SDL_OnApplicationDidEnterBackground();
|
|
|
+}
|
|
|
+
|
|
|
+- (void)handleURL:(NSURL *)url
|
|
|
+{
|
|
|
+ const char *sourceApplicationCString = NULL;
|
|
|
+ NSURL *fileURL = url.filePathURL;
|
|
|
+ if (fileURL != nil) {
|
|
|
+ SDL_SendDropFile(NULL, sourceApplicationCString, fileURL.path.UTF8String);
|
|
|
+ } else {
|
|
|
+ SDL_SendDropFile(NULL, sourceApplicationCString, url.absoluteString.UTF8String);
|
|
|
+ }
|
|
|
+ SDL_SendDropComplete(NULL);
|
|
|
+}
|
|
|
+
|
|
|
+- (void)hideLaunchScreen
|
|
|
+{
|
|
|
+ UIWindow *window = launchWindow;
|
|
|
+
|
|
|
+ if (!window || window.hidden) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ launchWindow = nil;
|
|
|
+
|
|
|
+ [UIView animateWithDuration:0.2
|
|
|
+ animations:^{
|
|
|
+ window.alpha = 0.0;
|
|
|
+ }
|
|
|
+ completion:^(BOOL finished) {
|
|
|
+ window.hidden = YES;
|
|
|
+ UIKit_ForceUpdateHomeIndicator();
|
|
|
+ }];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)postFinishLaunch
|
|
|
+{
|
|
|
+ [self performSelector:@selector(hideLaunchScreen) withObject:nil afterDelay:0.0];
|
|
|
+
|
|
|
+ SDL_SetiOSEventPump(true);
|
|
|
+ exit_status = forward_main(forward_argc, forward_argv);
|
|
|
+ SDL_SetiOSEventPump(false);
|
|
|
+
|
|
|
+ if (launchWindow) {
|
|
|
+ launchWindow.hidden = YES;
|
|
|
+ launchWindow = nil;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options API_AVAILABLE(ios(13.0))
|
|
|
+{
|
|
|
+ // This doesn't appear to be called, but it needs to be implemented to signal that we support the UIScene life cycle
|
|
|
+ UISceneConfiguration *config = [[UISceneConfiguration alloc] initWithName:@"SDLSceneConfiguration" sessionRole:connectingSceneSession.role];
|
|
|
+ config.delegateClass = [SDLUIKitSceneDelegate class];
|
|
|
+ return config;
|
|
|
+}
|
|
|
+
|
|
|
+@end // SDLUIKitSceneDelegate
|
|
|
+
|
|
|
|
|
|
@implementation SDLUIKitDelegate
|
|
|
{
|
|
|
@@ -514,6 +686,6 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
|
|
return YES;
|
|
|
}
|
|
|
|
|
|
-@end
|
|
|
+@end // SDLUIKitDelegate
|
|
|
|
|
|
#endif // SDL_VIDEO_DRIVER_UIKIT
|