Enhance mobile suspend MainLoop Notifications

This commit is contained in:
Zach Coleman 2023-11-17 08:23:06 -05:00
parent b4e2a24c1f
commit fc7a63cbf3
6 changed files with 57 additions and 10 deletions

View file

@ -119,19 +119,20 @@
</constant> </constant>
<constant name="NOTIFICATION_APPLICATION_RESUMED" value="2014"> <constant name="NOTIFICATION_APPLICATION_RESUMED" value="2014">
Notification received from the OS when the application is resumed. Notification received from the OS when the application is resumed.
Specific to the Android platform. Specific to the Android and iOS platforms.
</constant> </constant>
<constant name="NOTIFICATION_APPLICATION_PAUSED" value="2015"> <constant name="NOTIFICATION_APPLICATION_PAUSED" value="2015">
Notification received from the OS when the application is paused. Notification received from the OS when the application is paused.
Specific to the Android platform. Specific to the Android and iOS platforms.
[b]Note:[/b] On iOS, you only have approximately 5 seconds to finish a task started by this signal. If you go over this allotment, iOS will kill the app instead of pausing it.
</constant> </constant>
<constant name="NOTIFICATION_APPLICATION_FOCUS_IN" value="2016"> <constant name="NOTIFICATION_APPLICATION_FOCUS_IN" value="2016">
Notification received from the OS when the application is focused, i.e. when changing the focus from the OS desktop or a thirdparty application to any open window of the Godot instance. Notification received from the OS when the application is focused, i.e. when changing the focus from the OS desktop or a thirdparty application to any open window of the Godot instance.
Implemented on desktop platforms. Implemented on desktop and mobile platforms.
</constant> </constant>
<constant name="NOTIFICATION_APPLICATION_FOCUS_OUT" value="2017"> <constant name="NOTIFICATION_APPLICATION_FOCUS_OUT" value="2017">
Notification received from the OS when the application is defocused, i.e. when changing the focus from any open window of the Godot instance to the OS desktop or a thirdparty application. Notification received from the OS when the application is defocused, i.e. when changing the focus from any open window of the Godot instance to the OS desktop or a thirdparty application.
Implemented on desktop platforms. Implemented on desktop and mobile platforms.
</constant> </constant>
<constant name="NOTIFICATION_TEXT_SERVER_CHANGED" value="2018"> <constant name="NOTIFICATION_TEXT_SERVER_CHANGED" value="2018">
Notification received when text server is changed. Notification received when text server is changed.

View file

@ -1151,19 +1151,20 @@
</constant> </constant>
<constant name="NOTIFICATION_APPLICATION_RESUMED" value="2014"> <constant name="NOTIFICATION_APPLICATION_RESUMED" value="2014">
Notification received from the OS when the application is resumed. Notification received from the OS when the application is resumed.
Implemented only on Android. Specific to the Android and iOS platforms.
</constant> </constant>
<constant name="NOTIFICATION_APPLICATION_PAUSED" value="2015"> <constant name="NOTIFICATION_APPLICATION_PAUSED" value="2015">
Notification received from the OS when the application is paused. Notification received from the OS when the application is paused.
Implemented only on Android. Specific to the Android and iOS platforms.
[b]Note:[/b] On iOS, you only have approximately 5 seconds to finish a task started by this signal. If you go over this allotment, iOS will kill the app instead of pausing it.
</constant> </constant>
<constant name="NOTIFICATION_APPLICATION_FOCUS_IN" value="2016"> <constant name="NOTIFICATION_APPLICATION_FOCUS_IN" value="2016">
Notification received from the OS when the application is focused, i.e. when changing the focus from the OS desktop or a third-party application to any open window of the Godot instance. Notification received from the OS when the application is focused, i.e. when changing the focus from the OS desktop or a thirdparty application to any open window of the Godot instance.
Implemented on desktop platforms. Implemented on desktop and mobile platforms.
</constant> </constant>
<constant name="NOTIFICATION_APPLICATION_FOCUS_OUT" value="2017"> <constant name="NOTIFICATION_APPLICATION_FOCUS_OUT" value="2017">
Notification received from the OS when the application is defocused, i.e. when changing the focus from any open window of the Godot instance to the OS desktop or a third-party application. Notification received from the OS when the application is defocused, i.e. when changing the focus from any open window of the Godot instance to the OS desktop or a thirdparty application.
Implemented on desktop platforms. Implemented on desktop and mobile platforms.
</constant> </constant>
<constant name="NOTIFICATION_TEXT_SERVER_CHANGED" value="2018"> <constant name="NOTIFICATION_TEXT_SERVER_CHANGED" value="2018">
Notification received when the [TextServer] is changed. Notification received when the [TextServer] is changed.

View file

@ -324,11 +324,17 @@ void OS_Android::main_loop_end() {
void OS_Android::main_loop_focusout() { void OS_Android::main_loop_focusout() {
DisplayServerAndroid::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_OUT); DisplayServerAndroid::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_OUT);
if (OS::get_singleton()->get_main_loop()) {
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT);
}
audio_driver_android.set_pause(true); audio_driver_android.set_pause(true);
} }
void OS_Android::main_loop_focusin() { void OS_Android::main_loop_focusin() {
DisplayServerAndroid::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_IN); DisplayServerAndroid::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_IN);
if (OS::get_singleton()->get_main_loop()) {
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN);
}
audio_driver_android.set_pause(false); audio_driver_android.set_pause(false);
} }

View file

@ -167,6 +167,14 @@ static ViewController *mainViewController = nil;
OS_IOS::get_singleton()->on_focus_in(); OS_IOS::get_singleton()->on_focus_in();
} }
- (void)applicationDidEnterBackground:(UIApplication *)application {
OS_IOS::get_singleton()->on_enter_background();
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
OS_IOS::get_singleton()->on_exit_background();
}
- (void)dealloc { - (void)dealloc {
self.window = nil; self.window = nil;
} }

View file

@ -129,6 +129,9 @@ public:
void on_focus_out(); void on_focus_out();
void on_focus_in(); void on_focus_in();
void on_enter_background();
void on_exit_background();
}; };
#endif // IOS_ENABLED #endif // IOS_ENABLED

View file

@ -601,6 +601,10 @@ void OS_IOS::on_focus_out() {
DisplayServerIOS::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_OUT); DisplayServerIOS::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_OUT);
} }
if (OS::get_singleton()->get_main_loop()) {
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT);
}
[AppDelegate.viewController.godotView stopRendering]; [AppDelegate.viewController.godotView stopRendering];
audio_driver.stop(); audio_driver.stop();
@ -615,10 +619,34 @@ void OS_IOS::on_focus_in() {
DisplayServerIOS::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_IN); DisplayServerIOS::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_IN);
} }
if (OS::get_singleton()->get_main_loop()) {
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN);
}
[AppDelegate.viewController.godotView startRendering]; [AppDelegate.viewController.godotView startRendering];
audio_driver.start(); audio_driver.start();
} }
} }
void OS_IOS::on_enter_background() {
// Do not check for is_focused, because on_focus_out will always be fired first by applicationWillResignActive.
if (OS::get_singleton()->get_main_loop()) {
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_PAUSED);
}
on_focus_out();
}
void OS_IOS::on_exit_background() {
if (!is_focused) {
on_focus_in();
if (OS::get_singleton()->get_main_loop()) {
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_RESUMED);
}
}
}
#endif // IOS_ENABLED #endif // IOS_ENABLED