Skip to content

Commit 1c8f297

Browse files
fabriziocuccimeta-codesync[bot]
authored andcommitted
Sync clipChildren with overflow: hidden (#55368)
Summary: Pull Request resolved: #55368 Changelog: [Internal] We found an issue (T253147322) in the LivingRoom top bar where a full-screen OCPanel within a parent with `overflow: hidden` occludes content outside the parent (see [code](https://www.internalfb.com/code/fbsource/[753feac76cb1]/arvr/js/apps/LivingRoom/src/ReactNative/App/HTV/Shared/Toolbar/LivingRoomToolbar.react.js?lines=85-96)). This change adds a feature flag `enableClipChildrenForOverflowHidden` that, when enabled, sets `clipChildren = true` whenever `overflow: hidden` is set. This makes `TouchTargetHelper` also reject touches on children outside the parent's bounds (see [code](https://www.internalfb.com/code/fbsource/[753feac76cb1]/xplat/js/react-native-github/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/TouchTargetHelper.kt?lines=211-213)), aligning hit testing behavior with visual rendering. The fix is gated behind a feature flag to allow gradual rollout and prevent potential regressions in apps that may rely on the current behavior. Reviewed By: Abbondanzo Differential Revision: D91775635 fbshipit-source-id: a1bf9bbd7ea9ff71ac4e7cf407b6d5328272bf00
1 parent a640790 commit 1c8f297

21 files changed

Lines changed: 202 additions & 83 deletions

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<<1d13409e4db7a5a48e5d2caf59a5fbcf>>
7+
* @generated SignedSource<<f04d7cddd72c435fcce120b71366c81c>>
88
*/
99

1010
/**
@@ -120,6 +120,12 @@ public object ReactNativeFeatureFlags {
120120
@JvmStatic
121121
public fun enableBridgelessArchitecture(): Boolean = accessor.enableBridgelessArchitecture()
122122

123+
/**
124+
* When overflow: hidden is set, also set clipChildren to true so that clipped content does not occlude content outside the parent
125+
*/
126+
@JvmStatic
127+
public fun enableClipChildrenForOverflowHidden(): Boolean = accessor.enableClipChildrenForOverflowHidden()
128+
123129
/**
124130
* Enable prop iterator setter-style construction of Props in C++ (this flag is not used in Java).
125131
*/

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<<58a693fe003a9a19311fc0134d071154>>
7+
* @generated SignedSource<<9158cc3ba1ea8ea65140b582a02a5112>>
88
*/
99

1010
/**
@@ -35,6 +35,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
3535
private var enableAndroidLinearTextCache: Boolean? = null
3636
private var enableAndroidTextMeasurementOptimizationsCache: Boolean? = null
3737
private var enableBridgelessArchitectureCache: Boolean? = null
38+
private var enableClipChildrenForOverflowHiddenCache: Boolean? = null
3839
private var enableCppPropsIteratorSetterCache: Boolean? = null
3940
private var enableCustomFocusSearchOnClippedElementsAndroidCache: Boolean? = null
4041
private var enableDestroyShadowTreeRevisionAsyncCache: Boolean? = null
@@ -234,6 +235,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
234235
return cached
235236
}
236237

238+
override fun enableClipChildrenForOverflowHidden(): Boolean {
239+
var cached = enableClipChildrenForOverflowHiddenCache
240+
if (cached == null) {
241+
cached = ReactNativeFeatureFlagsCxxInterop.enableClipChildrenForOverflowHidden()
242+
enableClipChildrenForOverflowHiddenCache = cached
243+
}
244+
return cached
245+
}
246+
237247
override fun enableCppPropsIteratorSetter(): Boolean {
238248
var cached = enableCppPropsIteratorSetterCache
239249
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<<698641fe5c1a9f4933321d5b155467d1>>
7+
* @generated SignedSource<<8f93f5e6ce460e2337bbdc51bde69558>>
88
*/
99

1010
/**
@@ -58,6 +58,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
5858

5959
@DoNotStrip @JvmStatic public external fun enableBridgelessArchitecture(): Boolean
6060

61+
@DoNotStrip @JvmStatic public external fun enableClipChildrenForOverflowHidden(): Boolean
62+
6163
@DoNotStrip @JvmStatic public external fun enableCppPropsIteratorSetter(): Boolean
6264

6365
@DoNotStrip @JvmStatic public external fun enableCustomFocusSearchOnClippedElementsAndroid(): 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<<6ab1616102fb0807ad936f4333cb44c8>>
7+
* @generated SignedSource<<afd4040a9d72ea4af7a20084723506aa>>
88
*/
99

1010
/**
@@ -53,6 +53,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
5353

5454
override fun enableBridgelessArchitecture(): Boolean = false
5555

56+
override fun enableClipChildrenForOverflowHidden(): Boolean = false
57+
5658
override fun enableCppPropsIteratorSetter(): Boolean = false
5759

5860
override fun enableCustomFocusSearchOnClippedElementsAndroid(): Boolean = true

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<<f83c3d5107d900273c09061d6822f83d>>
7+
* @generated SignedSource<<377c50a9a022344cba12a1ad6c23b68d>>
88
*/
99

1010
/**
@@ -39,6 +39,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
3939
private var enableAndroidLinearTextCache: Boolean? = null
4040
private var enableAndroidTextMeasurementOptimizationsCache: Boolean? = null
4141
private var enableBridgelessArchitectureCache: Boolean? = null
42+
private var enableClipChildrenForOverflowHiddenCache: Boolean? = null
4243
private var enableCppPropsIteratorSetterCache: Boolean? = null
4344
private var enableCustomFocusSearchOnClippedElementsAndroidCache: Boolean? = null
4445
private var enableDestroyShadowTreeRevisionAsyncCache: Boolean? = null
@@ -253,6 +254,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
253254
return cached
254255
}
255256

257+
override fun enableClipChildrenForOverflowHidden(): Boolean {
258+
var cached = enableClipChildrenForOverflowHiddenCache
259+
if (cached == null) {
260+
cached = currentProvider.enableClipChildrenForOverflowHidden()
261+
accessedFeatureFlags.add("enableClipChildrenForOverflowHidden")
262+
enableClipChildrenForOverflowHiddenCache = cached
263+
}
264+
return cached
265+
}
266+
256267
override fun enableCppPropsIteratorSetter(): Boolean {
257268
var cached = enableCppPropsIteratorSetterCache
258269
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<<c2e44ee4f139a99b8179f750b416ed2f>>
7+
* @generated SignedSource<<c14e7e11bfb4404e2e8f94e551e1bb4d>>
88
*/
99

1010
/**
@@ -53,6 +53,8 @@ public interface ReactNativeFeatureFlagsProvider {
5353

5454
@DoNotStrip public fun enableBridgelessArchitecture(): Boolean
5555

56+
@DoNotStrip public fun enableClipChildrenForOverflowHidden(): Boolean
57+
5658
@DoNotStrip public fun enableCppPropsIteratorSetter(): Boolean
5759

5860
@DoNotStrip public fun enableCustomFocusSearchOnClippedElementsAndroid(): Boolean

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,9 @@ public open class ReactViewGroup public constructor(context: Context?) :
819819
} else {
820820
Overflow.fromString(overflow)
821821
}
822+
if (ReactNativeFeatureFlags.enableClipChildrenForOverflowHidden()) {
823+
clipChildren = (_overflow == Overflow.HIDDEN)
824+
}
822825
invalidate()
823826
}
824827

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<<e3d7f77795a066ffa164a02d74d7f4d1>>
7+
* @generated SignedSource<<3c268f88d2df4ad8500e29b91f1fecc0>>
88
*/
99

1010
/**
@@ -129,6 +129,12 @@ class ReactNativeFeatureFlagsJavaProvider
129129
return method(javaProvider_);
130130
}
131131

132+
bool enableClipChildrenForOverflowHidden() override {
133+
static const auto method =
134+
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableClipChildrenForOverflowHidden");
135+
return method(javaProvider_);
136+
}
137+
132138
bool enableCppPropsIteratorSetter() override {
133139
static const auto method =
134140
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableCppPropsIteratorSetter");
@@ -586,6 +592,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableBridgelessArchitecture(
586592
return ReactNativeFeatureFlags::enableBridgelessArchitecture();
587593
}
588594

595+
bool JReactNativeFeatureFlagsCxxInterop::enableClipChildrenForOverflowHidden(
596+
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
597+
return ReactNativeFeatureFlags::enableClipChildrenForOverflowHidden();
598+
}
599+
589600
bool JReactNativeFeatureFlagsCxxInterop::enableCppPropsIteratorSetter(
590601
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
591602
return ReactNativeFeatureFlags::enableCppPropsIteratorSetter();
@@ -977,6 +988,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
977988
makeNativeMethod(
978989
"enableBridgelessArchitecture",
979990
JReactNativeFeatureFlagsCxxInterop::enableBridgelessArchitecture),
991+
makeNativeMethod(
992+
"enableClipChildrenForOverflowHidden",
993+
JReactNativeFeatureFlagsCxxInterop::enableClipChildrenForOverflowHidden),
980994
makeNativeMethod(
981995
"enableCppPropsIteratorSetter",
982996
JReactNativeFeatureFlagsCxxInterop::enableCppPropsIteratorSetter),

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<<08d4a471097f96e6aecffe0d9fbd1e81>>
7+
* @generated SignedSource<<cd6ac6eb0dff3dc55780c809041b76e4>>
88
*/
99

1010
/**
@@ -75,6 +75,9 @@ class JReactNativeFeatureFlagsCxxInterop
7575
static bool enableBridgelessArchitecture(
7676
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
7777

78+
static bool enableClipChildrenForOverflowHidden(
79+
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
80+
7881
static bool enableCppPropsIteratorSetter(
7982
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
8083

packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp

Lines changed: 5 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<<ad0bd4c431f4f4d5658cb383bc5c16fa>>
7+
* @generated SignedSource<<fbd62713d66b440e7c18498ccd2a7c0b>>
88
*/
99

1010
/**
@@ -86,6 +86,10 @@ bool ReactNativeFeatureFlags::enableBridgelessArchitecture() {
8686
return getAccessor().enableBridgelessArchitecture();
8787
}
8888

89+
bool ReactNativeFeatureFlags::enableClipChildrenForOverflowHidden() {
90+
return getAccessor().enableClipChildrenForOverflowHidden();
91+
}
92+
8993
bool ReactNativeFeatureFlags::enableCppPropsIteratorSetter() {
9094
return getAccessor().enableCppPropsIteratorSetter();
9195
}

0 commit comments

Comments
 (0)