From 17da3ce7e50a18bcafbddcc24987bec782ca556d Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Fri, 19 Apr 2024 07:25:50 -0700 Subject: [PATCH] Fallback to the first `foregroundInactive` window when there are no `foregroundActive` windows in RCTKeyWindow (#44167) Summary: We received an issue for OSS where, when the main window is inactive and the system tries to present a dialog, the dialog is not presented in the right position on the screen. This change introduce a fallback to the first inactive window (which is still visible on screen) and it fixes the issues. ## Changelog: [iOS][Changed] - Fallback to the first `foregroundInactive` window when there are no `foregroundActive` windows in RCTKeyWindow Differential Revision: D56354741 --- packages/react-native/React/Base/RCTUtils.m | 36 +++++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/packages/react-native/React/Base/RCTUtils.m b/packages/react-native/React/Base/RCTUtils.m index 291d0e89cc824b..190c06aab0098c 100644 --- a/packages/react-native/React/Base/RCTUtils.m +++ b/packages/react-native/React/Base/RCTUtils.m @@ -562,21 +562,37 @@ BOOL RCTRunningInAppExtension(void) return nil; } - for (UIScene *scene in RCTSharedApplication().connectedScenes) { - if (scene.activationState != UISceneActivationStateForegroundActive || - ![scene isKindOfClass:[UIWindowScene class]]) { + NSSet *connectedScenes = RCTSharedApplication().connectedScenes; + + UIScene *foregroundActiveScene; + UIScene *foregroundInactiveScene; + + for (UIScene *scene in connectedScenes) { + if (![scene isKindOfClass:[UIWindowScene class]]) { continue; } - UIWindowScene *windowScene = (UIWindowScene *)scene; - if (@available(iOS 15.0, *)) { - return windowScene.keyWindow; + if (scene.activationState == UISceneActivationStateForegroundActive) { + foregroundActiveScene = scene; + break; } - for (UIWindow *window in windowScene.windows) { - if (window.isKeyWindow) { - return window; - } + if (!foregroundInactiveScene && scene.activationState == UISceneActivationStateForegroundInactive) { + foregroundInactiveScene = scene; + // no break, we can have the active scene later in the set. + } + } + + UIScene *sceneToUse = foregroundActiveScene ? foregroundActiveScene : foregroundInactiveScene; + UIWindowScene *windowScene = (UIWindowScene *)sceneToUse; + + if (@available(iOS 15.0, *)) { + return windowScene.keyWindow; + } + + for (UIWindow *window in windowScene.windows) { + if (window.isKeyWindow) { + return window; } }