Skip to content

Commit 718174f

Browse files
joevilchesfacebook-github-bot
authored andcommitted
Back out "Clean up useEditTextStockAndroidFocusBehavior feature flag"
Summary: Original commit changeset: 4682cf709aa2 Original Phabricator Diff: D73954790 I want to pick this into 0.80 so users can enable the feature flag so this doesn't break older versions Changelog: [Internal] Reviewed By: NickGerleman Differential Revision: D74754010
1 parent a356ceb commit 718174f

22 files changed

+189
-30
lines changed

packages/react-native/ReactAndroid/api/ReactAndroid.api

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6553,6 +6553,7 @@ public class com/facebook/react/views/textinput/ReactEditText : androidx/appcomp
65536553
public fun onTextContextMenuItem (I)Z
65546554
public fun onTouchEvent (Landroid/view/MotionEvent;)Z
65556555
public fun removeTextChangedListener (Landroid/text/TextWatcher;)V
6556+
public fun requestFocus (ILandroid/graphics/Rect;)Z
65566557
public final fun requestFocusFromJS ()V
65576558
public final fun setAllowFontScaling (Z)V
65586559
public final fun setAutoFocus (Z)V

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<e9a109fd77667dd0cb945ef6ef9737f2>>
7+
* @generated SignedSource<<2c8ff840fe0597ee9f1845ec2e3fa629>>
88
*/
99

1010
/**
@@ -276,6 +276,12 @@ public object ReactNativeFeatureFlags {
276276
@JvmStatic
277277
public fun useAndroidTextLayoutWidthDirectly(): Boolean = accessor.useAndroidTextLayoutWidthDirectly()
278278

279+
/**
280+
* If true, focusing in ReactEditText will mainly use stock Android requestFocus() behavior. If false it will use legacy custom focus behavior.
281+
*/
282+
@JvmStatic
283+
public fun useEditTextStockAndroidFocusBehavior(): Boolean = accessor.useEditTextStockAndroidFocusBehavior()
284+
279285
/**
280286
* Should this application enable the Fabric Interop Layer for Android? If yes, the application will behave so that it can accept non-Fabric components and render them on Fabric. This toggle is controlling extra logic such as custom event dispatching that are needed for the Fabric Interop Layer to work correctly.
281287
*/

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<1a5cd689229d4e0c31070123045e84da>>
7+
* @generated SignedSource<<0a6e4183387e503158277e8b7e974bc5>>
88
*/
99

1010
/**
@@ -61,6 +61,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
6161
private var updateRuntimeShadowNodeReferencesOnCommitCache: Boolean? = null
6262
private var useAlwaysAvailableJSErrorHandlingCache: Boolean? = null
6363
private var useAndroidTextLayoutWidthDirectlyCache: Boolean? = null
64+
private var useEditTextStockAndroidFocusBehaviorCache: Boolean? = null
6465
private var useFabricInteropCache: Boolean? = null
6566
private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null
6667
private var useOptimizedEventBatchingOnAndroidCache: Boolean? = null
@@ -438,6 +439,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
438439
return cached
439440
}
440441

442+
override fun useEditTextStockAndroidFocusBehavior(): Boolean {
443+
var cached = useEditTextStockAndroidFocusBehaviorCache
444+
if (cached == null) {
445+
cached = ReactNativeFeatureFlagsCxxInterop.useEditTextStockAndroidFocusBehavior()
446+
useEditTextStockAndroidFocusBehaviorCache = cached
447+
}
448+
return cached
449+
}
450+
441451
override fun useFabricInterop(): Boolean {
442452
var cached = useFabricInteropCache
443453
if (cached == null) {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<c39d0c1834797b3309b4fc5ce814280c>>
7+
* @generated SignedSource<<ef2a0c31e32310ba392680894467c2ca>>
88
*/
99

1010
/**
@@ -110,6 +110,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
110110

111111
@DoNotStrip @JvmStatic public external fun useAndroidTextLayoutWidthDirectly(): Boolean
112112

113+
@DoNotStrip @JvmStatic public external fun useEditTextStockAndroidFocusBehavior(): Boolean
114+
113115
@DoNotStrip @JvmStatic public external fun useFabricInterop(): Boolean
114116

115117
@DoNotStrip @JvmStatic public external fun useNativeViewConfigsInBridgelessMode(): Boolean

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<7f357475254104729cc7910c14e1c1fb>>
7+
* @generated SignedSource<<c53f68e4ebac61f7a04133e6589adc1b>>
88
*/
99

