Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Separate window dimensions change from orientation
Summary: **Summary:** There was a bug with RN.Dimensions returning incorrect window dimensions. In certain cases when device was in portrait, window dimensions reported landscape dimensions and vice versa. This happened because in certain scenarios, after device orientation changed, dimensions update event from ReactRootView had incorrect dimensions. Was able to reproduce this when device was rotated during app launch. After rotation global layout listener callback gets invoked. Inside the callback current and previous orientations are compared. When a change is detected, orientation and dimension change events are sent to JS. It is assumed, when orientation changes, new dimensions are available immediately. This is not the case for window dimensions as they are retrieved from resources object which gets updated asynchronously after orientation change. In cases when app is doing a lot of work on the main thread, like app startup, it takes more time to update the resources object. And when orientation change is detected in global layout, resources object is not updated with new dimensions yet. This causes dimensions update to be sent to JS with old window dimensions. Global layout listener callback does get invoked a second time when resources object is finally updated with new dimensions, but since orientation no longer changes, no event is sent to JS. Fixed this by separating dimensions update from orientation update. Now RN keeps track of previous window and screen dimension values. When a change is detected, an event is sent to JS with updated dimensions. This ensures that whenever dimensions change, JS gets the updated values. This has a side effect of sending dimension update twice in some cases. One example is the case above where window dimensions take time to update, but screen dimensions are updated immediately. This will cause two events to be sent to JS. One for window dimensions and one for screen dimensions update. Other change is that initial value for both window and screen fields is empty. Which results in first change to trigger an event. Previously initial orientation value was 0 which meant when app started in normal portrait orientation, first layout did not trigger a dimension update event. Now even first layout sends the event. This should not be an issue as it is to make sure dimensions in JS side are correct. **Testing:** Verified with a sample app that correct dimensions are available when app launches. Verified that after orientation dimensions are updated. Verified that in the scenario described above where window dimensions are updated later, we get correct dimension values in JS. We have incorporated this fix into our app and have been testing it internally. Ats Jenk Microsoft Corp. <!-- Thank you for sending the PR! If you changed any code, please provide us with clear instructions on how you verified your changes work. In other words, a test plan is *required*. Bonus points for screenshots and videos! Please read the Contribution Guidelines at https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md to learn more about contributing to React Native. Happy contributing! --> Closes #15181 Differential Revision: D5552195 Pulled By: shergin fbshipit-source-id: d1f190cb960090468886ff56cda58cac296745db
- Loading branch information
c9aeaf6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting ! I think I need a similar behavior to detect dimensions changes on iOS too.
But on iOS I don't know if there is something similar to
onGlobalLayout
like on Android…My issue about iOS Dimensions on iPad : #16152