-
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
Fix copy / paste menu and simplify controlled text selection on Android #37424
Conversation
Base commit: 61335a1 |
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.
So, we always go through viewCommands.setTextAndSelection()
? That makes sense to me I think.
A caveat for this change, because of how Meta ships React native to its own apps, we need to stage this so that the JS change can work with a ~1 week old native build. So, we would need to first land a version where the existing JS platform was compatible with a week old native, platform, before then removing prop-setting, etc from JS.
Fabric already uses only view commands, the prop is implemented but never used. For old arch it uses both the prop in shadow node as well as view commands. I will think about how we can roll this out and if this would cause issues. |
@NickGerleman I tested this and selection still works properly with only the JS changes. Even if we don't pass the selection prop it works since Fabric already doesn't use it and Paper uses both the prop and view commands. |
Ah, that makes sense 👍 |
@NickGerleman has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
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.
Great work @janicduplessis !
@NickGerleman merged this pull request in d4f6cf1. |
…id (#37424) Summary: Currently when using a TextInput with a controlled selection prop the Copy / Paste menu is constantly getting dismissed and is impossible to use. This is because Android dismisses it when certain method that affect the input text are called (https://cs.android.com/android/platform/superproject/+/refs/heads/master:frameworks/base/core/java/android/widget/Editor.java;l=1667;drc=7346c436e5a11ce08f6a80dcfeb8ef941ca30176?q=Editor, https://cs.android.com/android/platform/superproject/+/refs/heads/master:frameworks/base/core/java/android/widget/TextView.java;l=6792;drc=7346c436e5a11ce08f6a80dcfeb8ef941ca30176). The solution to fix this is to avoid calling those methods when only the selection changes. I also noticed there are a lot of differences on how selection is handled in old vs new arch and a lot of the selection handling can actually be removed as it is partially the cause of this issue. This implements 2 mitigations to avoid the issue: - Unify selection handling via commands for old arch, like fabric. Selection is currently a prop in the native component, but it is completely ignored in fabric and selection is set using commands. I removed the selection prop from the native component on Android so now it is exclusively handled with commands like it is currently for fabric. This makes it so that when the selection prop changes the native component no longer re-renders which helps mitigate this issue. More specifically for the old arch we no longer handle the `selection` prop in `ReactTextInputShadowNode`, which used to invalidate the shadow node and cause the text to be replaced and the copy / paste menu to close. - Only set placeholder if the text value changed. Calling `EditText.setHint` also causes the copy / paste menu to be dismissed. Fabric will call all props handlers when a single prop changed, so if the `selection` prop changed the `placeholder` prop handler would be called too. To fix this we can check that the value changed before calling `setHint`. ## Changelog: [ANDROID] [FIXED] - Fix copy / paste menu and simplify controlled text selection on Android Pull Request resolved: #37424 Test Plan: Tested on new and old arch in RNTester example. Before: https://github.com/facebook/react-native/assets/2677334/a915b62a-dd79-4adb-9d95-2317780431cf After: https://github.com/facebook/react-native/assets/2677334/0dd475ed-8981-410c-8908-f00998dcc425 Reviewed By: cortinico Differential Revision: D45958425 Pulled By: NickGerleman fbshipit-source-id: 7b90c1270274f6621303efa60b5398b1a49276ca # Conflicts: # packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java
…id (facebook#37424) Summary: Currently when using a TextInput with a controlled selection prop the Copy / Paste menu is constantly getting dismissed and is impossible to use. This is because Android dismisses it when certain method that affect the input text are called (https://cs.android.com/android/platform/superproject/+/refs/heads/master:frameworks/base/core/java/android/widget/Editor.java;l=1667;drc=7346c436e5a11ce08f6a80dcfeb8ef941ca30176?q=Editor, https://cs.android.com/android/platform/superproject/+/refs/heads/master:frameworks/base/core/java/android/widget/TextView.java;l=6792;drc=7346c436e5a11ce08f6a80dcfeb8ef941ca30176). The solution to fix this is to avoid calling those methods when only the selection changes. I also noticed there are a lot of differences on how selection is handled in old vs new arch and a lot of the selection handling can actually be removed as it is partially the cause of this issue. This implements 2 mitigations to avoid the issue: - Unify selection handling via commands for old arch, like fabric. Selection is currently a prop in the native component, but it is completely ignored in fabric and selection is set using commands. I removed the selection prop from the native component on Android so now it is exclusively handled with commands like it is currently for fabric. This makes it so that when the selection prop changes the native component no longer re-renders which helps mitigate this issue. More specifically for the old arch we no longer handle the `selection` prop in `ReactTextInputShadowNode`, which used to invalidate the shadow node and cause the text to be replaced and the copy / paste menu to close. - Only set placeholder if the text value changed. Calling `EditText.setHint` also causes the copy / paste menu to be dismissed. Fabric will call all props handlers when a single prop changed, so if the `selection` prop changed the `placeholder` prop handler would be called too. To fix this we can check that the value changed before calling `setHint`. ## Changelog: [ANDROID] [FIXED] - Fix copy / paste menu and simplify controlled text selection on Android Pull Request resolved: facebook#37424 Test Plan: Tested on new and old arch in RNTester example. Before: https://github.com/facebook/react-native/assets/2677334/a915b62a-dd79-4adb-9d95-2317780431cf After: https://github.com/facebook/react-native/assets/2677334/0dd475ed-8981-410c-8908-f00998dcc425 Reviewed By: cortinico Differential Revision: D45958425 Pulled By: NickGerleman fbshipit-source-id: 7b90c1270274f6621303efa60b5398b1a49276ca # Conflicts: # packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java (cherry picked from commit dfc64d5)
Summary:
Currently when using a TextInput with a controlled selection prop the Copy / Paste menu is constantly getting dismissed and is impossible to use. This is because Android dismisses it when certain method that affect the input text are called (https://cs.android.com/android/platform/superproject/+/refs/heads/master:frameworks/base/core/java/android/widget/Editor.java;l=1667;drc=7346c436e5a11ce08f6a80dcfeb8ef941ca30176?q=Editor, https://cs.android.com/android/platform/superproject/+/refs/heads/master:frameworks/base/core/java/android/widget/TextView.java;l=6792;drc=7346c436e5a11ce08f6a80dcfeb8ef941ca30176). The solution to fix this is to avoid calling those methods when only the selection changes.
I also noticed there are a lot of differences on how selection is handled in old vs new arch and a lot of the selection handling can actually be removed as it is partially the cause of this issue.
This implements 2 mitigations to avoid the issue:
Unify selection handling via commands for old arch, like fabric. Selection is currently a prop in the native component, but it is completely ignored in fabric and selection is set using commands. I removed the selection prop from the native component on Android so now it is exclusively handled with commands like it is currently for fabric. This makes it so that when the selection prop changes the native component no longer re-renders which helps mitigate this issue. More specifically for the old arch we no longer handle the
selection
prop inReactTextInputShadowNode
, which used to invalidate the shadow node and cause the text to be replaced and the copy / paste menu to close.Only set placeholder if the text value changed. Calling
EditText.setHint
also causes the copy / paste menu to be dismissed. Fabric will call all props handlers when a single prop changed, so if theselection
prop changed theplaceholder
prop handler would be called too. To fix this we can check that the value changed before callingsetHint
.Changelog:
[ANDROID] [FIXED] - Fix copy / paste menu and simplify controlled text selection on Android
Test Plan:
Tested on new and old arch in RNTester example.
Before:
Screen.Recording.2023-05-13.at.11.56.49.mov
After:
Screen.Recording.2023-05-13.at.11.52.16.mov