Skip to content

Back out "Clean up useEditTextStockAndroidFocusBehavior feature flag" #51359

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<e9a109fd77667dd0cb945ef6ef9737f2>>
* @generated SignedSource<<2c8ff840fe0597ee9f1845ec2e3fa629>>
*/

/**
Expand Down Expand Up @@ -276,6 +276,12 @@ public object ReactNativeFeatureFlags {
@JvmStatic
public fun useAndroidTextLayoutWidthDirectly(): Boolean = accessor.useAndroidTextLayoutWidthDirectly()

/**
* If true, focusing in ReactEditText will mainly use stock Android requestFocus() behavior. If false it will use legacy custom focus behavior.
*/
@JvmStatic
public fun useEditTextStockAndroidFocusBehavior(): Boolean = accessor.useEditTextStockAndroidFocusBehavior()

/**
* 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.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<1a5cd689229d4e0c31070123045e84da>>
* @generated SignedSource<<0a6e4183387e503158277e8b7e974bc5>>
*/

/**
Expand Down Expand Up @@ -61,6 +61,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
private var updateRuntimeShadowNodeReferencesOnCommitCache: Boolean? = null
private var useAlwaysAvailableJSErrorHandlingCache: Boolean? = null
private var useAndroidTextLayoutWidthDirectlyCache: Boolean? = null
private var useEditTextStockAndroidFocusBehaviorCache: Boolean? = null
private var useFabricInteropCache: Boolean? = null
private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null
private var useOptimizedEventBatchingOnAndroidCache: Boolean? = null
Expand Down Expand Up @@ -438,6 +439,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
return cached
}

override fun useEditTextStockAndroidFocusBehavior(): Boolean {
var cached = useEditTextStockAndroidFocusBehaviorCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.useEditTextStockAndroidFocusBehavior()
useEditTextStockAndroidFocusBehaviorCache = cached
}
return cached
}

override fun useFabricInterop(): Boolean {
var cached = useFabricInteropCache
if (cached == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<c39d0c1834797b3309b4fc5ce814280c>>
* @generated SignedSource<<ef2a0c31e32310ba392680894467c2ca>>
*/

/**
Expand Down Expand Up @@ -110,6 +110,8 @@ public object ReactNativeFeatureFlagsCxxInterop {

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

@DoNotStrip @JvmStatic public external fun useEditTextStockAndroidFocusBehavior(): Boolean

@DoNotStrip @JvmStatic public external fun useFabricInterop(): Boolean

@DoNotStrip @JvmStatic public external fun useNativeViewConfigsInBridgelessMode(): Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<7f357475254104729cc7910c14e1c1fb>>
* @generated SignedSource<<c53f68e4ebac61f7a04133e6589adc1b>>
*/

/**
Expand Down Expand Up @@ -105,6 +105,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi

override fun useAndroidTextLayoutWidthDirectly(): Boolean = true

override fun useEditTextStockAndroidFocusBehavior(): Boolean = true

override fun useFabricInterop(): Boolean = true

override fun useNativeViewConfigsInBridgelessMode(): Boolean = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<14cd1a58bd153dedda045a72c1494caa>>
* @generated SignedSource<<9d94cb3f7378ef24346a66cb0da746e9>>
*/

/**
Expand Down Expand Up @@ -65,6 +65,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
private var updateRuntimeShadowNodeReferencesOnCommitCache: Boolean? = null
private var useAlwaysAvailableJSErrorHandlingCache: Boolean? = null
private var useAndroidTextLayoutWidthDirectlyCache: Boolean? = null
private var useEditTextStockAndroidFocusBehaviorCache: Boolean? = null
private var useFabricInteropCache: Boolean? = null
private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null
private var useOptimizedEventBatchingOnAndroidCache: Boolean? = null
Expand Down Expand Up @@ -483,6 +484,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
return cached
}

override fun useEditTextStockAndroidFocusBehavior(): Boolean {
var cached = useEditTextStockAndroidFocusBehaviorCache
if (cached == null) {
cached = currentProvider.useEditTextStockAndroidFocusBehavior()
accessedFeatureFlags.add("useEditTextStockAndroidFocusBehavior")
useEditTextStockAndroidFocusBehaviorCache = cached
}
return cached
}

override fun useFabricInterop(): Boolean {
var cached = useFabricInteropCache
if (cached == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<593b1d64dc31038140032a6b0a439700>>
* @generated SignedSource<<85eb4d0a5e538bd028a4d33784fea741>>
*/

