-
Notifications
You must be signed in to change notification settings - Fork 24.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BREAKING: Android: Correct value of Dimensions.get('screen').fontScale #11008
BREAKING: Android: Correct value of Dimensions.get('screen').fontScale #11008
Conversation
By analyzing the blame information on this pull request, we identified @astreet and @AaaChiuuu to be potential reviewers. |
Summary: Corresponding Android PR: #11008 This gives apps the ability to find out the current scaling factor for fonts on the device. An event was also added so that apps can find out when this value changes. **Test plan (required)** Verified that the getter and the event work properly in a test app. Also, this change is used in my team's app. Adam Comella Microsoft Corp. Closes #11010 Differential Revision: D4207620 Pulled By: ericvicenti fbshipit-source-id: b3f6f4a412557ba97e1f5fb63446c7ff9a2ff753
Since it looks like the method and event deal purely with fonts, what do you think of the following naming?
But I see on iOS this reads Should the method and event be declared and documented in a JS file somewhere? |
|
Functionality-wise, everything works fine without declaring the method or event in a JS file. You raise a good point about documentation. Do you have any suggestions of where to document it? It doesn't look like there's any API reference page for
Perhaps the same solution should be used for documenting all of these UIManager methods.
I don't have a strong preference here. I'm not an expert on the subject but looking at the iOS and Android docs, the native sources of
Since this appears to be about font scaling, I can see why the name
If you want me to rename it to Confusingly, RN Android already exposes a |
Do you propose we do anything for the For (2), do you propose we expose that value to JS through As I mentioned to Martin, I discovered that RN Android already exposes a
|
Whoops, I think you found a bug/misnaming in RN: According to http://androidxref.com/4.2_r1/xref/packages/apps/Settings/src/com/android/settings/Display.java#99, react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModuleConstants.java Line 111 in abb8ea3
fontScale , is actually fontScale * density . But it seems to be exposed and used as an actual fontScale in our JS code? I'm pretty confused, this seems very clowny as it would indicate some things using this weren't very well tested :P @foghina, am I reading this wrong?
|
I agree, I checked the website before asking the original question and didn't see any docs for We do have a
Good points, let's keep
Thanks for noticing this! It might be wrong and maybe we should deprecate it as part of this PR? |
Ok. So.
As for |
Ok, thanks Felix. I don't think we should be doing anything new then, except for maybe renaming fontScale to something more accurate (this would be breaking though) or exposing a convenience method to PixelRatio. |
You've convinced me that we don't need to add As Felix mentioned, on Android we can calculate For iOS, we could expose @foghina, you mentioned you don't think we should add random getters to UIManager. In general, should apps be directly calling any UIManager APIs from JS? If not:
|
Yeah, I would say we should revert eddc2c9. I'm not sure about the iOS APIs -- do they even have system-wide font scaling? It also looks to me like our one internal use of |
Yes, they do. eddc2c9 exposed the current font scale to JS. Currently, Android exposes @astreet @foghina What do you think of this proposal:
One question: do we need to make any changes to |
That sounds like a breaking change on Android, so I'm not really in love with it. However, I did some grepping internally and I think we only have one place where we use this, so it should be easy to fix. I'd say let's go ahead with this plan. Also, I just realized
Can you change constants on iOS? You can't on Android (without restarting the bridge). I'm asking because we should stick with the getter if we can't change the constant. We don't want to end up with Last question: what number does iOS return from |
I only saw that one place too and it should really just be removed: we already factor system font scale on the native side by converting from SP so they're double-factoring font scale. @rigdern changing Also, just expose
I'm less sure about the impacts of this change... would it cause us to do a re-layout? Should probably get @javache in on this. |
Why do you think this is iOS-inspired? Looking at the code, iOS only exposes window dimensions whereas Android exposes both window and screen dimensions. Do you have a suggestion for how this could be cleaned up?
I don't think you can change constants on iOS but I don't think this is important in this case because it looks like apps don't use these constants directly. Instead, they are accessed through the
If by
Okay, I just noticed that iOS already exports a
Here are the options I have in mind for notifying the app that
Note that apps might access I think |
I'm fine with creating a new event. Just making sure, updating the font scale causes us to perform a re-layout, right? |
Sorry for the delay on this.
@astreet Yes. On iOS, text is marked as dirty and relaid out. On Android, the root view is destroyed and recreated. I ran into some issues trying to implement this on Android:
|
Summary: Corresponding Android PR: facebook#11008 This gives apps the ability to find out the current scaling factor for fonts on the device. An event was also added so that apps can find out when this value changes. **Test plan (required)** Verified that the getter and the event work properly in a test app. Also, this change is used in my team's app. Adam Comella Microsoft Corp. Closes facebook#11010 Differential Revision: D4207620 Pulled By: ericvicenti fbshipit-source-id: b3f6f4a412557ba97e1f5fb63446c7ff9a2ff753
@astreet do you have any thoughts on my previous comment? |
Ah, that's a good point, you can listen from onConfigurationChanged.
The font scale for the window and the screen should be the same. Or am I misunderstanding you?
Same answer as above: the only reason window is deprecated is for consistency with iOS in width/height people are using (afaik), either will give the correct fontScale though |
Thanks, I will try using Regarding I'm confused about the deprecation of |
Re:
|
@andreicoman11 I see, thanks for the explanation. I suspect the code you linked to is not running on iOS. The reason is that the code is within an if statement checking for So based on code inspection, I don't think iOS currently supports |
Summary: cc astreet The goal of this PR is to enable the buck module `uimanager` to depend on `modules/core` without introducing any dependency cycles. PR #11008 relies on this PR. PR #11008 needs `uimanager` to depend on `modules/core` so that `uimanager` can fire events using `RCTDeviceEventEmitter` which is in `modules/core`. This PR moved a number of classes and interfaces: - `com.facebook.react.modules.debug.DeveloperSettings` -> `com.facebook.react.modules.debug.interfaces.DeveloperSettings` - `com.facebook.react.devsupport.DevOptionHandler` -> `com.facebook.react.devsupport.interfaces.DevOptionHandler ` - `com.facebook.react.devsupport.DevSupportManager` -> `com.facebook.react.devsupport.interfaces.DevSupportManager` - `com.facebook.react.devsupport.DevServerHelper.PackagerStatusCallback` -> `com.facebook.react.devsupport.interfaces.PackagerStatusCallback` - The class `com.facebook.react.devsupport.StackTraceHelper.StackFrame` was renamed to `StackFram Closes #12329 Differential Revision: D4551160 Pulled By: astreet fbshipit-source-id: 3a78443c4f30469b13ddfbdcc9bbef6af9e8381a
This gives apps the ability to find out the current scaling factor for fonts on the device.
This reverts commit 29c8093. Instead of exposing new getContentSizeMultiplier method, expose this information on Dimensions.get('screen').fontScale.
Here's a summary of the changes in this commit: - Breaking change: UIManager was exporting DisplayMetrics.scaledDensity under the name fontScale. However, scaledDensity is actually density * fontScale. We now correctly export just fontScale under the name fontScale. - The didUpdateDimensions event now fires when fontScale changes.
- Removed some unnecessary imports to fix some buck errors. - Added a missing dependency to a BUCK file. Unfortunately, it introduced a dependency cycle. I'm not sure how to break it yet.
emitUpdateDimensionsEvent shouldn't have side effects. Instead, set it in onHostResume.
The same helper function, getDimensionsConstants, is now used both when constructing the UIManager's initial constants object and when firing the didUpdateDimensions event.
… platform interface
bb214ef
to
55a9467
Compare
@astreet I did all of the changes we discussed. I rebased this on top of my commit for breaking dependency cycles and I added a |
Can we add tests for this? This is such an infrequent event that I'm worried we might break it accidentally and not realize it. |
@astreet has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
@astreet Tests for which event? Normally, firing these events requires rotating the device or changing the font scale settings. How do you propose to test it? For |
A related Android PR is facebook#11008. Font scale was exposed through the: - getContentSizeMultiplier method - didUpdateContentSizeMultiplier event These are now deprecated. The reason is that there was already an API that exposed font scale. However, it was Android only. We now expose font scale through that API on iOS as well. Specifically: - Font scale is now available as PixelRatio.getFontScale() on iOS. - The didUpdateDimensions event now fires when font scale changes.
This would be a test to make sure that when we detect a font scale change, that JS receives an update and triggers listeners. We have instrumentation tests that test JS and native code together here: https://github.com/facebook/react-native/tree/master/ReactAndroid/src/androidTest/java/com/facebook/react/tests. Simulating a configuration such that it changes between onResume calls might be difficult: since it's running as an actual Application on an actual device (so that we can test JS), we can't do standard mocking of static functions with PowerMockito afaik. An idea that comes to mind is creating a setter function on UIManager, but it's not great. Let me know if you have any ideas. Really sketchy other idea: fontScale on Configuration isn't final so you might be able to just manually set it... |
Summary: cc astreet The goal of this PR is to enable the buck module `uimanager` to depend on `modules/core` without introducing any dependency cycles. PR facebook#11008 relies on this PR. PR facebook#11008 needs `uimanager` to depend on `modules/core` so that `uimanager` can fire events using `RCTDeviceEventEmitter` which is in `modules/core`. This PR moved a number of classes and interfaces: - `com.facebook.react.modules.debug.DeveloperSettings` -> `com.facebook.react.modules.debug.interfaces.DeveloperSettings` - `com.facebook.react.devsupport.DevOptionHandler` -> `com.facebook.react.devsupport.interfaces.DevOptionHandler ` - `com.facebook.react.devsupport.DevSupportManager` -> `com.facebook.react.devsupport.interfaces.DevSupportManager` - `com.facebook.react.devsupport.DevServerHelper.PackagerStatusCallback` -> `com.facebook.react.devsupport.interfaces.PackagerStatusCallback` - The class `com.facebook.react.devsupport.StackTraceHelper.StackFrame` was renamed to `StackFram Closes facebook#12329 Differential Revision: D4551160 Pulled By: astreet fbshipit-source-id: 3a78443c4f30469b13ddfbdcc9bbef6af9e8381a
Summary: The PR description has been updated to reflect the new approach. **Breaking Change Summary** On Android, the following properties now return a different number: - `Dimensions.get('window').fontScale` - `Dimensions.get('screen').fontScale` - `PixelRatio.getFontScale()` This is a breaking change to anyone who was using these properties because the meaning of these properties has now changed. These properties used to return a value representing font scale times density ([`DisplayMetrics.scaledDensity`](https://developer.android.com/reference/android/util/DisplayMetrics.html#scaledDensity)). Now they return a value representing just font scale ([`Configuration.fontScale`](https://developer.android.com/reference/android/content/res/Configuration.html#fontScale)). **PR Description** This PR changes a few things: - Correctly exposes the font scale to JavaScript as `Dimensions.get('screen').fontScale`. UIManager was exporting `DisplayMetrics.scaledDensity` under the name `fontScale`. How Closes facebook#11008 Differential Revision: D4558207 Pulled By: astreet fbshipit-source-id: 096ce7b28051325dfd45fdb2a14b5e9b7d3bc46f
Summary: cc astreet The goal of this PR is to enable the buck module `uimanager` to depend on `modules/core` without introducing any dependency cycles. PR facebook#11008 relies on this PR. PR facebook#11008 needs `uimanager` to depend on `modules/core` so that `uimanager` can fire events using `RCTDeviceEventEmitter` which is in `modules/core`. This PR moved a number of classes and interfaces: - `com.facebook.react.modules.debug.DeveloperSettings` -> `com.facebook.react.modules.debug.interfaces.DeveloperSettings` - `com.facebook.react.devsupport.DevOptionHandler` -> `com.facebook.react.devsupport.interfaces.DevOptionHandler ` - `com.facebook.react.devsupport.DevSupportManager` -> `com.facebook.react.devsupport.interfaces.DevSupportManager` - `com.facebook.react.devsupport.DevServerHelper.PackagerStatusCallback` -> `com.facebook.react.devsupport.interfaces.PackagerStatusCallback` - The class `com.facebook.react.devsupport.StackTraceHelper.StackFrame` was renamed to `StackFram Closes facebook#12329 Differential Revision: D4551160 Pulled By: astreet fbshipit-source-id: 3a78443c4f30469b13ddfbdcc9bbef6af9e8381a
Summary: The PR description has been updated to reflect the new approach. **Breaking Change Summary** On Android, the following properties now return a different number: - `Dimensions.get('window').fontScale` - `Dimensions.get('screen').fontScale` - `PixelRatio.getFontScale()` This is a breaking change to anyone who was using these properties because the meaning of these properties has now changed. These properties used to return a value representing font scale times density ([`DisplayMetrics.scaledDensity`](https://developer.android.com/reference/android/util/DisplayMetrics.html#scaledDensity)). Now they return a value representing just font scale ([`Configuration.fontScale`](https://developer.android.com/reference/android/content/res/Configuration.html#fontScale)). **PR Description** This PR changes a few things: - Correctly exposes the font scale to JavaScript as `Dimensions.get('screen').fontScale`. UIManager was exporting `DisplayMetrics.scaledDensity` under the name `fontScale`. How Closes facebook#11008 Differential Revision: D4558207 Pulled By: astreet fbshipit-source-id: 096ce7b28051325dfd45fdb2a14b5e9b7d3bc46f
Summary: cc astreet The goal of this PR is to enable the buck module `uimanager` to depend on `modules/core` without introducing any dependency cycles. PR facebook#11008 relies on this PR. PR facebook#11008 needs `uimanager` to depend on `modules/core` so that `uimanager` can fire events using `RCTDeviceEventEmitter` which is in `modules/core`. This PR moved a number of classes and interfaces: - `com.facebook.react.modules.debug.DeveloperSettings` -> `com.facebook.react.modules.debug.interfaces.DeveloperSettings` - `com.facebook.react.devsupport.DevOptionHandler` -> `com.facebook.react.devsupport.interfaces.DevOptionHandler ` - `com.facebook.react.devsupport.DevSupportManager` -> `com.facebook.react.devsupport.interfaces.DevSupportManager` - `com.facebook.react.devsupport.DevServerHelper.PackagerStatusCallback` -> `com.facebook.react.devsupport.interfaces.PackagerStatusCallback` - The class `com.facebook.react.devsupport.StackTraceHelper.StackFrame` was renamed to `StackFram Closes facebook#12329 Differential Revision: D4551160 Pulled By: astreet fbshipit-source-id: 3a78443c4f30469b13ddfbdcc9bbef6af9e8381a
Summary: The PR description has been updated to reflect the new approach. **Breaking Change Summary** On Android, the following properties now return a different number: - `Dimensions.get('window').fontScale` - `Dimensions.get('screen').fontScale` - `PixelRatio.getFontScale()` This is a breaking change to anyone who was using these properties because the meaning of these properties has now changed. These properties used to return a value representing font scale times density ([`DisplayMetrics.scaledDensity`](https://developer.android.com/reference/android/util/DisplayMetrics.html#scaledDensity)). Now they return a value representing just font scale ([`Configuration.fontScale`](https://developer.android.com/reference/android/content/res/Configuration.html#fontScale)). **PR Description** This PR changes a few things: - Correctly exposes the font scale to JavaScript as `Dimensions.get('screen').fontScale`. UIManager was exporting `DisplayMetrics.scaledDensity` under the name `fontScale`. How Closes facebook#11008 Differential Revision: D4558207 Pulled By: astreet fbshipit-source-id: 096ce7b28051325dfd45fdb2a14b5e9b7d3bc46f
Summary: A related Android PR is #11008. Font scale was exposed through: - The `getContentSizeMultiplier` method - The `didUpdateContentSizeMultiplier` event These are now deprecated. The reason is that there was already an API that exposed font scale. However, it was Android only. We now expose font scale through that API on iOS as well. Specifically: - Font scale is now available as `PixelRatio.getFontScale()`. - The `change` event on the `Dimensions` object now fires when font scale changes. This change also adds support for `Dimensions.get('screen')` on iOS. Previously, only `Dimensions.get('window')` was available on iOS. The motivation is that, [according to this comment](#11008 (comment)), we'd like to deprecate `window` dimensions in favor of `screen` dimensions in the future. **Test plan (required)** Verified that `PixelRatio.getFontScale()` and the `change` event work properly in a test app. Adam Comella Microsoft Corp. Closes #12268 Differential Revision: D4673642 Pulled By: mkonicek fbshipit-source-id: 2602204da6998a96216e06f5321f28f6603e4972
Summary: cc astreet The goal of this PR is to enable the buck module `uimanager` to depend on `modules/core` without introducing any dependency cycles. PR facebook#11008 relies on this PR. PR facebook#11008 needs `uimanager` to depend on `modules/core` so that `uimanager` can fire events using `RCTDeviceEventEmitter` which is in `modules/core`. This PR moved a number of classes and interfaces: - `com.facebook.react.modules.debug.DeveloperSettings` -> `com.facebook.react.modules.debug.interfaces.DeveloperSettings` - `com.facebook.react.devsupport.DevOptionHandler` -> `com.facebook.react.devsupport.interfaces.DevOptionHandler ` - `com.facebook.react.devsupport.DevSupportManager` -> `com.facebook.react.devsupport.interfaces.DevSupportManager` - `com.facebook.react.devsupport.DevServerHelper.PackagerStatusCallback` -> `com.facebook.react.devsupport.interfaces.PackagerStatusCallback` - The class `com.facebook.react.devsupport.StackTraceHelper.StackFrame` was renamed to `StackFram Closes facebook#12329 Differential Revision: D4551160 Pulled By: astreet fbshipit-source-id: 3a78443c4f30469b13ddfbdcc9bbef6af9e8381a
The PR description has been updated to reflect the new approach.
Breaking Change Summary
On Android, the following properties now return a different number:
Dimensions.get('window').fontScale
Dimensions.get('screen').fontScale
PixelRatio.getFontScale()
This is a breaking change to anyone who was using these properties because the meaning of these properties has now changed.
These properties used to return a value representing font scale times density (
DisplayMetrics.scaledDensity
). Now they return a value representing just font scale (Configuration.fontScale
).PR Description
This PR changes a few things:
Dimensions.get('screen').fontScale
. UIManager was exportingDisplayMetrics.scaledDensity
under the namefontScale
. However, this isn't correct becausescaledDensity
is actuallydensity * fontScale
. We now correctly export justfontScale
under the namefontScale
.didUpdateDimensions
now fires wheneverfontScale
changes.Dimensions
now fires achange
event whenever a property within theDimensions
object changes. The primary benefit of this event overdidUpdateDimensions
is that this event provides an event object which has the same shape on iOS and Android. The event object fordidUpdateDimensions
uses different properties names on iOS than it does on Android.Test plan (required)
Verified that the API works for different font settings in a test app. Also, verified that the
didUpdateDimensions
andchange
events fire with the proper information when changing the font settings and when rotating the device.Adam Comella
Microsoft Corp.