From 08a924bcee3b4d128ddcf261a8c2fc915db486fc Mon Sep 17 00:00:00 2001 From: Ruslan Mustakov Date: Fri, 11 May 2018 17:07:43 +0700 Subject: [PATCH] Proper focus in/out handling on iOS PR #18675 (commit 96301e9) revealed a problem with how iOS lifecycle callbacks were handled by Godot. Before that PR it was possible to get NOTIFICATION_WM_FOCUS_IN callback without getting the corresponding NOTIFICATION_WM_FOCUS_OUT. That commit added a flag to ensure they are always coupled, but now there is an issue when, for example, you open a notification panel on iOS without moving the app to background. It resulted in view.stopAnimation being called without the corresponding startAnimation when the app moves to foreground again, so it looked like the game hanged. I changed focus out notification to be sent in applicationWillResignActive, because it makes more sense than to do it in applicationDidEnterBackground, because it is always called in pair with applicationDidBecomeActive, where focus in is sent. applicationDidEnterBackground may not come under circumstances that are now described as a comment in code. --- platform/iphone/app_delegate.mm | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm index 7ed1328b20d..dd5ce4ab10b 100644 --- a/platform/iphone/app_delegate.mm +++ b/platform/iphone/app_delegate.mm @@ -709,21 +709,18 @@ static int frame_count = 0; iphone_finish(); }; -- (void)applicationDidEnterBackground:(UIApplication *)application { - ///@TODO maybe add pause motionManager? and where would we unpause it? +// When application goes to background (e.g. user switches to another app or presses Home), +// then applicationWillResignActive -> applicationDidEnterBackground are called. +// When user opens the inactive app again, +// applicationWillEnterForeground -> applicationDidBecomeActive are called. - on_focus_out(view_controller, &is_focus_out); -} - -- (void)applicationWillEnterForeground:(UIApplication *)application { - // OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN); - [view_controller.view startAnimation]; -} +// There are cases when applicationWillResignActive -> applicationDidBecomeActive +// sequence is called without the app going to background. For example, that happens +// if you open the app list without switching to another app or open/close the +// notification panel by swiping from the upper part of the screen. - (void)applicationWillResignActive:(UIApplication *)application { - // OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT); - [view_controller.view - stopAnimation]; // FIXME: pause seems to be recommended elsewhere + on_focus_out(view_controller, &is_focus_out); } - (void)applicationDidBecomeActive:(UIApplication *)application {