react-native-screens icon indicating copy to clipboard operation
react-native-screens copied to clipboard

feat(Android,Fabric): add FullWindowOverlay support for Android

Open kkafar opened this issue 10 months ago • 6 comments

Description

Closes: https://github.com/software-mansion/react-native-screens-labs/issues/660

[!note] @kkafar: Hey, the progress here was halted because IIRC there was no good way to achieve desired behaviour. Namely if I presented the FWO component as Dialog, any other Dialog presented afterwards would be displayed above FWO overlay. Which is undesirable. IIRC there was also an option to display some content literally above everything else, but that included whole application & potentially different applications (I think that was feature meant for screen recording apps etc.). Additionally this mode required explicit permission from application user, therefore introducing another undesirable characteristic.

I don't rule out future proceeding on this PR / exploring different options but currently we >don't have it in active backlog.

This PR aims to add experimental support for FullWindowOverlay component on Android.

Supersedes #2421, #2425 (shoutout to @maciekstosio & @mfazekas for the initial work & research)

State:

  • [x] Edge-to-edge (targetSdk >= 35)
  • [ ] regular (targetSdk < 35)
  • [x] screen orientation change
  • [x] gesture support for items in FWO subtree
    • [x] pointer events (including hover)
  • [x] blocks gestures in main tree
    • [x] pointer events (including hover)
  • [x] react modal interaction tested & described
  • [ ] interaction with our modals
    • [x] Android (formSheet stays underneath)
    • [ ] iOS

Description copied from the "docs" I've added for this component in this PR

FullWindowOverlay

[!caution] Support of this component on Android is currently experimental and limited to new architecture.

In addition to navigation primitives described above :point_up:, the library exposes FullWindowOverlay component. Its purpose is to enable displaying overlay above all other application contents. Example usage can be found in TestFullWindowOverlay example in our test app.

Below we shortly describe current characteristics of the component.

[!note] Description below should be treated as implementation details and not as stable behavior description, unless explicitly stated otherwise.

View hierarchy placement

On both platforms - iOS & Android the FullWindowOverlay component gives you opportunity to mount your views directly under UIWindow & Window respectively. This allows for presenting the content above all main application content.

When using FullWindowOverlay the views are mounted in a subtree separate from main react-native subtree. This has some diverging behavior implications for each platform. Please see below the behavior description.

Behavior aspects

[!note] Description below should be treated as implementation details and not as stable behavior description, unless explicitly stated otherwise.

Dimensions

FullWindowOverlay should have dimensions of full window. It does not take safe area insets into account - it is left to the user to handle.

In Android applications that do not have edge-to-edge enabled (vast majority of applications targeting SDK 34 or lower) the status & navigation bars are expected.

Gestures

By design, the FullWindowOverlay component blocks gesture interaction with content underneath.

The gestures for views in FullWindowOverlay's subtree are fully supported.

Interaction with modal components

In this section we describe briefly how the FullWindowOverlay component behaves when used simultaneously with different modal components. Due to platform differences the behavior is slightly different depending whether it is used on iOS or Android devices.

iOS

On iOS the FullWindowOverlay stays above navigation screens with modal presentation. The same applies for e.g. Modal from react-native. We do not guarantee that this will be the case for any third-party modal component, since it depends on its internal implementation.

Android

On Android we use TYPE_APPLICATION_ATTACHED_DIALOG to mount the component directly under the window. Together with react-native's Modal implementation details this implies that Modal will be displayed above the FullWindowOverlay if displayed from already mounted FullWindowOverlay - and vice versa -FullWindowOverlay will be displayed above the Modal if displayed from already mounted Modal.

To make FullWindowOverlay display always on top of everything on Android is technically possible, however requires explicit permission from the application user. At the moment we decided to avoid this and settled on "weaker" implementation. Please note that we might add this option some time in the future (in a non-breaking way).


and back to PR description...

Changes

Test code and steps to reproduce

Test1096, TestFullWindowOverlay

Checklist

  • [ ] Included code example that can be used to test this change
  • [ ] Ensured that CI passes

kkafar avatar Feb 22 '25 12:02 kkafar

Currently blocked by a layout bug when changing screen orientation on Android SDK 34.

kkafar avatar Feb 25 '25 12:02 kkafar

Any progress on this? Would love support for this :)

mrmuke avatar Apr 13 '25 23:04 mrmuke

Are you still blocked?

mrmuke avatar Apr 13 '25 23:04 mrmuke

Hey @mrmuke, I haven't look into this PR since. This still requires some debugging work & refactor to use Dialog. I might be able to be back at it after release of stable 4.11.0

kkafar avatar Apr 14 '25 18:04 kkafar

Any progress on this? would this allow nested formSheets / modals on Android to display over the parent components it's nested with / under? as they do in iOS?

unsure if this is an issue with screens or expo router tho but this does look promising

Bowlerr avatar Aug 27 '25 13:08 Bowlerr

Hey, the progress here was halted because IIRC there was no good way to achieve desired behaviour. Namely if I presented the FWO component as Dialog, any other Dialog presented afterwards would be displayed above FWO overlay. Which is undesirable. IIRC there was also an option to display some content literally above everything else, but that included whole application & potentially different applications (I think that was feature meant for screen recording apps etc.). Additionally this mode required explicit permission from application user, therefore introducing another undesirable characteristic.

I don't rule out future proceeding on this PR / exploring different options but currently we don't have it in active backlog.

kkafar avatar Nov 03 '25 14:11 kkafar