react-native 0.84.0-nightly-20251118-d314e5f4e → 0.84.0-nightly-20251120-88447cf20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Libraries/Components/View/ViewPropTypes.js +10 -0
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/Libraries/NativeComponent/BaseViewConfig.android.js +12 -0
- package/Libraries/Types/CoreEventTypes.js +31 -0
- package/React/Base/RCTVersion.m +1 -1
- package/React/CxxModule/RCTCxxUtils.mm +1 -1
- package/React/FBReactNativeSpec/FBReactNativeSpecJSI.h +8 -0
- package/React/FBReactNativeSpec/react/renderer/components/FBReactNativeSpec/Props.h +14 -0
- package/React/Fabric/Mounting/ComponentViews/ScrollView/RCTEnhancedScrollView.mm +6 -0
- package/ReactAndroid/api/ReactAndroid.api +2 -14
- package/ReactAndroid/gradle.properties +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +0 -7
- package/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.kt +0 -10
- package/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java +58 -2
- package/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.kt +0 -18
- package/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java +0 -54
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +7 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +11 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +3 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +3 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +12 -1
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +3 -1
- package/ReactAndroid/src/main/java/com/facebook/react/modules/debug/FpsDebugFrameCallback.kt +3 -27
- package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.kt +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessCatalystInstance.kt +0 -9
- package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactSurfaceView.kt +52 -0
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java +33 -0
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/JSKeyDispatcher.kt +65 -0
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java +0 -8
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java +0 -8
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java +0 -16
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/KeyDownEvent.kt +23 -0
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/KeyEvent.kt +156 -0
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/KeyUpEvent.kt +24 -0
- package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +15 -1
- package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +4 -1
- package/ReactAndroid/src/main/jni/react/tracing/PerformanceTracerCxxInterop.cpp +1 -1
- package/ReactAndroid/src/main/res/views/uimanager/values-ne/strings.xml +1 -0
- package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
- package/ReactCommon/jsi/jsi/test/testlib.cpp +2 -2
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +5 -1
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +6 -1
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +37 -19
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +4 -2
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +5 -1
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +10 -1
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +2 -1
- package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +6 -1
- package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +3 -1
- package/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformViewProps.cpp +1 -1
- package/ReactCommon/react/runtime/ReactInstance.cpp +1 -1
- package/index.js.flow +3 -0
- package/package.json +9 -9
- package/sdks/hermes-engine/version.properties +1 -1
- package/src/private/featureflags/ReactNativeFeatureFlags.js +6 -1
- package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +2 -1
- package/types_generated/Libraries/Components/View/ViewPropTypes.d.ts +9 -3
- package/types_generated/Libraries/Types/CoreEventTypes.d.ts +29 -1
- package/types_generated/index.d.ts +2 -2
- package/ReactAndroid/src/main/java/com/facebook/react/bridge/NotThreadSafeBridgeIdleDebugListener.kt +0 -36
- package/ReactAndroid/src/main/java/com/facebook/react/modules/debug/DidJSUpdateUiDuringFrameDetector.kt +0 -157
- package/ReactAndroid/src/main/java/com/facebook/react/uimanager/debug/NotThreadSafeViewHierarchyUpdateDebugListener.kt +0 -30
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @generated SignedSource<<
|
|
7
|
+
* @generated SignedSource<<15bb2229e65b6a6ae728d512ff51885f>>
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -91,6 +91,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
|
|
|
91
91
|
private var preventShadowTreeCommitExhaustionCache: Boolean? = null
|
|
92
92
|
private var shouldPressibilityUseW3CPointerEventsForHoverCache: Boolean? = null
|
|
93
93
|
private var shouldSetEnabledBasedOnAccessibilityStateCache: Boolean? = null
|
|
94
|
+
private var shouldSetIsClickableByDefaultCache: Boolean? = null
|
|
94
95
|
private var shouldTriggerResponderTransferOnScrollAndroidCache: Boolean? = null
|
|
95
96
|
private var skipActivityIdentityAssertionOnHostPauseCache: Boolean? = null
|
|
96
97
|
private var traceTurboModulePromiseRejectionsOnAndroidCache: Boolean? = null
|
|
@@ -749,6 +750,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
|
|
|
749
750
|
return cached
|
|
750
751
|
}
|
|
751
752
|
|
|
753
|
+
override fun shouldSetIsClickableByDefault(): Boolean {
|
|
754
|
+
var cached = shouldSetIsClickableByDefaultCache
|
|
755
|
+
if (cached == null) {
|
|
756
|
+
cached = ReactNativeFeatureFlagsCxxInterop.shouldSetIsClickableByDefault()
|
|
757
|
+
shouldSetIsClickableByDefaultCache = cached
|
|
758
|
+
}
|
|
759
|
+
return cached
|
|
760
|
+
}
|
|
761
|
+
|
|
752
762
|
override fun shouldTriggerResponderTransferOnScrollAndroid(): Boolean {
|
|
753
763
|
var cached = shouldTriggerResponderTransferOnScrollAndroidCache
|
|
754
764
|
if (cached == null) {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @generated SignedSource<<
|
|
7
|
+
* @generated SignedSource<<85a6247f6049f60c18efdce5db0cccdf>>
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -170,6 +170,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
|
|
|
170
170
|
|
|
171
171
|
@DoNotStrip @JvmStatic public external fun shouldSetEnabledBasedOnAccessibilityState(): Boolean
|
|
172
172
|
|
|
173
|
+
@DoNotStrip @JvmStatic public external fun shouldSetIsClickableByDefault(): Boolean
|
|
174
|
+
|
|
173
175
|
@DoNotStrip @JvmStatic public external fun shouldTriggerResponderTransferOnScrollAndroid(): Boolean
|
|
174
176
|
|
|
175
177
|
@DoNotStrip @JvmStatic public external fun skipActivityIdentityAssertionOnHostPause(): Boolean
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @generated SignedSource<<
|
|
7
|
+
* @generated SignedSource<<614d228af81090b8b1dee65f4bfb67d7>>
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -165,6 +165,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
|
|
|
165
165
|
|
|
166
166
|
override fun shouldSetEnabledBasedOnAccessibilityState(): Boolean = true
|
|
167
167
|
|
|
168
|
+
override fun shouldSetIsClickableByDefault(): Boolean = false
|
|
169
|
+
|
|
168
170
|
override fun shouldTriggerResponderTransferOnScrollAndroid(): Boolean = false
|
|
169
171
|
|
|
170
172
|
override fun skipActivityIdentityAssertionOnHostPause(): Boolean = false
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @generated SignedSource<<
|
|
7
|
+
* @generated SignedSource<<e4971d843cf79d94f8c61394f4c27204>>
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -95,6 +95,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
|
|
|
95
95
|
private var preventShadowTreeCommitExhaustionCache: Boolean? = null
|
|
96
96
|
private var shouldPressibilityUseW3CPointerEventsForHoverCache: Boolean? = null
|
|
97
97
|
private var shouldSetEnabledBasedOnAccessibilityStateCache: Boolean? = null
|
|
98
|
+
private var shouldSetIsClickableByDefaultCache: Boolean? = null
|
|
98
99
|
private var shouldTriggerResponderTransferOnScrollAndroidCache: Boolean? = null
|
|
99
100
|
private var skipActivityIdentityAssertionOnHostPauseCache: Boolean? = null
|
|
100
101
|
private var traceTurboModulePromiseRejectionsOnAndroidCache: Boolean? = null
|
|
@@ -824,6 +825,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
|
|
|
824
825
|
return cached
|
|
825
826
|
}
|
|
826
827
|
|
|
828
|
+
override fun shouldSetIsClickableByDefault(): Boolean {
|
|
829
|
+
var cached = shouldSetIsClickableByDefaultCache
|
|
830
|
+
if (cached == null) {
|
|
831
|
+
cached = currentProvider.shouldSetIsClickableByDefault()
|
|
832
|
+
accessedFeatureFlags.add("shouldSetIsClickableByDefault")
|
|
833
|
+
shouldSetIsClickableByDefaultCache = cached
|
|
834
|
+
}
|
|
835
|
+
return cached
|
|
836
|
+
}
|
|
837
|
+
|
|
827
838
|
override fun shouldTriggerResponderTransferOnScrollAndroid(): Boolean {
|
|
828
839
|
var cached = shouldTriggerResponderTransferOnScrollAndroidCache
|
|
829
840
|
if (cached == null) {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @generated SignedSource<<
|
|
7
|
+
* @generated SignedSource<<e7b49105c0cea6be905be90610f0c7e4>>
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -165,6 +165,8 @@ public interface ReactNativeFeatureFlagsProvider {
|
|
|
165
165
|
|
|
166
166
|
@DoNotStrip public fun shouldSetEnabledBasedOnAccessibilityState(): Boolean
|
|
167
167
|
|
|
168
|
+
@DoNotStrip public fun shouldSetIsClickableByDefault(): Boolean
|
|
169
|
+
|
|
168
170
|
@DoNotStrip public fun shouldTriggerResponderTransferOnScrollAndroid(): Boolean
|
|
169
171
|
|
|
170
172
|
@DoNotStrip public fun skipActivityIdentityAssertionOnHostPause(): Boolean
|
package/ReactAndroid/src/main/java/com/facebook/react/modules/debug/FpsDebugFrameCallback.kt
CHANGED
|
@@ -26,8 +26,6 @@ internal class FpsDebugFrameCallback(private val reactContext: ReactContext) :
|
|
|
26
26
|
Choreographer.FrameCallback {
|
|
27
27
|
|
|
28
28
|
private var choreographer: Choreographer? = null
|
|
29
|
-
private val didJSUpdateUiDuringFrameDetector: DidJSUpdateUiDuringFrameDetector =
|
|
30
|
-
DidJSUpdateUiDuringFrameDetector()
|
|
31
29
|
private var firstFrameTime: Long = -1
|
|
32
30
|
private var lastFrameTime: Long = -1
|
|
33
31
|
private var numFrameCallbacks = 0
|
|
@@ -40,11 +38,7 @@ internal class FpsDebugFrameCallback(private val reactContext: ReactContext) :
|
|
|
40
38
|
if (firstFrameTime == -1L) {
|
|
41
39
|
firstFrameTime = l
|
|
42
40
|
}
|
|
43
|
-
val lastFrameStartTime = lastFrameTime
|
|
44
41
|
lastFrameTime = l
|
|
45
|
-
if (didJSUpdateUiDuringFrameDetector.getDidJSHitFrameAndCleanup(lastFrameStartTime, l)) {
|
|
46
|
-
numFrameCallbacksWithBatchDispatches++
|
|
47
|
-
}
|
|
48
42
|
numFrameCallbacks++
|
|
49
43
|
val expectedNumFrames = expectedNumFrames
|
|
50
44
|
val framesDropped = expectedNumFrames - expectedNumFramesPrev - 1
|
|
@@ -61,17 +55,9 @@ internal class FpsDebugFrameCallback(private val reactContext: ReactContext) :
|
|
|
61
55
|
// removeBridgeIdleDebugListener for Bridgeless
|
|
62
56
|
@Suppress("DEPRECATION")
|
|
63
57
|
if (!ReactBuildConfig.UNSTABLE_ENABLE_MINIFY_LEGACY_ARCHITECTURE) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
reactContext.catalystInstance.addBridgeIdleDebugListener(didJSUpdateUiDuringFrameDetector)
|
|
68
|
-
isRunningOnFabric = false
|
|
69
|
-
} else {
|
|
70
|
-
// T172641976 Consider either implementing a mechanism similar to addBridgeIdleDebugListener
|
|
71
|
-
// for Fabric or point users to use RNDT.
|
|
72
|
-
isRunningOnFabric = true
|
|
73
|
-
}
|
|
74
|
-
uiManagerModule?.setViewHierarchyUpdateDebugListener(didJSUpdateUiDuringFrameDetector)
|
|
58
|
+
// T172641976 Consider either implementing a mechanism similar to addBridgeIdleDebugListener
|
|
59
|
+
// for Fabric or point users to use RNDT.
|
|
60
|
+
isRunningOnFabric = true
|
|
75
61
|
}
|
|
76
62
|
this.targetFps = targetFps
|
|
77
63
|
UiThreadUtil.runOnUiThread {
|
|
@@ -82,16 +68,6 @@ internal class FpsDebugFrameCallback(private val reactContext: ReactContext) :
|
|
|
82
68
|
|
|
83
69
|
fun stop() {
|
|
84
70
|
@Suppress("DEPRECATION")
|
|
85
|
-
if (!ReactBuildConfig.UNSTABLE_ENABLE_MINIFY_LEGACY_ARCHITECTURE) {
|
|
86
|
-
val uiManagerModule =
|
|
87
|
-
reactContext.getNativeModule(com.facebook.react.uimanager.UIManagerModule::class.java)
|
|
88
|
-
if (!reactContext.isBridgeless) {
|
|
89
|
-
reactContext.catalystInstance.removeBridgeIdleDebugListener(
|
|
90
|
-
didJSUpdateUiDuringFrameDetector
|
|
91
|
-
)
|
|
92
|
-
}
|
|
93
|
-
uiManagerModule?.setViewHierarchyUpdateDebugListener(null)
|
|
94
|
-
}
|
|
95
71
|
UiThreadUtil.runOnUiThread {
|
|
96
72
|
choreographer = Choreographer.getInstance()
|
|
97
73
|
choreographer?.removeFrameCallback(this)
|
|
@@ -19,7 +19,6 @@ import com.facebook.react.bridge.NativeArray
|
|
|
19
19
|
import com.facebook.react.bridge.NativeArrayInterface
|
|
20
20
|
import com.facebook.react.bridge.NativeModule
|
|
21
21
|
import com.facebook.react.bridge.NativeModuleRegistry
|
|
22
|
-
import com.facebook.react.bridge.NotThreadSafeBridgeIdleDebugListener
|
|
23
22
|
import com.facebook.react.bridge.RuntimeExecutor
|
|
24
23
|
import com.facebook.react.bridge.RuntimeScheduler
|
|
25
24
|
import com.facebook.react.bridge.UIManager
|
|
@@ -140,14 +139,6 @@ internal class BridgelessCatalystInstance(private val reactHost: ReactHostImpl)
|
|
|
140
139
|
override val sourceURL: String
|
|
141
140
|
get() = throw UnsupportedOperationException("Unimplemented method 'getSourceURL'")
|
|
142
141
|
|
|
143
|
-
override fun addBridgeIdleDebugListener(listener: NotThreadSafeBridgeIdleDebugListener) {
|
|
144
|
-
throw UnsupportedOperationException("Unimplemented method 'addBridgeIdleDebugListener'")
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
override fun removeBridgeIdleDebugListener(listener: NotThreadSafeBridgeIdleDebugListener) {
|
|
148
|
-
throw UnsupportedOperationException("Unimplemented method 'removeBridgeIdleDebugListener'")
|
|
149
|
-
}
|
|
150
|
-
|
|
151
142
|
override fun registerSegment(segmentId: Int, path: String) {
|
|
152
143
|
throw UnsupportedOperationException("Unimplemented method 'registerSegment'")
|
|
153
144
|
}
|
|
@@ -12,6 +12,7 @@ package com.facebook.react.runtime
|
|
|
12
12
|
import android.content.Context
|
|
13
13
|
import android.graphics.Point
|
|
14
14
|
import android.graphics.Rect
|
|
15
|
+
import android.view.KeyEvent
|
|
15
16
|
import android.view.MotionEvent
|
|
16
17
|
import android.view.View
|
|
17
18
|
import com.facebook.common.logging.FLog
|
|
@@ -20,7 +21,9 @@ import com.facebook.react.bridge.ReactContext
|
|
|
20
21
|
import com.facebook.react.common.annotations.FrameworkAPI
|
|
21
22
|
import com.facebook.react.common.annotations.UnstableReactNativeAPI
|
|
22
23
|
import com.facebook.react.config.ReactFeatureFlags
|
|
24
|
+
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
|
|
23
25
|
import com.facebook.react.uimanager.IllegalViewOperationException
|
|
26
|
+
import com.facebook.react.uimanager.JSKeyDispatcher
|
|
24
27
|
import com.facebook.react.uimanager.JSPointerDispatcher
|
|
25
28
|
import com.facebook.react.uimanager.JSTouchDispatcher
|
|
26
29
|
import com.facebook.react.uimanager.common.UIManagerType
|
|
@@ -37,6 +40,7 @@ public class ReactSurfaceView(context: Context?, private val surface: ReactSurfa
|
|
|
37
40
|
ReactRootView(context) {
|
|
38
41
|
private val jsTouchDispatcher: JSTouchDispatcher = JSTouchDispatcher(this)
|
|
39
42
|
private var jsPointerDispatcher: JSPointerDispatcher? = null
|
|
43
|
+
private var jsKeyDispatcher: JSKeyDispatcher? = null
|
|
40
44
|
private var wasMeasured = false
|
|
41
45
|
private var widthMeasureSpec = 0
|
|
42
46
|
private var heightMeasureSpec = 0
|
|
@@ -45,6 +49,9 @@ public class ReactSurfaceView(context: Context?, private val surface: ReactSurfa
|
|
|
45
49
|
if (ReactFeatureFlags.dispatchPointerEvents) {
|
|
46
50
|
jsPointerDispatcher = JSPointerDispatcher(this)
|
|
47
51
|
}
|
|
52
|
+
if (ReactNativeFeatureFlags.enableKeyEvents()) {
|
|
53
|
+
jsKeyDispatcher = JSKeyDispatcher()
|
|
54
|
+
}
|
|
48
55
|
}
|
|
49
56
|
|
|
50
57
|
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
|
@@ -188,6 +195,51 @@ public class ReactSurfaceView(context: Context?, private val surface: ReactSurfa
|
|
|
188
195
|
}
|
|
189
196
|
}
|
|
190
197
|
|
|
198
|
+
override fun dispatchJSKeyEvent(event: KeyEvent) {
|
|
199
|
+
if (jsKeyDispatcher == null) {
|
|
200
|
+
if (!ReactNativeFeatureFlags.enableKeyEvents()) {
|
|
201
|
+
return
|
|
202
|
+
}
|
|
203
|
+
FLog.w(TAG, "Unable to dispatch key events to JS before the dispatcher is available")
|
|
204
|
+
return
|
|
205
|
+
}
|
|
206
|
+
val eventDispatcher = surface.eventDispatcher
|
|
207
|
+
if (eventDispatcher != null) {
|
|
208
|
+
jsKeyDispatcher?.handleKeyEvent(event, eventDispatcher, surface.surfaceID)
|
|
209
|
+
} else {
|
|
210
|
+
FLog.w(
|
|
211
|
+
TAG,
|
|
212
|
+
"Unable to dispatch key events to JS as the React instance has not been attached",
|
|
213
|
+
)
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
override fun requestChildFocus(child: View?, focused: View?) {
|
|
218
|
+
super.requestChildFocus(child, focused)
|
|
219
|
+
|
|
220
|
+
if (ReactNativeFeatureFlags.enableKeyEvents()) {
|
|
221
|
+
val focusedViewTag = focused?.id
|
|
222
|
+
if (focusedViewTag != null) {
|
|
223
|
+
jsKeyDispatcher?.setFocusedView(focusedViewTag)
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
override fun onFocusChanged(gainFocus: Boolean, direction: Int, previouslyFocusedRect: Rect?) {
|
|
229
|
+
super.onFocusChanged(gainFocus, direction, previouslyFocusedRect)
|
|
230
|
+
|
|
231
|
+
if (ReactNativeFeatureFlags.enableKeyEvents()) {
|
|
232
|
+
if (gainFocus) {
|
|
233
|
+
val focusedViewTag = focusedChild?.id
|
|
234
|
+
if (focusedViewTag != null) {
|
|
235
|
+
jsKeyDispatcher?.setFocusedView(focusedViewTag)
|
|
236
|
+
}
|
|
237
|
+
} else {
|
|
238
|
+
jsKeyDispatcher?.clearFocus()
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
191
243
|
override fun hasActiveReactContext(): Boolean =
|
|
192
244
|
surface.isAttached && surface.reactHost?.currentReactContext != null
|
|
193
245
|
|
|
@@ -149,6 +149,9 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
|
|
|
149
149
|
// https://android.googlesource.com/platform/frameworks/base/+/a175a5b/core/java/android/view/View.java#2712
|
|
150
150
|
// `mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED | LAYOUT_DIRECTION_INHERIT`
|
|
151
151
|
// Therefore we set the following options as such:
|
|
152
|
+
if (ReactNativeFeatureFlags.shouldSetIsClickableByDefault()) {
|
|
153
|
+
view.setClickable(true);
|
|
154
|
+
}
|
|
152
155
|
view.setFocusable(false);
|
|
153
156
|
view.setFocusableInTouchMode(false);
|
|
154
157
|
|
|
@@ -678,6 +681,7 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
|
|
|
678
681
|
@Override
|
|
679
682
|
protected void onAfterUpdateTransaction(@NonNull T view) {
|
|
680
683
|
super.onAfterUpdateTransaction(view);
|
|
684
|
+
configureClickableState(view);
|
|
681
685
|
updateViewAccessibility(view);
|
|
682
686
|
|
|
683
687
|
Boolean invalidateTransform = (Boolean) view.getTag(R.id.invalidate_transform);
|
|
@@ -770,6 +774,16 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
|
|
|
770
774
|
MapBuilder.of(
|
|
771
775
|
"phasedRegistrationNames",
|
|
772
776
|
MapBuilder.of("bubbled", "onFocus", "captured", "onFocusCapture")))
|
|
777
|
+
.put(
|
|
778
|
+
"topKeyDown",
|
|
779
|
+
MapBuilder.of(
|
|
780
|
+
"phasedRegistrationNames",
|
|
781
|
+
MapBuilder.of("bubbled", "onKeyDown", "captured", "onKeyDownCapture")))
|
|
782
|
+
.put(
|
|
783
|
+
"topKeyUp",
|
|
784
|
+
MapBuilder.of(
|
|
785
|
+
"phasedRegistrationNames",
|
|
786
|
+
MapBuilder.of("bubbled", "onKeyUp", "captured", "onKeyUpCapture")))
|
|
773
787
|
.build());
|
|
774
788
|
return eventTypeConstants;
|
|
775
789
|
}
|
|
@@ -1001,6 +1015,25 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
|
|
|
1001
1015
|
|
|
1002
1016
|
// Please add new props to BaseViewManagerDelegate as well!
|
|
1003
1017
|
|
|
1018
|
+
private static <T extends View> void configureClickableState(@NonNull T view) {
|
|
1019
|
+
if (!ReactNativeFeatureFlags.shouldSetIsClickableByDefault()) {
|
|
1020
|
+
return;
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
boolean shouldBeClickable =
|
|
1024
|
+
!(view instanceof ReactPointerEventsView)
|
|
1025
|
+
|| PointerEvents.canBeTouchTarget(((ReactPointerEventsView) view).getPointerEvents());
|
|
1026
|
+
|
|
1027
|
+
// NOTE: In Android O+, setClickable(true) has the side effect of setting focusable=true.
|
|
1028
|
+
// We need to preserve the original focusable state to respect the focusable prop.
|
|
1029
|
+
boolean wasFocusable = view.isFocusable();
|
|
1030
|
+
boolean wasFocusableInTouchMode = view.isFocusableInTouchMode();
|
|
1031
|
+
|
|
1032
|
+
view.setClickable(shouldBeClickable);
|
|
1033
|
+
view.setFocusable(wasFocusable);
|
|
1034
|
+
view.setFocusableInTouchMode(wasFocusableInTouchMode);
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1004
1037
|
/**
|
|
1005
1038
|
* A helper class to keep track of the original focus change listener if one is set. This is
|
|
1006
1039
|
* especially helpful for views that are recycled so we can retain and restore the original
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
package com.facebook.react.uimanager
|
|
9
|
+
|
|
10
|
+
import android.view.KeyEvent as AndroidKeyEvent
|
|
11
|
+
import android.view.View
|
|
12
|
+
import com.facebook.react.uimanager.events.EventDispatcher
|
|
13
|
+
import com.facebook.react.uimanager.events.KeyDownEvent
|
|
14
|
+
import com.facebook.react.uimanager.events.KeyUpEvent
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* JSKeyDispatcher handles dispatching keyboard events to JS from RootViews. It sends keydown and
|
|
18
|
+
* keyup events according to the W3C KeyboardEvent specification, supporting both capture and bubble
|
|
19
|
+
* phases.
|
|
20
|
+
*
|
|
21
|
+
* The keydown and keyup events provide a code indicating which key is pressed. The event target is
|
|
22
|
+
* derived from the currently focused Android view.
|
|
23
|
+
*/
|
|
24
|
+
internal class JSKeyDispatcher {
|
|
25
|
+
private var focusedViewTag: Int = View.NO_ID
|
|
26
|
+
|
|
27
|
+
fun handleKeyEvent(
|
|
28
|
+
keyEvent: AndroidKeyEvent,
|
|
29
|
+
eventDispatcher: EventDispatcher,
|
|
30
|
+
surfaceId: Int,
|
|
31
|
+
) {
|
|
32
|
+
if (focusedViewTag == View.NO_ID) {
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
when (keyEvent.action) {
|
|
37
|
+
AndroidKeyEvent.ACTION_DOWN -> {
|
|
38
|
+
eventDispatcher.dispatchEvent(
|
|
39
|
+
KeyDownEvent(
|
|
40
|
+
surfaceId,
|
|
41
|
+
focusedViewTag,
|
|
42
|
+
keyEvent,
|
|
43
|
+
)
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
AndroidKeyEvent.ACTION_UP -> {
|
|
47
|
+
eventDispatcher.dispatchEvent(
|
|
48
|
+
KeyUpEvent(
|
|
49
|
+
surfaceId,
|
|
50
|
+
focusedViewTag,
|
|
51
|
+
keyEvent,
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
fun setFocusedView(viewTag: Int) {
|
|
59
|
+
focusedViewTag = viewTag
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
fun clearFocus() {
|
|
63
|
+
focusedViewTag = View.NO_ID
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -26,7 +26,6 @@ import com.facebook.react.common.annotations.internal.LegacyArchitectureLogLevel
|
|
|
26
26
|
import com.facebook.react.common.annotations.internal.LegacyArchitectureLogger;
|
|
27
27
|
import com.facebook.react.common.build.ReactBuildConfig;
|
|
28
28
|
import com.facebook.react.modules.i18nmanager.I18nUtil;
|
|
29
|
-
import com.facebook.react.uimanager.debug.NotThreadSafeViewHierarchyUpdateDebugListener;
|
|
30
29
|
import com.facebook.react.uimanager.events.EventDispatcher;
|
|
31
30
|
import com.facebook.systrace.Systrace;
|
|
32
31
|
import com.facebook.systrace.SystraceMessage;
|
|
@@ -782,13 +781,6 @@ public class UIImplementation {
|
|
|
782
781
|
mViewManagers.invalidate();
|
|
783
782
|
}
|
|
784
783
|
|
|
785
|
-
// NOTE: When converted to Kotlin this method should be `internal` due to
|
|
786
|
-
// visibility restriction for `NotThreadSafeViewHierarchyUpdateDebugListener`
|
|
787
|
-
public void setViewHierarchyUpdateDebugListener(
|
|
788
|
-
@Nullable NotThreadSafeViewHierarchyUpdateDebugListener listener) {
|
|
789
|
-
mOperationsQueue.setViewHierarchyUpdateDebugListener(listener);
|
|
790
|
-
}
|
|
791
|
-
|
|
792
784
|
protected final void removeShadowNode(ReactShadowNode nodeToRemove) {
|
|
793
785
|
removeShadowNodeRecursive(nodeToRemove);
|
|
794
786
|
nodeToRemove.dispose();
|
|
@@ -45,7 +45,6 @@ import com.facebook.react.common.annotations.internal.LegacyArchitectureLogger;
|
|
|
45
45
|
import com.facebook.react.common.build.ReactBuildConfig;
|
|
46
46
|
import com.facebook.react.module.annotations.ReactModule;
|
|
47
47
|
import com.facebook.react.uimanager.common.ViewUtil;
|
|
48
|
-
import com.facebook.react.uimanager.debug.NotThreadSafeViewHierarchyUpdateDebugListener;
|
|
49
48
|
import com.facebook.react.uimanager.events.EventDispatcher;
|
|
50
49
|
import com.facebook.react.uimanager.events.EventDispatcherImpl;
|
|
51
50
|
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
|
@@ -699,13 +698,6 @@ public class UIManagerModule extends ReactContextBaseJavaModule
|
|
|
699
698
|
}
|
|
700
699
|
}
|
|
701
700
|
|
|
702
|
-
// NOTE: When converted to Kotlin this method should be `internal` due to
|
|
703
|
-
// visibility restriction for `NotThreadSafeViewHierarchyUpdateDebugListener`
|
|
704
|
-
public void setViewHierarchyUpdateDebugListener(
|
|
705
|
-
@Nullable NotThreadSafeViewHierarchyUpdateDebugListener listener) {
|
|
706
|
-
mUIImplementation.setViewHierarchyUpdateDebugListener(listener);
|
|
707
|
-
}
|
|
708
|
-
|
|
709
701
|
@Override
|
|
710
702
|
public EventDispatcher getEventDispatcher() {
|
|
711
703
|
return mEventDispatcher;
|
|
@@ -29,7 +29,6 @@ import com.facebook.react.common.annotations.internal.LegacyArchitecture;
|
|
|
29
29
|
import com.facebook.react.common.annotations.internal.LegacyArchitectureLogLevel;
|
|
30
30
|
import com.facebook.react.common.annotations.internal.LegacyArchitectureLogger;
|
|
31
31
|
import com.facebook.react.modules.core.ReactChoreographer;
|
|
32
|
-
import com.facebook.react.uimanager.debug.NotThreadSafeViewHierarchyUpdateDebugListener;
|
|
33
32
|
import com.facebook.systrace.Systrace;
|
|
34
33
|
import com.facebook.systrace.SystraceMessage;
|
|
35
34
|
import com.facebook.yoga.YogaDirection;
|
|
@@ -584,7 +583,6 @@ public class UIViewOperationQueue {
|
|
|
584
583
|
@GuardedBy("mNonBatchedOperationsLock")
|
|
585
584
|
private ArrayDeque<UIOperation> mNonBatchedOperations = new ArrayDeque<>();
|
|
586
585
|
|
|
587
|
-
private @Nullable NotThreadSafeViewHierarchyUpdateDebugListener mViewHierarchyUpdateDebugListener;
|
|
588
586
|
private boolean mIsDispatchUIFrameCallbackEnqueued = false;
|
|
589
587
|
private boolean mIsInIllegalUIState = false;
|
|
590
588
|
private boolean mIsProfilingNextBatch = false;
|
|
@@ -619,13 +617,6 @@ public class UIViewOperationQueue {
|
|
|
619
617
|
return mNativeViewHierarchyManager;
|
|
620
618
|
}
|
|
621
619
|
|
|
622
|
-
// NOTE: When converted to Kotlin this method should be `internal` due to
|
|
623
|
-
// visibility restriction for `NotThreadSafeViewHierarchyUpdateDebugListener`
|
|
624
|
-
public void setViewHierarchyUpdateDebugListener(
|
|
625
|
-
@Nullable NotThreadSafeViewHierarchyUpdateDebugListener listener) {
|
|
626
|
-
mViewHierarchyUpdateDebugListener = listener;
|
|
627
|
-
}
|
|
628
|
-
|
|
629
620
|
public void profileNextBatch() {
|
|
630
621
|
mIsProfilingNextBatch = true;
|
|
631
622
|
mProfiledBatchCommitStartTime = 0;
|
|
@@ -833,10 +824,6 @@ public class UIViewOperationQueue {
|
|
|
833
824
|
}
|
|
834
825
|
}
|
|
835
826
|
|
|
836
|
-
if (mViewHierarchyUpdateDebugListener != null) {
|
|
837
|
-
mViewHierarchyUpdateDebugListener.onViewHierarchyUpdateEnqueued();
|
|
838
|
-
}
|
|
839
|
-
|
|
840
827
|
Runnable runOperations =
|
|
841
828
|
new Runnable() {
|
|
842
829
|
@Override
|
|
@@ -926,9 +913,6 @@ public class UIViewOperationQueue {
|
|
|
926
913
|
// Clear layout animation, as animation only apply to current UI operations batch.
|
|
927
914
|
mNativeViewHierarchyManager.clearLayoutAnimation();
|
|
928
915
|
|
|
929
|
-
if (mViewHierarchyUpdateDebugListener != null) {
|
|
930
|
-
mViewHierarchyUpdateDebugListener.onViewHierarchyUpdateFinished();
|
|
931
|
-
}
|
|
932
916
|
} catch (Exception e) {
|
|
933
917
|
mIsInIllegalUIState = true;
|
|
934
918
|
throw e;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
package com.facebook.react.uimanager.events
|
|
9
|
+
|
|
10
|
+
import android.view.KeyEvent as AndroidKeyEvent
|
|
11
|
+
|
|
12
|
+
internal class KeyDownEvent(
|
|
13
|
+
surfaceId: Int,
|
|
14
|
+
viewTag: Int,
|
|
15
|
+
keyEvent: AndroidKeyEvent,
|
|
16
|
+
) : KeyEvent(surfaceId, viewTag, keyEvent) {
|
|
17
|
+
|
|
18
|
+
override fun getEventName(): String = EVENT_NAME
|
|
19
|
+
|
|
20
|
+
companion object {
|
|
21
|
+
private const val EVENT_NAME: String = "topKeyDown"
|
|
22
|
+
}
|
|
23
|
+
}
|