Skip to content
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<<2fc347cdb33327437d29e5fd91e24011>>
* @generated SignedSource<<b8337f9ceefd811c5e82ec930e4bc387>>
*/

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

/**
* Android views that declare a gesture-responder handler (e.g. PanResponder) register a no-op touch listener so they can be recognized as interactable.
*/
@JvmStatic
public fun enableInteractableResponderViews(): Boolean = accessor.enableInteractableResponderViews()

/**
* This is to fix the issue with interop view manager where component descriptor lookup is causing ViewManager to preload.
*/
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<<a506d2515fce404e19bd61099cc60117>>
* @generated SignedSource<<3adaf496717c56f69757170a5b8208c0>>
*/

/**
Expand Down Expand Up @@ -52,6 +52,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
private var enableImageTransparentTintColorCache: Boolean? = null
private var enableImmediateUpdateModeForContentOffsetChangesCache: Boolean? = null
private var enableImperativeFocusCache: Boolean? = null
private var enableInteractableResponderViewsCache: Boolean? = null
private var enableInteropViewManagerClassLookUpOptimizationIOSCache: Boolean? = null
private var enableIntersectionObserverByDefaultCache: Boolean? = null
private var enableKeyEventsCache: Boolean? = null
Expand Down Expand Up @@ -396,6 +397,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
return cached
}

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

override fun enableInteropViewManagerClassLookUpOptimizationIOS(): Boolean {
var cached = enableInteropViewManagerClassLookUpOptimizationIOSCache
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<<1ef72233f02973021b83bd2e2aa1f69b>>
* @generated SignedSource<<f2f7056ba727479213f1a0a18d70ee3b>>
*/

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

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

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

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

@DoNotStrip @JvmStatic public external fun enableIntersectionObserverByDefault(): 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<<eb9958ddc04dd1cd8d1add366f5f7741>>
* @generated SignedSource<<680eb7406c435cb37b10a8e21e705cea>>
*/

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

override fun enableImperativeFocus(): Boolean = false

override fun enableInteractableResponderViews(): Boolean = false

override fun enableInteropViewManagerClassLookUpOptimizationIOS(): Boolean = false

override fun enableIntersectionObserverByDefault(): 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<<9ae32c46a5a6310ef96eb91c9ea5b12e>>
* @generated SignedSource<<7a2efa683876c41f0007310c9d23bef2>>
*/

/**
Expand Down Expand Up @@ -56,6 +56,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
private var enableImageTransparentTintColorCache: Boolean? = null
private var enableImmediateUpdateModeForContentOffsetChangesCache: Boolean? = null
private var enableImperativeFocusCache: Boolean? = null
private var enableInteractableResponderViewsCache: Boolean? = null
private var enableInteropViewManagerClassLookUpOptimizationIOSCache: Boolean? = null
private var enableIntersectionObserverByDefaultCache: Boolean? = null
private var enableKeyEventsCache: Boolean? = null
Expand Down Expand Up @@ -432,6 +433,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
return cached
}

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

override fun enableInteropViewManagerClassLookUpOptimizationIOS(): Boolean {
var cached = enableInteropViewManagerClassLookUpOptimizationIOSCache
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<<1a1d47f2d85404c776e55db40f7dbc6e>>
* @generated SignedSource<<4392a0cc206a741ac53a14dba50de3e8>>
*/

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

@DoNotStrip public fun enableImperativeFocus(): Boolean

@DoNotStrip public fun enableInteractableResponderViews(): Boolean

@DoNotStrip public fun enableInteropViewManagerClassLookUpOptimizationIOS(): Boolean

@DoNotStrip public fun enableIntersectionObserverByDefault(): Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags;
import com.facebook.react.uimanager.ReactAccessibilityDelegate.AccessibilityRole;
import com.facebook.react.uimanager.ReactAccessibilityDelegate.Role;
import com.facebook.react.uimanager.annotations.ReactProp;
Expand Down Expand Up @@ -64,6 +65,8 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
private static final String STATE_EXPANDED = "expanded";
private static final String STATE_MIXED = "mixed";

