From eaaf865449e6b89cc2794b68f314d01aa775748e Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Thu, 25 Apr 2024 03:28:22 -0700 Subject: [PATCH] Fallback to the first `foregroundInactive` window when there are no `foregroundActive` windows in RCTKeyWindow (#44167) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/44167 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. [iOS][Changed] - Fallback to the first `foregroundInactive` window when there are no `foregroundActive` windows in RCTKeyWindow Reviewed By: dmytrorykun Differential Revision: D56354741 fbshipit-source-id: fa23131ecd40f6d91c705879a72890506ee21486 --- packages/react-native/React/Base/RCTUtils.m | 36 ++++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/packages/react-native/React/Base/RCTUtils.m b/packages/react-native/React/Base/RCTUtils.m index 96e59e2db10181..226a2bc8604481 100644 --- a/packages/react-native/React/Base/RCTUtils.m +++ b/packages/react-native/React/Base/RCTUtils.m @@ -562,17 +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; - for (UIWindow *window in windowScene.windows) { - if (window.isKeyWindow) { - return window; - } + if (scene.activationState == UISceneActivationStateForegroundActive) { + foregroundActiveScene = scene; + break; + } + + 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; } }