Fix measureInWindow on Android edge-to-edge#56056
Fix measureInWindow on Android edge-to-edge#56056zoontek wants to merge 2 commits intofacebook:mainfrom
Conversation
04d84f8 to
f165005
Compare
## 📜 Description Fixed broken `measureInWindow` measurements in react-native. ## 💡 Motivation and Context The `measureInWindow` works unreliably in Fabric + formSheet Modal (facebook/react-native#56062) or on Android with edge-to-edge enabled (facebook/react-native#56056) Upstream fixes are available, but the problem is that it will require at least RN 0.85+ to work properly. So in this PR we add internal function that is capable of measuring given view. In future this functionality can be removed, but for now this is critical to have it bundled within a package. Fixes #1356 ## 📢 Changelog <!-- High level overview of important changes --> <!-- For example: fixed status bar manipulation; added new types declarations; --> <!-- If your changes don't affect one of platform/language below - then remove this platform/language --> ### JS - added `viewPositionInWindow` to `types`; - added `viewPositionInWindow` to codegen; - added `viewPositionInWindow` to bindings/module; - use `viewPositionInWindow` instead of `measureInWindow`; - added `viewPositionInWindow` to mocks; ### iOS - implement `viewPositionInWindow`; - make `activeWindow` objc available; ### Android - implement `viewPositionInWindow`; - add `uiManager` and `eventDispatcher` to `ReactContext` extensions; ## 🤔 How Has This Been Tested? Tested manually on iPhone 17 Pro (iOS 26.2, simulator) and Pixel 9 Pro (API 35, emulator). ## 📸 Screenshots (if appropriate): ### Android #### Fabric |Before|After| |-------|-----| |<video src="https://github.com/user-attachments/assets/afb99e51-043f-459c-90e3-7e1eb1e184ed">|<video src="https://github.com/user-attachments/assets/8ea0d593-f7bd-47a5-9343-e2fd85f4af45">| #### Paper |Before|After| |-------|-----| |<video src="https://github.com/user-attachments/assets/702c7d88-755b-45f0-b39f-fe4aaa60ab2e">|<video src="https://github.com/user-attachments/assets/f5346bbd-cc85-4a40-9cc5-9422931b04af">| ### iOS #### Fabric |Before|After| |-------|-----| |<video src="https://github.com/user-attachments/assets/49fb9ac6-15b8-4842-939c-4ec06a4e0c42">|<video src="https://github.com/user-attachments/assets/b559a52a-0a91-48bc-911a-7125ce96e013">| #### Paper |Before|After| |-------|-----| |<video src="https://github.com/user-attachments/assets/c4d234a7-122a-4023-8d86-fad71ed043dc">|<video src="https://github.com/user-attachments/assets/d5d48487-16ad-40c2-b6c6-fea85b563e20">| ## 📝 Checklist - [x] CI successfully passed - [x] I added new mocks and corresponding unit-tests if library API was changed --------- Co-authored-by: thomasvo <thomas.vo@openspace.ai> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: kirillzyusko <zyusko.kirik@gmail.com>
2c7f994 to
0c702a0
Compare
|
@alanleedev has imported this pull request. If you are a Meta employee, you can view this in D101308387. |
0c702a0 to
547fc3a
Compare
dc2a7ab to
be7ec70
Compare
c40bf04 to
d0ea897
Compare
| @@ -47,16 +50,24 @@ public class ReactSurfaceView(context: Context?, internal val surface: ReactSurf | |||
|
|
|||
| private val viewportOffset: Point | |||
There was a problem hiding this comment.
The logic is similar to RootViewUtil.getViewportOffset(v: View), it's just not used here because of it's bad naming (getViewportOffset could be called for any view, not just the root one)
| import com.facebook.react.uimanager.JSPointerDispatcher | ||
| import com.facebook.react.uimanager.JSTouchDispatcher | ||
| import com.facebook.react.uimanager.common.UIManagerType | ||
| import com.facebook.react.views.view.isEdgeToEdgeFeatureFlagOn |
There was a problem hiding this comment.
copying here comment from @javache
I don't think react.runtime can depend on react.views? There seems to be a dependency issue.
Maybe the feature flag should live in UIManager/
There was a problem hiding this comment.
we could move isEdgeToEdgeFeatureFlagOn / setEdgeToEdgeFeatureFlagOn / updateEdgeToEdgeFeatureFlag in a separate file, but that introduces a change in the public API
There was a problem hiding this comment.
FYI, com.facebook.react.views.view.isEdgeToEdgeFeatureFlagOn was add in June 2025.
@javache I also don't see any build issues so is this more of an architectural policy?
|
This pull request was successfully merged by @zoontek in 9d18367 When will my fix make it into a release? | How to file a pick request? |
Summary:
Fixes
measureInWindowon Android when edge-to-edge is enabled.Both
ReactSurfaceView.viewportOffsetandRootViewUtil.getViewportOffsetsubtract the visible window frame (status bar insets, split screen offsets) fromgetLocationOnScreen/getLocationInWindowcoordinates. This is incorrect in edge-to-edge mode, where the content already extends behind system bars.Related issue: #50509
Changelog:
[ANDROID] [FIXED] - Fix
measureInWindowreturning incorrect coordinates when edge-to-edge is enabledTest Plan:
Tested
measureInWindowwith and without edge-to-edge enabled, in both single-window and split-screen configurations. Verified that returned coordinates correctly reflect the view's position relative to the visible content area.For that, in
RNTesterActivity.kt, comment:And in
RNTesterAppShared.jsreplaceexport default RNTesterAppwith:Screenshots:
Android 16 / edge-to-edge on - current behavior
Android 16 / edge-to-edge on - with fix
Android 14 / edge-to-edge off - current behavior
Android 14 / edge-to-edge off - with fix (no change)