1010
/**
@@ -105,6 +105,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
105105

106106
override fun useAndroidTextLayoutWidthDirectly(): Boolean = true
107107

108+
override fun useEditTextStockAndroidFocusBehavior(): Boolean = true
109+
108110
override fun useFabricInterop(): Boolean = true
109111

110112
override fun useNativeViewConfigsInBridgelessMode(): Boolean = false

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<14cd1a58bd153dedda045a72c1494caa>>
7+
* @generated SignedSource<<9d94cb3f7378ef24346a66cb0da746e9>>
88
*/
99

1010
/**
@@ -65,6 +65,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
6565
private var updateRuntimeShadowNodeReferencesOnCommitCache: Boolean? = null
6666
private var useAlwaysAvailableJSErrorHandlingCache: Boolean? = null
6767
private var useAndroidTextLayoutWidthDirectlyCache: Boolean? = null
68+
private var useEditTextStockAndroidFocusBehaviorCache: Boolean? = null
6869
private var useFabricInteropCache: Boolean? = null
6970
private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null
7071
private var useOptimizedEventBatchingOnAndroidCache: Boolean? = null
@@ -483,6 +484,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
483484
return cached
484485
}
485486

487+
override fun useEditTextStockAndroidFocusBehavior(): Boolean {
488+
var cached = useEditTextStockAndroidFocusBehaviorCache
489+
if (cached == null) {
490+
cached = currentProvider.useEditTextStockAndroidFocusBehavior()
491+
accessedFeatureFlags.add("useEditTextStockAndroidFocusBehavior")
492+
useEditTextStockAndroidFocusBehaviorCache = cached
493+
}
494+
return cached
495+
}
496+
486497
override fun useFabricInterop(): Boolean {
487498
var cached = useFabricInteropCache
488499
if (cached == null) {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<593b1d64dc31038140032a6b0a439700>>
7+
* @generated SignedSource<<85eb4d0a5e538bd028a4d33784fea741>>
88
*/
99

1010
/**
@@ -105,6 +105,8 @@ public interface ReactNativeFeatureFlagsProvider {
105105

106106
@DoNotStrip public fun useAndroidTextLayoutWidthDirectly(): Boolean
107107

108+
@DoNotStrip public fun useEditTextStockAndroidFocusBehavior(): Boolean
109+
108110
@DoNotStrip public fun useFabricInterop(): Boolean
109111

110112
@DoNotStrip public fun useNativeViewConfigsInBridgelessMode(): Boolean

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.kt

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import com.facebook.react.bridge.ReactSoftExceptionLogger.logSoftException
4747
import com.facebook.react.common.ReactConstants
4848
import com.facebook.react.common.build.ReactBuildConfig
4949
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
50+
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags.useEditTextStockAndroidFocusBehavior
5051
import com.facebook.react.internal.featureflags.ReactNativeNewArchitectureFeatureFlags
5152
import com.facebook.react.uimanager.BackgroundStyleApplicator.clipToPaddingBox
5253
import com.facebook.react.uimanager.BackgroundStyleApplicator.getBackgroundColor
@@ -197,6 +198,10 @@ public open class ReactEditText public constructor(context: Context) : AppCompat
197198
}
198199

199200
init {
201+
if (!useEditTextStockAndroidFocusBehavior()) {
202+
isFocusableInTouchMode = false
203+
}
204+
200205
inputMethodManager =
201206
context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
202207
defaultGravityHorizontal =
@@ -235,7 +240,8 @@ public open class ReactEditText public constructor(context: Context) : AppCompat
235240
// selection on accessibility click to undo that.
236241
setSelection(length)
237242
}
238-
return requestFocusProgrammatically()
243+
return if (useEditTextStockAndroidFocusBehavior()) requestFocusProgrammatically()
244+
else requestFocusInternal()
239245
}
240246
return super.performAccessibilityAction(host, action, args)
241247
}
@@ -360,10 +366,38 @@ public open class ReactEditText public constructor(context: Context) : AppCompat
360366
if (id == android.R.id.paste) android.R.id.pasteAsPlainText else id)
361367

362368
override fun clearFocus() {
369+
val useStockFocusBehavior = useEditTextStockAndroidFocusBehavior()
370+
if (!useStockFocusBehavior) {
371+
isFocusableInTouchMode = false
372+
}
363373
super.clearFocus()
364374
hideSoftKeyboard()
365375
}
366376

377+
override fun requestFocus(direction: Int, previouslyFocusedRect: Rect?): Boolean =
378+
// This is a no-op so that when the OS calls requestFocus(), nothing will happen.
379+
// ReactEditText
380+
// is a controlled component, which means its focus is controlled by JS, with two exceptions:
381+
// autofocus when it's attached to the window, and responding to accessibility events. In both
382+
// of these cases, we call requestFocusInternal() directly.
383+
if (useEditTextStockAndroidFocusBehavior()) {
384+
super.requestFocus(direction, previouslyFocusedRect)
385+
} else {
386+
isFocused
387+
}
388+
389+
private fun requestFocusInternal(): Boolean {
390+
isFocusableInTouchMode = true
391+
// We must explicitly call this method on the super class; if we call requestFocus() without
392+
// any arguments, it will call into the overridden requestFocus(int, Rect) above, which no-ops.
393+
val focused = super.requestFocus(FOCUS_DOWN, null)
394+
if (showSoftInputOnFocus) {
395+
showSoftKeyboard()
396+
}
397+
398+
return focused
399+
}
400+
367401
// For cases like autoFocus, or ref.focus() where we request focus programmatically and not
368402
// through
369403
// interacting with the EditText directly (like clicking on it). We cannot use stock
@@ -595,7 +629,11 @@ public open class ReactEditText public constructor(context: Context) : AppCompat
595629
}
596630

597631
public fun requestFocusFromJS() {
598-
requestFocusProgrammatically()
632+
if (useEditTextStockAndroidFocusBehavior()) {
633+
requestFocusProgrammatically()
634+
} else {
635+
requestFocusInternal()
636+
}
599637
}
600638

601639
internal fun clearFocusFromJS() {
@@ -945,7 +983,11 @@ public open class ReactEditText public constructor(context: Context) : AppCompat
945983
}
946984

947985
if (autoFocus && !didAttachToWindow) {
948-
requestFocusProgrammatically()
986+
if (useEditTextStockAndroidFocusBehavior()) {
987+
requestFocusProgrammatically()
988+
} else {
989+
requestFocusInternal()
990+
}
949991
}
950992

951993
didAttachToWindow = true

packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<d74dc8182a14fddbd7118149298515bd>>
7+
* @generated SignedSource<<f7db897c6e1f59c494c8b7cebea7c942>>
88
*/
99

