software-mansion / software-mansion/react-native-screens

Android: touch hit testing breaks after fullscreen orientation change when screen shadow state reset is enabled

Open
#4,289 10 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

missing-info missing-repro platform:android
Dominant language
TypeScript
Stars
3.7k
Forks
714
Avg merge
2d 23h
Merged PRs (30d)
71

Description

Description

We are seeing an Android regression where touch hit testing becomes broken on the previous RNSScreen after a fullscreen video flow changes orientation and then returns to the previous screen.

This appears to be related to the Android orientation-change layout fix from #3295, specifically the androidResetScreenShadowStateOnOrientationChangeEnabled / RNSScreenShadowNodeCommitHook path.

Environment
  • react-native-screens: reproduced with 4.19.0 and 4.25.2
  • react-native: 0.86.0
  • expo: ~57.0.4
  • expo-router: ~57.0.4
  • Platform: Android
  • New Architecture/Fabric: enabled by default in Expo SDK 57
  • Navigation: Expo Router / native stack
Regression range
  • react-native-screens@4.18.0: works
  • react-native-screens@4.19.0: broken
  • react-native-screens@4.25.2: broken
  • react-native-screens@4.25.2 with androidResetScreenShadowStateOnOrientationChangeEnabled default changed from true to false: works
Reproduction pattern
  1. Open a stack screen, for example a workspace/file-list screen.
  2. Navigate to a video player screen.
  3. Enter fullscreen video, which changes the device/app orientation to landscape.
  4. Exit fullscreen, returning orientation to portrait.
  5. Dismiss the video player and return to the previous stack screen.
  6. Try tapping content inside the previous screen.
Actual behavior

The native header still responds to taps, but the previous screen content area becomes mostly unresponsive.

For example:

  • file/folder list items mostly cannot be tapped;
  • repeated taps may occasionally trigger something;
  • native header back button still works;
  • tab/root screens still work;
  • entering the same screen again as a new screen instance restores normal touch behavior;
  • manually rotating the device again also restores normal touch behavior.

This makes it look like the old RNSScreen content area's native layout / hit-test state is stale after the fullscreen orientation transition.

Expected behavior

After exiting fullscreen and dismissing the video player screen, the previous screen should receive touches normally.

Workaround that fixes it

Keeping react-native-screens@4.25.2, this local patch fixes the issue for us:

-const RNS_ANDROID_RESET_SCREEN_SHADOW_STATE_ON_ORIENTATION_CHANGE_DEFAULT = true;
+const RNS_ANDROID_RESET_SCREEN_SHADOW_STATE_ON_ORIENTATION_CHANGE_DEFAULT = false;

and in the codegen spec:

 androidResetScreenShadowStateOnOrientationChangeEnabled?: CT.WithDefault<
   boolean,
-  true
+  false
 >;

After that patch, the same fullscreen video orientation flow no longer breaks touch handling on the previous screen.

Why this looks related to #3295

#3295 introduced a commit hook that detects orientation changes and resets RNSScreen frame size so Yoga recalculates layout. That matches the regression boundary exactly: 4.18.0 works, 4.19.0 fails.

The issue also seems consistent with later work such as commit aedf1ee / #4200, whose description says stale Yoga measurements can still be received after orientation changes and avoids applying Yoga layout directly to StackHost children.

Our case may be another path where the orientation reset happens while a fullscreen/modal video screen is being dismissed and the previous screen is being revealed. The parent/root/native dimensions may not be fully synchronized yet, so the recalculated Yoga layout or hit-test geometry for the previous screen can become stale until another full orientation/layout pass occurs.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the RNSScreenShadowNodeCommitHook orientation-reset path introduced by #3295 and the related codegen spec; compare it with the later changes described in #4200 and commit aedf1ee. Reproduce the fullscreen video orientation flow using the listed version boundary and verify that the previous screen's content receives touches after dismissal without requiring another rotation.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, react-native, typescript
Domain
mobile-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.