/**
Expand Down Expand Up @@ -105,6 +105,8 @@ public interface ReactNativeFeatureFlagsProvider {

@DoNotStrip public fun useAndroidTextLayoutWidthDirectly(): Boolean

@DoNotStrip public fun useEditTextStockAndroidFocusBehavior(): Boolean

@DoNotStrip public fun useFabricInterop(): Boolean

@DoNotStrip public fun useNativeViewConfigsInBridgelessMode(): Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import com.facebook.react.bridge.ReactSoftExceptionLogger.logSoftException
import com.facebook.react.common.ReactConstants
import com.facebook.react.common.build.ReactBuildConfig
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags.useEditTextStockAndroidFocusBehavior
import com.facebook.react.internal.featureflags.ReactNativeNewArchitectureFeatureFlags
import com.facebook.react.uimanager.BackgroundStyleApplicator.clipToPaddingBox
import com.facebook.react.uimanager.BackgroundStyleApplicator.getBackgroundColor
Expand Down Expand Up @@ -197,6 +198,10 @@ public open class ReactEditText public constructor(context: Context) : AppCompat
}

init {
if (!useEditTextStockAndroidFocusBehavior()) {
isFocusableInTouchMode = false
}

inputMethodManager =
context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
defaultGravityHorizontal =
Expand Down Expand Up @@ -235,7 +240,8 @@ public open class ReactEditText public constructor(context: Context) : AppCompat
// selection on accessibility click to undo that.
setSelection(length)
}
return requestFocusProgrammatically()
return if (useEditTextStockAndroidFocusBehavior()) requestFocusProgrammatically()
else requestFocusInternal()
}
return super.performAccessibilityAction(host, action, args)
}
Expand Down Expand Up @@ -360,27 +366,41 @@ public open class ReactEditText public constructor(context: Context) : AppCompat
if (id == android.R.id.paste) android.R.id.pasteAsPlainText else id)

override fun clearFocus() {
val useStockFocusBehavior = useEditTextStockAndroidFocusBehavior()
if (!useStockFocusBehavior) {
isFocusableInTouchMode = false
}
super.clearFocus()
hideSoftKeyboard()
}

override fun requestFocus(direction: Int, previouslyFocusedRect: Rect?): Boolean {
// On some older versions of Android there is a bug where `clearFocus` will try to focus the
// first focusable View in the hierarchy after clearing focus. This is intended behavior, but
// only if you are not in touch mode per
// https://developer.android.com/reference/android/view/View#clearFocus(), yet this happens in
// both. Therefore, we are swallowing Android-based focus calls if we are in touch mode.
// If we are not in touch mode (using a hardware keyboard) then we will allow this to happen.
// Note this only happens for Android-origin focus calls, as opposed to JS-origin (like tapping)
// since those go through `requestFocusProgrammatically`
if (isInTouchMode) {
return isFocused
override fun requestFocus(direction: Int, previouslyFocusedRect: Rect?): Boolean =
// This is a no-op so that when the OS calls requestFocus(), nothing will happen.
// ReactEditText
// is a controlled component, which means its focus is controlled by JS, with two exceptions:
// autofocus when it's attached to the window, and responding to accessibility events. In both
// of these cases, we call requestFocusInternal() directly.
if (useEditTextStockAndroidFocusBehavior()) {
super.requestFocus(direction, previouslyFocusedRect)
} else {
isFocused
}

private fun requestFocusInternal(): Boolean {
isFocusableInTouchMode = true
// We must explicitly call this method on the super class; if we call requestFocus() without
// any arguments, it will call into the overridden requestFocus(int, Rect) above, which no-ops.
val focused = super.requestFocus(FOCUS_DOWN, null)
if (showSoftInputOnFocus) {
showSoftKeyboard()
}
return super.requestFocus(direction, previouslyFocusedRect)

return focused
}

// For cases like autoFocus, or ref.focus() where we request focus programmatically and not
// through interacting with the EditText directly (like clicking on it). We cannot use stock
// through
// interacting with the EditText directly (like clicking on it). We cannot use stock
// requestFocus() because it will not pop up the soft keyboard, only clicking the input will do
// that. This method will eventually replace requestFocusInternal()
private fun requestFocusProgrammatically(): Boolean {
Expand Down Expand Up @@ -609,7 +629,11 @@ public open class ReactEditText public constructor(context: Context) : AppCompat
}

public fun requestFocusFromJS() {
requestFocusProgrammatically()
if (useEditTextStockAndroidFocusBehavior()) {
requestFocusProgrammatically()
} else {
requestFocusInternal()
}
}

internal fun clearFocusFromJS() {
Expand Down Expand Up @@ -959,7 +983,11 @@ public open class ReactEditText public constructor(context: Context) : AppCompat
}

if (autoFocus && !didAttachToWindow) {
requestFocusProgrammatically()
if (useEditTextStockAndroidFocusBehavior()) {
requestFocusProgrammatically()
} else {
requestFocusInternal()
}
}

didAttachToWindow = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<d74dc8182a14fddbd7118149298515bd>>
* @generated SignedSource<<f7db897c6e1f59c494c8b7cebea7c942>>
*/