1010
/**
@@ -285,6 +285,12 @@ class ReactNativeFeatureFlagsJavaProvider
285285
return method(javaProvider_);
286286
}
287287

288+
bool useEditTextStockAndroidFocusBehavior() override {
289+
static const auto method =
290+
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("useEditTextStockAndroidFocusBehavior");
291+
return method(javaProvider_);
292+
}
293+
288294
bool useFabricInterop() override {
289295
static const auto method =
290296
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("useFabricInterop");
@@ -536,6 +542,11 @@ bool JReactNativeFeatureFlagsCxxInterop::useAndroidTextLayoutWidthDirectly(
536542
return ReactNativeFeatureFlags::useAndroidTextLayoutWidthDirectly();
537543
}
538544

545+
bool JReactNativeFeatureFlagsCxxInterop::useEditTextStockAndroidFocusBehavior(
546+
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
547+
return ReactNativeFeatureFlags::useEditTextStockAndroidFocusBehavior();
548+
}
549+
539550
bool JReactNativeFeatureFlagsCxxInterop::useFabricInterop(
540551
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
541552
return ReactNativeFeatureFlags::useFabricInterop();
@@ -725,6 +736,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
725736
makeNativeMethod(
726737
"useAndroidTextLayoutWidthDirectly",
727738
JReactNativeFeatureFlagsCxxInterop::useAndroidTextLayoutWidthDirectly),
739+
makeNativeMethod(
740+
"useEditTextStockAndroidFocusBehavior",
741+
JReactNativeFeatureFlagsCxxInterop::useEditTextStockAndroidFocusBehavior),
728742
makeNativeMethod(
729743
"useFabricInterop",
730744
JReactNativeFeatureFlagsCxxInterop::useFabricInterop),

packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<a5ab0022f6a01bd6e929d36d9d87db10>>
7+
* @generated SignedSource<<69f0ab1339e848cb292cc6612e7776f3>>
88
*/
99

1010
/**
@@ -153,6 +153,9 @@ class JReactNativeFeatureFlagsCxxInterop
153153
static bool useAndroidTextLayoutWidthDirectly(
154154
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
155155

156+
static bool useEditTextStockAndroidFocusBehavior(
157+
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
158+
156159
static bool useFabricInterop(
157160
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
158161

0 commit comments

Comments
 (0)