private static final View.OnTouchListener NOOP_LISTENER = (v, event) -> false;

public BaseViewManager() {
super(null);
}
Expand Down Expand Up @@ -150,6 +153,7 @@ public BaseViewManager(@Nullable ReactApplicationContext reactContext) {
// NOTE: setClickable MUST be called AFTER setOnClickListener because
// the latter has the side effect of setting isClickable=true on some views!
view.setOnClickListener(null);
setInteractable(view, false);
view.setClickable(false);
view.setFocusable(false);
view.setFocusableInTouchMode(false);
Expand Down Expand Up @@ -960,7 +964,24 @@ public void setMoveShouldSetResponderCapture(@NonNull T view, boolean value) {

@ReactProp(name = "onStartShouldSetResponder")
public void setStartShouldSetResponder(@NonNull T view, boolean value) {
// no-op, handled by JSResponder
// Touch handled by the JSResponder system, but listener is needed to indicate interactability.
setInteractable(view, value);
}

private static void setInteractable(@NonNull View view, boolean interactable) {
if (!ReactNativeFeatureFlags.enableInteractableResponderViews()) {
return;
}
boolean noopListener = view.getTag(R.id.noop_touch_listener) != null;
if (interactable) {
if (!noopListener) {
view.setOnTouchListener(NOOP_LISTENER);
view.setTag(R.id.noop_touch_listener, Boolean.TRUE);
}
} else if (noopListener) {
view.setOnTouchListener(null);
view.setTag(R.id.noop_touch_listener, null);
}
}

@ReactProp(name = "onStartShouldSetResponderCapture")
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<<28de1e205f30135e96d5cb94a902faec>>
* @generated SignedSource<<d961f98c7fe7188d3d8dc1905969a6c4>>
*/

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

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

bool enableInteropViewManagerClassLookUpOptimizationIOS() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableInteropViewManagerClassLookUpOptimizationIOS");
Expand Down Expand Up @@ -725,6 +731,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableImperativeFocus(
return ReactNativeFeatureFlags::enableImperativeFocus();
}

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

bool JReactNativeFeatureFlagsCxxInterop::enableInteropViewManagerClassLookUpOptimizationIOS(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableInteropViewManagerClassLookUpOptimizationIOS();
Expand Down Expand Up @@ -1127,6 +1138,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
makeNativeMethod(
"enableImperativeFocus",
JReactNativeFeatureFlagsCxxInterop::enableImperativeFocus),
makeNativeMethod(
"enableInteractableResponderViews",
JReactNativeFeatureFlagsCxxInterop::enableInteractableResponderViews),
makeNativeMethod(
"enableInteropViewManagerClassLookUpOptimizationIOS",
JReactNativeFeatureFlagsCxxInterop::enableInteropViewManagerClassLookUpOptimizationIOS),
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<<535898dd9498c65f30d56122c06b408b>>
* @generated SignedSource<<a20d534450537bfc8ac8ef1cfbcc23aa>>
*/

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

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

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,7 @@

<!-- tag is used to store important_for_interaction state -->
<item type="id" name="important_for_interaction"/>

<!-- tag marks that BaseViewManager installed the no-op touch listener -->
<item type="id" name="noop_touch_listener"/>
</resources>
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<<8fd664cb106945e5c6e436a0cf36120d>>
* @generated SignedSource<<feb416809e8464b6bdfbeac4b8d76c72>>
*/

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

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

bool ReactNativeFeatureFlags::enableInteropViewManagerClassLookUpOptimizationIOS() {
return getAccessor().enableInteropViewManagerClassLookUpOptimizationIOS();
}
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<<196ba25b807fd064ca6150c7d2cd741c>>
* @generated SignedSource<<aecf7c39b22b27891d299b9d4ccbba95>>
*/

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

/**
* Android views that declare a gesture-responder handler (e.g. PanResponder) register a no-op touch listener so they can be recognized as interactable.
*/
RN_EXPORT static bool enableInteractableResponderViews();

/**
* This is to fix the issue with interop view manager where component descriptor lookup is causing ViewManager to preload.
*/
Expand Down
Loading
Loading