/**
Expand Down Expand Up @@ -285,6 +285,12 @@ class ReactNativeFeatureFlagsJavaProvider
return method(javaProvider_);
}

bool useEditTextStockAndroidFocusBehavior() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("useEditTextStockAndroidFocusBehavior");
return method(javaProvider_);
}

bool useFabricInterop() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("useFabricInterop");
Expand Down Expand Up @@ -536,6 +542,11 @@ bool JReactNativeFeatureFlagsCxxInterop::useAndroidTextLayoutWidthDirectly(
return ReactNativeFeatureFlags::useAndroidTextLayoutWidthDirectly();
}

bool JReactNativeFeatureFlagsCxxInterop::useEditTextStockAndroidFocusBehavior(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::useEditTextStockAndroidFocusBehavior();
}

bool JReactNativeFeatureFlagsCxxInterop::useFabricInterop(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::useFabricInterop();
Expand Down Expand Up @@ -725,6 +736,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
makeNativeMethod(
"useAndroidTextLayoutWidthDirectly",
JReactNativeFeatureFlagsCxxInterop::useAndroidTextLayoutWidthDirectly),
makeNativeMethod(
"useEditTextStockAndroidFocusBehavior",
JReactNativeFeatureFlagsCxxInterop::useEditTextStockAndroidFocusBehavior),
makeNativeMethod(
"useFabricInterop",
JReactNativeFeatureFlagsCxxInterop::useFabricInterop),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<a5ab0022f6a01bd6e929d36d9d87db10>>
* @generated SignedSource<<69f0ab1339e848cb292cc6612e7776f3>>
*/

/**
Expand Down Expand Up @@ -153,6 +153,9 @@ class JReactNativeFeatureFlagsCxxInterop
static bool useAndroidTextLayoutWidthDirectly(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);

static bool useEditTextStockAndroidFocusBehavior(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);

static bool useFabricInterop(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<88fdbea2f97f628187164a47a9737da0>>
* @generated SignedSource<<1a4a09ac92cba613c186ddfabcb14b31>>
*/

/**
Expand Down Expand Up @@ -190,6 +190,10 @@ bool ReactNativeFeatureFlags::useAndroidTextLayoutWidthDirectly() {
return getAccessor().useAndroidTextLayoutWidthDirectly();
}

bool ReactNativeFeatureFlags::useEditTextStockAndroidFocusBehavior() {
return getAccessor().useEditTextStockAndroidFocusBehavior();
}

bool ReactNativeFeatureFlags::useFabricInterop() {
return getAccessor().useFabricInterop();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<a4123bc6f44835c022a1a5238908674c>>
* @generated SignedSource<<3e716502e96c4b39f70df4beca076acf>>
*/

/**
Expand Down Expand Up @@ -244,6 +244,11 @@ class ReactNativeFeatureFlags {
*/
RN_EXPORT static bool useAndroidTextLayoutWidthDirectly();

/**
* If true, focusing in ReactEditText will mainly use stock Android requestFocus() behavior. If false it will use legacy custom focus behavior.
*/
RN_EXPORT static bool useEditTextStockAndroidFocusBehavior();

/**
* 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.
*/
Expand Down
Loading
Loading