react-native-windows 0.83.0-preview.3 → 0.84.0-preview.10
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/.flowconfig +2 -2
- package/Folly/Folly.vcxproj +2 -0
- package/Libraries/Animated/AnimatedEvent.js +2 -2
- package/Libraries/Animated/animations/Animation.js +1 -3
- package/Libraries/Animated/createAnimatedComponent.js +8 -5
- package/Libraries/Animated/nodes/AnimatedColor.js +1 -1
- package/Libraries/Animated/nodes/AnimatedInterpolation.js +40 -4
- package/Libraries/Animated/nodes/AnimatedNode.js +3 -3
- package/Libraries/Animated/nodes/AnimatedObject.js +16 -11
- package/Libraries/Animated/nodes/AnimatedProps.js +43 -12
- package/Libraries/Animated/nodes/AnimatedStyle.js +12 -12
- package/Libraries/Animated/nodes/AnimatedValue.js +6 -3
- package/Libraries/Animated/nodes/AnimatedValueXY.js +1 -1
- package/Libraries/BatchedBridge/MessageQueue.js +24 -22
- package/Libraries/Blob/URL.js +34 -3
- package/Libraries/Blob/URLSearchParams.js +1 -0
- package/Libraries/Components/AccessibilityInfo/AccessibilityInfo.d.ts +9 -1
- package/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js +6 -1
- package/Libraries/Components/AccessibilityInfo/AccessibilityInfo.windows.js +6 -1
- package/Libraries/Components/Button.js +2 -5
- package/Libraries/Components/Button.windows.js +2 -5
- package/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js +1 -1
- package/Libraries/Components/DrawerAndroid/DrawerLayoutAndroidTypes.js +4 -4
- package/Libraries/Components/Keyboard/Keyboard.js +2 -2
- package/Libraries/Components/Pressable/Pressable.js +8 -8
- package/Libraries/Components/Pressable/Pressable.windows.js +14 -13
- package/Libraries/Components/TextInput/TextInput.flow.js +13 -13
- package/Libraries/Components/TextInput/TextInput.flow.windows.js +19 -18
- package/Libraries/Components/TextInput/TextInput.js +33 -34
- package/Libraries/Components/TextInput/TextInput.windows.js +40 -39
- package/Libraries/Components/Touchable/PooledClass.js +2 -2
- package/Libraries/Components/Touchable/TouchableBounce.js +3 -3
- package/Libraries/Components/Touchable/TouchableBounce.windows.js +3 -3
- package/Libraries/Components/Touchable/TouchableNativeFeedback.js +1 -1
- package/Libraries/Components/Touchable/TouchableNativeFeedback.windows.js +1 -1
- package/Libraries/Components/Touchable/TouchableWithoutFeedback.js +9 -9
- package/Libraries/Components/Touchable/TouchableWithoutFeedback.windows.js +9 -9
- package/Libraries/Components/View/ViewPropTypes.js +16 -6
- package/Libraries/Components/View/ViewPropTypes.windows.js +21 -11
- package/Libraries/Core/Devtools/loadBundleFromServer.js +6 -3
- package/Libraries/Core/Devtools/loadBundleFromServer.windows.js +6 -3
- package/Libraries/Core/Devtools/symbolicateStackTrace.js +1 -1
- package/Libraries/Core/ExceptionsManager.js +3 -3
- package/Libraries/Core/RawEventEmitter.js +1 -1
- package/Libraries/Core/ReactFiberErrorDialog.js +1 -1
- package/Libraries/Core/ReactNativeVersion.js +2 -2
- package/Libraries/Core/setUpDeveloperTools.js +1 -1
- package/Libraries/Core/setUpErrorHandling.js +1 -1
- package/Libraries/Core/setUpReactDevTools.js +6 -23
- package/Libraries/EventEmitter/NativeEventEmitter.js +2 -2
- package/Libraries/Image/Image.android.js +2 -2
- package/Libraries/Image/Image.ios.js +2 -2
- package/Libraries/Image/Image.windows.js +2 -2
- package/Libraries/Image/ImageProps.js +1 -1
- package/Libraries/Image/ImageTypes.flow.js +2 -2
- package/Libraries/Interaction/InteractionManager.js +3 -3
- package/Libraries/Interaction/PanResponder.js +1 -1
- package/Libraries/LayoutAnimation/LayoutAnimation.js +1 -1
- package/Libraries/Linking/Linking.js +1 -1
- package/Libraries/Lists/FlatList.js +2 -2
- package/Libraries/LogBox/Data/LogBoxData.js +31 -4
- package/Libraries/LogBox/Data/LogBoxLog.js +2 -2
- package/Libraries/LogBox/Data/LogBoxSymbolication.js +1 -1
- package/Libraries/LogBox/Data/parseLogBoxLog.js +5 -5
- package/Libraries/LogBox/LogBox.js +7 -7
- package/Libraries/Modal/Modal.windows.js +1 -7
- package/Libraries/NativeComponent/BaseViewConfig.android.js +12 -0
- package/Libraries/NativeComponent/StaticViewConfigValidator.js +4 -4
- package/Libraries/NativeComponent/ViewConfigIgnore.js +1 -1
- package/Libraries/NativeComponent/ViewConfigIgnore.windows.js +1 -1
- package/Libraries/Network/RCTNetworking.android.js +3 -3
- package/Libraries/Network/RCTNetworking.ios.js +2 -2
- package/Libraries/Network/RCTNetworking.js.flow +2 -2
- package/Libraries/Network/RCTNetworking.windows.js +2 -2
- package/Libraries/Pressability/Pressability.js +9 -9
- package/Libraries/Pressability/Pressability.windows.js +17 -16
- package/Libraries/ReactNative/AppRegistry.flow.js +1 -1
- package/Libraries/ReactNative/BridgelessUIManager.js +1 -1
- package/Libraries/ReactNative/FabricUIManager.js +1 -1
- package/Libraries/ReactNative/PaperUIManager.js +1 -1
- package/Libraries/ReactNative/PaperUIManager.windows.js +1 -1
- package/Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricPublicInstance.js +1 -1
- package/Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricPublicInstanceUtils.js +2 -2
- package/Libraries/ReactNative/ReactFabricPublicInstance/ReactNativeAttributePayload.js +1 -1
- package/Libraries/ReactNative/RendererImplementation.js +1 -1
- package/Libraries/ReactNative/getNativeComponentAttributes.js +1 -1
- package/Libraries/ReactPrivate/ReactNativePrivateInterface.js +1 -2
- package/Libraries/Renderer/implementations/ReactFabric-dev.js +3 -3
- package/Libraries/Renderer/implementations/ReactFabric-prod.js +3 -3
- package/Libraries/Renderer/implementations/ReactFabric-profiling.js +3 -3
- package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +11 -4
- package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +11 -4
- package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +11 -4
- package/Libraries/Renderer/shims/ReactFabric.js +3 -1
- package/Libraries/Renderer/shims/ReactFeatureFlags.js +3 -1
- package/Libraries/Renderer/shims/ReactNative.js +2 -2
- package/Libraries/Renderer/shims/ReactNativeTypes.js +3 -1
- package/Libraries/Renderer/shims/ReactNativeTypes.windows.js +3 -1
- package/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +3 -1
- package/Libraries/Renderer/shims/createReactNativeComponentClass.js +3 -1
- package/Libraries/Settings/Settings.ios.js +1 -1
- package/Libraries/StyleSheet/PlatformColorValueTypes.android.js +2 -2
- package/Libraries/StyleSheet/PlatformColorValueTypes.ios.js +1 -1
- package/Libraries/StyleSheet/PlatformColorValueTypes.js.flow +4 -2
- package/Libraries/StyleSheet/StyleSheetExports.js +1 -1
- package/Libraries/StyleSheet/StyleSheetTypes.d.ts +99 -4
- package/Libraries/StyleSheet/StyleSheetTypes.js +6 -8
- package/Libraries/StyleSheet/processFilter.js +1 -1
- package/Libraries/Text/Text.js +46 -6
- package/Libraries/Text/Text.windows.js +46 -6
- package/Libraries/Text/TextNativeComponent.js +1 -1
- package/Libraries/Text/TextProps.js +7 -7
- package/Libraries/Text/TextProps.windows.js +7 -7
- package/Libraries/Types/CodegenTypes.js +1 -1
- package/Libraries/Types/CoreEventTypes.js +31 -0
- package/Libraries/Types/CoreEventTypes.windows.js +31 -13
- package/Libraries/Types/ReactDevToolsTypes.js +2 -2
- package/Libraries/Utilities/Appearance.js +2 -2
- package/Libraries/Utilities/DevLoadingView.js +8 -1
- package/Libraries/Utilities/DevSettings.js +3 -3
- package/Libraries/Utilities/HMRClient.js +4 -3
- package/Libraries/Utilities/RCTLog.js +3 -3
- package/Libraries/Utilities/ReactNativeTestTools.js +1 -1
- package/Libraries/Utilities/SceneTracker.js +1 -1
- package/Libraries/Utilities/codegenNativeCommands.js +1 -1
- package/Libraries/Utilities/deepFreezeAndThrowOnMutationInDev.js +3 -3
- package/Libraries/Utilities/logError.js +1 -1
- package/Libraries/Utilities/stringifySafe.js +7 -7
- package/Libraries/Utilities/useRefEffect.js +1 -1
- package/Libraries/WebSocket/WebSocketInterceptor.js +3 -3
- package/Libraries/promiseRejectionTrackingOptions.js +8 -8
- package/Libraries/vendor/core/ErrorUtils.js +10 -10
- package/Libraries/vendor/emitter/EventEmitter.js +6 -6
- package/Microsoft.ReactNative/Fabric/AbiViewProps.cpp +5 -0
- package/Microsoft.ReactNative/Fabric/AbiViewProps.h +1 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionContextHelper.cpp +58 -20
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +5 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +302 -67
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +19 -4
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +23 -12
- package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp +4 -0
- package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h +1 -0
- package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +0 -2
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +98 -44
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +4 -2
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +2 -3
- package/Microsoft.ReactNative/Fabric/ReactTaggedView.h +2 -2
- package/Microsoft.ReactNative/Fabric/WindowsComponentDescriptorRegistry.cpp +3 -3
- package/Microsoft.ReactNative/Fabric/WindowsComponentDescriptorRegistry.h +3 -1
- package/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp +0 -1
- package/Microsoft.ReactNative/IReactCompositionViewComponentBuilder.idl +2 -0
- package/Microsoft.ReactNative/Modules/Animated/AnimatedNode.cpp +3 -3
- package/Microsoft.ReactNative/Modules/Animated/AnimatedNode.h +3 -2
- package/Microsoft.ReactNative/Modules/Timing.h +2 -1
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +6 -0
- package/Microsoft.ReactNative/ViewProps.idl +9 -0
- package/Microsoft.ReactNative.Cxx/ReactCommon/TurboModule.h +12 -2
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/PropertySheets/JSEngine.props +1 -1
- package/ReactCommon/ReactCommon.vcxproj +7 -1
- package/ReactCommon/ReactCommon.vcxproj.filters +0 -3
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/JSIndexedRAMBundle.cpp +5 -5
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/ReactMarker.cpp +0 -1
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsiexecutor/jsireact/JSIExecutor.cpp +2 -43
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/nativemodule/core/ReactCommon/TurboModule.h +12 -2
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/attributedstring/TextAttributes.cpp +291 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/core/EventDispatcher.cpp +0 -1
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/core/EventQueueProcessor.cpp +1 -3
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/core/propsConversions.h +199 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/uimanager/UIManager.cpp +6 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/runtime/ReactInstance.cpp +17 -10
- package/Scripts/creaternwapp.cmd +8 -1
- package/Scripts/creaternwlib.cmd +21 -2
- package/Shared/DevSettings.h +0 -3
- package/Shared/Modules/WebSocketModule.cpp +0 -1
- package/Shared/Modules/WebSocketModule.h +62 -3
- package/Shared/OInstance.cpp +5 -0
- package/Shared/Shared.vcxitems +4 -6
- package/Shared/Shared.vcxitems.filters +218 -709
- package/codegen/NativeAccessibilityManagerSpec.g.h +2 -0
- package/codegen/NativeAnimatedModuleSpec.g.h +21 -15
- package/codegen/NativeDevLoadingViewSpec.g.h +3 -3
- package/codegen/NativeIntentAndroidSpec.g.h +16 -3
- package/codegen/NativeReactNativeFeatureFlagsSpec.g.h +209 -191
- package/codegen/react/components/rnwcore/EventEmitters.h +1 -0
- package/codegen/react/components/rnwcore/Props.h +14 -0
- package/codegen/rnwcoreJSI.h +246 -211
- package/index.js +3 -0
- package/index.windows.js +3 -0
- package/jest/mock.js +2 -2
- package/jest/mockComponent.js +1 -1
- package/jest/setup.js +1 -1
- package/package.json +22 -21
- package/src/private/animated/NativeAnimatedHelper.js +130 -125
- package/src/private/animated/NativeAnimatedValidation.js +7 -4
- package/src/private/animated/createAnimatedPropsHook.js +13 -5
- package/src/private/animated/createAnimatedPropsMemoHook.js +10 -10
- package/src/private/components/virtualview/VirtualView.js +16 -9
- package/src/private/components/virtualview/logger/VirtualViewLogger.js +21 -0
- package/src/private/components/virtualview/logger/VirtualViewLoggerTypes.js +24 -0
- package/src/private/devsupport/devmenu/elementinspector/ElementProperties.js +1 -1
- package/src/private/devsupport/devmenu/elementinspector/Inspector.js +6 -25
- package/src/private/devsupport/devmenu/elementinspector/InspectorPanel.js +1 -27
- package/src/private/devsupport/devmenu/elementinspector/XHRInterceptor.js +3 -2
- package/src/private/featureflags/ReactNativeFeatureFlags.js +63 -42
- package/src/private/featureflags/ReactNativeFeatureFlagsBase.js +3 -3
- package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +12 -9
- package/src/private/renderer/errorhandling/ErrorHandlers.js +7 -4
- package/src/private/specs_DEPRECATED/modules/NativeAccessibilityManager.js +1 -1
- package/src/private/specs_DEPRECATED/modules/NativeAnimatedModule.js +4 -0
- package/src/private/specs_DEPRECATED/modules/NativeDevLoadingView.js +1 -0
- package/src/private/webapis/dom/events/CustomEvent.js +3 -3
- package/src/private/webapis/dom/nodes/internals/ReactNativeDocumentElementInstanceHandle.js +1 -1
- package/src/private/webapis/dom/nodes/internals/ReactNativeDocumentInstanceHandle.js +1 -1
- package/src/private/webapis/dom/nodes/specs/NativeDOM.js +29 -29
- package/src/private/webapis/dom/oldstylecollections/HTMLCollection.js +1 -1
- package/src/private/webapis/dom/oldstylecollections/NodeList.js +2 -2
- package/src/private/webapis/geometry/DOMRectReadOnly.js +1 -1
- package/src/private/webapis/html/events/MessageEvent.js +3 -3
- package/src/private/webapis/idlecallbacks/specs/NativeIdleCallbacks.js +3 -3
- package/src/private/webapis/intersectionobserver/IntersectionObserver.js +53 -5
- package/src/private/webapis/intersectionobserver/internals/IntersectionObserverManager.js +2 -2
- package/src/private/webapis/intersectionobserver/specs/NativeIntersectionObserver.js +4 -4
- package/src/private/webapis/microtasks/specs/NativeMicrotasks.js +1 -1
- package/src/private/webapis/mutationobserver/MutationObserver.js +1 -1
- package/src/private/webapis/mutationobserver/MutationRecord.js +1 -1
- package/src/private/webapis/mutationobserver/specs/NativeMutationObserver.js +4 -4
- package/src/private/webapis/performance/Performance.js +1 -1
- package/src/private/webapis/performance/UserTiming.js +1 -1
- package/src/private/webapis/performance/specs/NativePerformance.js +3 -3
- package/src/private/webapis/structuredClone/structuredClone.js +3 -3
- package/src/types/globals.d.ts +30 -1
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/image/conversions.h +0 -178
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/imagemanager/primitives.h +0 -183
- package/Shared/Modules/WebSocketTurboModule.h +0 -71
- package/src/private/devsupport/devmenu/elementinspector/NetworkOverlay.js +0 -628
- package/src/private/devsupport/devmenu/perfmonitor/PerformanceOverlay.js +0 -66
|
@@ -250,7 +250,10 @@ void CompositionEventHandler::Initialize() noexcept {
|
|
|
250
250
|
if (strongThis->SurfaceId() == -1)
|
|
251
251
|
return;
|
|
252
252
|
|
|
253
|
-
auto
|
|
253
|
+
auto *rootView = strongThis->RootComponentView();
|
|
254
|
+
if (!rootView)
|
|
255
|
+
return;
|
|
256
|
+
auto focusedComponent = rootView->GetFocusedComponent();
|
|
254
257
|
auto keyboardSource = winrt::make<CompositionInputKeyboardSource>(source);
|
|
255
258
|
auto keyArgs =
|
|
256
259
|
winrt::make<winrt::Microsoft::ReactNative::Composition::Input::implementation::KeyRoutedEventArgs>(
|
|
@@ -276,7 +279,10 @@ void CompositionEventHandler::Initialize() noexcept {
|
|
|
276
279
|
if (strongThis->SurfaceId() == -1)
|
|
277
280
|
return;
|
|
278
281
|
|
|
279
|
-
auto
|
|
282
|
+
auto *rootView = strongThis->RootComponentView();
|
|
283
|
+
if (!rootView)
|
|
284
|
+
return;
|
|
285
|
+
auto focusedComponent = rootView->GetFocusedComponent();
|
|
280
286
|
auto keyboardSource = winrt::make<CompositionInputKeyboardSource>(source);
|
|
281
287
|
auto keyArgs =
|
|
282
288
|
winrt::make<winrt::Microsoft::ReactNative::Composition::Input::implementation::KeyRoutedEventArgs>(
|
|
@@ -303,7 +309,10 @@ void CompositionEventHandler::Initialize() noexcept {
|
|
|
303
309
|
if (strongThis->SurfaceId() == -1)
|
|
304
310
|
return;
|
|
305
311
|
|
|
306
|
-
auto
|
|
312
|
+
auto *rootView = strongThis->RootComponentView();
|
|
313
|
+
if (!rootView)
|
|
314
|
+
return;
|
|
315
|
+
auto focusedComponent = rootView->GetFocusedComponent();
|
|
307
316
|
auto keyboardSource = winrt::make<CompositionInputKeyboardSource>(source);
|
|
308
317
|
auto charArgs = winrt::make<
|
|
309
318
|
winrt::Microsoft::ReactNative::Composition::Input::implementation::CharacterReceivedRoutedEventArgs>(
|
|
@@ -330,7 +339,10 @@ void CompositionEventHandler::Initialize() noexcept {
|
|
|
330
339
|
if (strongThis->SurfaceId() == -1)
|
|
331
340
|
return;
|
|
332
341
|
|
|
333
|
-
auto
|
|
342
|
+
auto *rootView = strongThis->RootComponentView();
|
|
343
|
+
if (!rootView)
|
|
344
|
+
return;
|
|
345
|
+
auto focusedComponent = rootView->GetFocusedComponent();
|
|
334
346
|
if (focusedComponent) {
|
|
335
347
|
auto tag =
|
|
336
348
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(focusedComponent)
|
|
@@ -358,6 +370,7 @@ CompositionEventHandler::~CompositionEventHandler() {
|
|
|
358
370
|
pointerSource.PointerMoved(m_pointerMovedToken);
|
|
359
371
|
pointerSource.PointerCaptureLost(m_pointerCaptureLostToken);
|
|
360
372
|
pointerSource.PointerWheelChanged(m_pointerWheelChangedToken);
|
|
373
|
+
pointerSource.PointerExited(m_pointerExitedToken);
|
|
361
374
|
auto keyboardSource = winrt::Microsoft::UI::Input::InputKeyboardSource::GetForIsland(island);
|
|
362
375
|
keyboardSource.KeyDown(m_keyDownToken);
|
|
363
376
|
keyboardSource.KeyUp(m_keyUpToken);
|
|
@@ -380,10 +393,15 @@ facebook::react::SurfaceId CompositionEventHandler::SurfaceId() const noexcept {
|
|
|
380
393
|
return -1;
|
|
381
394
|
}
|
|
382
395
|
|
|
383
|
-
winrt::Microsoft::ReactNative::Composition::implementation::RootComponentView
|
|
396
|
+
winrt::Microsoft::ReactNative::Composition::implementation::RootComponentView *
|
|
384
397
|
CompositionEventHandler::RootComponentView() const noexcept {
|
|
385
398
|
auto island = m_wkRootView.get();
|
|
386
|
-
|
|
399
|
+
if (!island) {
|
|
400
|
+
return nullptr;
|
|
401
|
+
}
|
|
402
|
+
return winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>(island)
|
|
403
|
+
->GetComponentView()
|
|
404
|
+
.get();
|
|
387
405
|
}
|
|
388
406
|
|
|
389
407
|
void CompositionEventHandler::onPointerWheelChanged(
|
|
@@ -398,8 +416,11 @@ void CompositionEventHandler::onPointerWheelChanged(
|
|
|
398
416
|
|
|
399
417
|
// In the case of a sub rootview, we may have a non-zero origin. hitTest takes a pt in the parent coords, so we
|
|
400
418
|
// need to apply the current origin
|
|
401
|
-
|
|
402
|
-
|
|
419
|
+
auto *rootView = RootComponentView();
|
|
420
|
+
if (!rootView)
|
|
421
|
+
return;
|
|
422
|
+
ptScaled += rootView->layoutMetrics().frame.origin;
|
|
423
|
+
auto tag = rootView->hitTest(ptScaled, ptLocal);
|
|
403
424
|
|
|
404
425
|
if (tag == -1)
|
|
405
426
|
return;
|
|
@@ -553,7 +574,10 @@ int64_t CompositionEventHandler::SendMessage(HWND hwnd, uint32_t msg, uint64_t w
|
|
|
553
574
|
case WM_CHAR:
|
|
554
575
|
case WM_SYSCHAR: {
|
|
555
576
|
if (auto strongRootView = m_wkRootView.get()) {
|
|
556
|
-
auto
|
|
577
|
+
auto *rootView = RootComponentView();
|
|
578
|
+
if (!rootView)
|
|
579
|
+
break;
|
|
580
|
+
auto focusedComponent = rootView->GetFocusedComponent();
|
|
557
581
|
auto keyboardSource = winrt::make<CompositionKeyboardSource>(this);
|
|
558
582
|
auto args = winrt::make<
|
|
559
583
|
winrt::Microsoft::ReactNative::Composition::Input::implementation::CharacterReceivedRoutedEventArgs>(
|
|
@@ -576,7 +600,10 @@ int64_t CompositionEventHandler::SendMessage(HWND hwnd, uint32_t msg, uint64_t w
|
|
|
576
600
|
case WM_SYSKEYDOWN:
|
|
577
601
|
case WM_SYSKEYUP: {
|
|
578
602
|
if (auto strongRootView = m_wkRootView.get()) {
|
|
579
|
-
auto
|
|
603
|
+
auto *rootView = RootComponentView();
|
|
604
|
+
if (!rootView)
|
|
605
|
+
break;
|
|
606
|
+
auto focusedComponent = rootView->GetFocusedComponent();
|
|
580
607
|
auto keyboardSource = winrt::make<CompositionKeyboardSource>(this);
|
|
581
608
|
auto args = winrt::make<winrt::Microsoft::ReactNative::Composition::Input::implementation::KeyRoutedEventArgs>(
|
|
582
609
|
focusedComponent
|
|
@@ -608,9 +635,12 @@ int64_t CompositionEventHandler::SendMessage(HWND hwnd, uint32_t msg, uint64_t w
|
|
|
608
635
|
|
|
609
636
|
void CompositionEventHandler::onKeyDown(
|
|
610
637
|
const winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs &args) noexcept {
|
|
611
|
-
RootComponentView()
|
|
638
|
+
auto *rootView = RootComponentView();
|
|
639
|
+
if (!rootView)
|
|
640
|
+
return;
|
|
641
|
+
rootView->UseKeyboardForProgrammaticFocus(true);
|
|
612
642
|
|
|
613
|
-
if (auto focusedComponent =
|
|
643
|
+
if (auto focusedComponent = rootView->GetFocusedComponent()) {
|
|
614
644
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(focusedComponent)->OnKeyDown(args);
|
|
615
645
|
|
|
616
646
|
if (args.Handled())
|
|
@@ -633,7 +663,7 @@ void CompositionEventHandler::onKeyDown(
|
|
|
633
663
|
}
|
|
634
664
|
|
|
635
665
|
if (!fCtrl && args.Key() == winrt::Windows::System::VirtualKey::Tab) {
|
|
636
|
-
if (
|
|
666
|
+
if (rootView->TryMoveFocus(!fShift, winrt::Microsoft::ReactNative::FocusState::Keyboard)) {
|
|
637
667
|
args.Handled(true);
|
|
638
668
|
}
|
|
639
669
|
|
|
@@ -643,9 +673,12 @@ void CompositionEventHandler::onKeyDown(
|
|
|
643
673
|
|
|
644
674
|
void CompositionEventHandler::onKeyUp(
|
|
645
675
|
const winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs &args) noexcept {
|
|
646
|
-
RootComponentView()
|
|
676
|
+
auto *rootView = RootComponentView();
|
|
677
|
+
if (!rootView)
|
|
678
|
+
return;
|
|
679
|
+
rootView->UseKeyboardForProgrammaticFocus(true);
|
|
647
680
|
|
|
648
|
-
if (auto focusedComponent =
|
|
681
|
+
if (auto focusedComponent = rootView->GetFocusedComponent()) {
|
|
649
682
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(focusedComponent)->OnKeyUp(args);
|
|
650
683
|
|
|
651
684
|
if (args.Handled())
|
|
@@ -655,7 +688,10 @@ void CompositionEventHandler::onKeyUp(
|
|
|
655
688
|
|
|
656
689
|
void CompositionEventHandler::onCharacterReceived(
|
|
657
690
|
const winrt::Microsoft::ReactNative::Composition::Input::CharacterReceivedRoutedEventArgs &args) noexcept {
|
|
658
|
-
|
|
691
|
+
auto *rootView = RootComponentView();
|
|
692
|
+
if (!rootView)
|
|
693
|
+
return;
|
|
694
|
+
if (auto focusedComponent = rootView->GetFocusedComponent()) {
|
|
659
695
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(focusedComponent)
|
|
660
696
|
->OnCharacterReceived(args);
|
|
661
697
|
|
|
@@ -664,7 +700,7 @@ void CompositionEventHandler::onCharacterReceived(
|
|
|
664
700
|
}
|
|
665
701
|
}
|
|
666
702
|
|
|
667
|
-
std::vector<winrt::Microsoft::ReactNative::ComponentView> GetTouchableViewsInPathToRoot(
|
|
703
|
+
std::vector<winrt::Microsoft::ReactNative::ComponentView> CompositionEventHandler::GetTouchableViewsInPathToRoot(
|
|
668
704
|
const winrt::Microsoft::ReactNative::ComponentView &componentView) {
|
|
669
705
|
std::vector<winrt::Microsoft::ReactNative::ComponentView> results;
|
|
670
706
|
auto view = componentView;
|
|
@@ -674,6 +710,7 @@ std::vector<winrt::Microsoft::ReactNative::ComponentView> GetTouchableViewsInPat
|
|
|
674
710
|
}
|
|
675
711
|
view = view.Parent();
|
|
676
712
|
}
|
|
713
|
+
|
|
677
714
|
return results;
|
|
678
715
|
}
|
|
679
716
|
|
|
@@ -974,8 +1011,8 @@ void CompositionEventHandler::UpdateActiveTouch(
|
|
|
974
1011
|
// activeTouch.touch.isEraser = false;
|
|
975
1012
|
activeTouch.touch.pagePoint.x = ptScaled.x;
|
|
976
1013
|
activeTouch.touch.pagePoint.y = ptScaled.y;
|
|
977
|
-
activeTouch.touch.screenPoint.x =
|
|
978
|
-
activeTouch.touch.screenPoint.y =
|
|
1014
|
+
activeTouch.touch.screenPoint.x = ptScaled.x;
|
|
1015
|
+
activeTouch.touch.screenPoint.y = ptScaled.y;
|
|
979
1016
|
activeTouch.touch.offsetPoint.x = ptLocal.x;
|
|
980
1017
|
activeTouch.touch.offsetPoint.y = ptLocal.y;
|
|
981
1018
|
activeTouch.touch.timestamp = static_cast<facebook::react::Float>(
|
|
@@ -986,8 +1023,6 @@ void CompositionEventHandler::UpdateActiveTouch(
|
|
|
986
1023
|
// activeTouch.touch.shiftKey = false;
|
|
987
1024
|
// activeTouch.touch.ctrlKey = false;
|
|
988
1025
|
// activeTouch.touch.altKey = false;
|
|
989
|
-
|
|
990
|
-
// activeTouch.touch.isPrimary = true;
|
|
991
1026
|
}
|
|
992
1027
|
|
|
993
1028
|
facebook::react::PointerEvent CreatePointerEventFromIncompleteHoverData(
|
|
@@ -1030,9 +1065,12 @@ void CompositionEventHandler::getTargetPointerArgs(
|
|
|
1030
1065
|
|
|
1031
1066
|
// In the case of a sub rootview, we may have a non-zero origin. hitTest takes a pt in the parent coords, so we need
|
|
1032
1067
|
// to apply the current origin
|
|
1033
|
-
|
|
1068
|
+
auto *rootView = RootComponentView();
|
|
1069
|
+
if (!rootView)
|
|
1070
|
+
return;
|
|
1071
|
+
ptScaled += rootView->layoutMetrics().frame.origin;
|
|
1034
1072
|
|
|
1035
|
-
if (
|
|
1073
|
+
if (m_capturedPointers.count(pointerId)) {
|
|
1036
1074
|
assert(m_pointerCapturingComponentTag != -1);
|
|
1037
1075
|
tag = m_pointerCapturingComponentTag;
|
|
1038
1076
|
|
|
@@ -1044,7 +1082,7 @@ void CompositionEventHandler::getTargetPointerArgs(
|
|
|
1044
1082
|
ptLocal.y = ptScaled.y - (clientRect.top / strongRootView.ScaleFactor());
|
|
1045
1083
|
}
|
|
1046
1084
|
} else {
|
|
1047
|
-
tag =
|
|
1085
|
+
tag = rootView->hitTest(ptScaled, ptLocal);
|
|
1048
1086
|
}
|
|
1049
1087
|
}
|
|
1050
1088
|
|
|
@@ -1054,16 +1092,49 @@ void CompositionEventHandler::onPointerCaptureLost(
|
|
|
1054
1092
|
if (SurfaceId() == -1)
|
|
1055
1093
|
return;
|
|
1056
1094
|
|
|
1057
|
-
if (m_pointerCapturingComponentTag) {
|
|
1095
|
+
if (m_pointerCapturingComponentTag != -1) {
|
|
1058
1096
|
// copy array to avoid iterator being invalidated during deletion
|
|
1059
|
-
std::
|
|
1097
|
+
std::unordered_set<PointerId> capturedPointers = m_capturedPointers;
|
|
1060
1098
|
|
|
1061
1099
|
for (auto pointerId : capturedPointers) {
|
|
1062
1100
|
releasePointerCapture(pointerId, m_pointerCapturingComponentTag);
|
|
1101
|
+
|
|
1102
|
+
// Cancel any active touch for this pointer so React Native is notified that
|
|
1103
|
+
// the touch ended. Without this, m_activeTouches retains a zombie entry and
|
|
1104
|
+
// RN JS is never told the touch is gone — leaving Pressables stuck in a
|
|
1105
|
+
// pressed state after a system-interrupted gesture (e.g. system back swipe,
|
|
1106
|
+
// Alt+Tab, another window coming foreground).
|
|
1107
|
+
auto activeTouch = m_activeTouches.find(pointerId);
|
|
1108
|
+
if (activeTouch != m_activeTouches.end()) {
|
|
1109
|
+
ActiveTouch cancelledTouchCopy = std::move(activeTouch->second);
|
|
1110
|
+
m_activeTouches.erase(activeTouch);
|
|
1111
|
+
if (cancelledTouchCopy.eventEmitter) {
|
|
1112
|
+
DispatchSynthesizedTouchCancelForActiveTouch(cancelledTouchCopy, pointerPoint, keyModifiers);
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1063
1115
|
}
|
|
1064
1116
|
|
|
1065
1117
|
m_pointerCapturingComponentTag = -1;
|
|
1066
1118
|
}
|
|
1119
|
+
|
|
1120
|
+
// Also cancel any active touch for the specific pointer that lost capture, even
|
|
1121
|
+
// when no JS-level CapturePointer was ever issued. This handles ScrollView (and
|
|
1122
|
+
// any other VisualInteractionSource) calling TryRedirectForManipulation: the OS
|
|
1123
|
+
// reassigns the pointer to the InteractionTracker, fires PointerCaptureLost, and
|
|
1124
|
+
// then stops delivering PointerMoved/PointerReleased to us. Without this cleanup
|
|
1125
|
+
// m_activeTouches keeps a zombie entry whose target is the originally-pressed
|
|
1126
|
+
// Pressable, leaving it visually pressed and causing later taps to be attributed
|
|
1127
|
+
// to that original target. If the entry was already cleared above (for a JS-level
|
|
1128
|
+
// capture) or by onPointerReleased running first, the find() is a no-op.
|
|
1129
|
+
PointerId pointerId = pointerPoint.PointerId();
|
|
1130
|
+
auto activeTouch = m_activeTouches.find(pointerId);
|
|
1131
|
+
if (activeTouch != m_activeTouches.end()) {
|
|
1132
|
+
ActiveTouch cancelledTouchCopy = std::move(activeTouch->second);
|
|
1133
|
+
m_activeTouches.erase(activeTouch);
|
|
1134
|
+
if (cancelledTouchCopy.eventEmitter) {
|
|
1135
|
+
DispatchSynthesizedTouchCancelForActiveTouch(cancelledTouchCopy, pointerPoint, keyModifiers);
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1067
1138
|
}
|
|
1068
1139
|
|
|
1069
1140
|
void CompositionEventHandler::onPointerMoved(
|
|
@@ -1103,10 +1174,11 @@ void CompositionEventHandler::onPointerMoved(
|
|
|
1103
1174
|
|
|
1104
1175
|
auto handler = [&, targetView, pointerEvent, isActiveTouch](
|
|
1105
1176
|
std::vector<winrt::Microsoft::ReactNative::ComponentView> &eventPathViews) {
|
|
1177
|
+
auto *rootViewForEmitter = RootComponentView();
|
|
1106
1178
|
const auto eventEmitter = targetView
|
|
1107
1179
|
? winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(targetView)
|
|
1108
1180
|
->eventEmitterAtPoint(pointerEvent.offsetPoint)
|
|
1109
|
-
:
|
|
1181
|
+
: (rootViewForEmitter ? rootViewForEmitter->eventEmitterAtPoint(pointerEvent.offsetPoint) : nullptr);
|
|
1110
1182
|
|
|
1111
1183
|
if (eventEmitter != nullptr) {
|
|
1112
1184
|
eventEmitter->onPointerMove(pointerEvent);
|
|
@@ -1132,7 +1204,10 @@ void CompositionEventHandler::ClearAllHoveredForPointer(const facebook::react::P
|
|
|
1132
1204
|
// events. If we get null for the targetView, that means that the mouse is no over any components, so we have no
|
|
1133
1205
|
// element to send the move event to. However we need to send something so that any previously hovered elements
|
|
1134
1206
|
// are no longer hovered.
|
|
1135
|
-
auto
|
|
1207
|
+
auto *rootView = RootComponentView();
|
|
1208
|
+
if (!rootView)
|
|
1209
|
+
return;
|
|
1210
|
+
auto children = rootView->Children();
|
|
1136
1211
|
if (auto size = children.Size()) {
|
|
1137
1212
|
auto firstChild = children.GetAt(0);
|
|
1138
1213
|
if (auto childEventEmitter =
|
|
@@ -1172,28 +1247,67 @@ void CompositionEventHandler::onPointerExited(
|
|
|
1172
1247
|
}
|
|
1173
1248
|
}
|
|
1174
1249
|
|
|
1250
|
+
// Windows touch pointer IDs can be arbitrarily large (e.g. 2233). React Native's JS
|
|
1251
|
+
// touch handler uses identifiers as array indices and warns/misbehaves for values > 20.
|
|
1252
|
+
// This function maps each live Windows pointer to a small identifier in [0, 19] by
|
|
1253
|
+
// scanning m_activeTouches for in-use slots and cycling from the last assigned index.
|
|
1254
|
+
// Identifier MOUSE_POINTER_ID (1) is permanently reserved for mouse and never returned here.
|
|
1255
|
+
int CompositionEventHandler::AllocateTouchIdentifier() noexcept {
|
|
1256
|
+
constexpr int kMaxTouchIdentifier = 20;
|
|
1257
|
+
for (int i = 0; i < kMaxTouchIdentifier; i++) {
|
|
1258
|
+
int candidate = (m_touchId + i) % kMaxTouchIdentifier;
|
|
1259
|
+
if (candidate == static_cast<int>(MOUSE_POINTER_ID)) {
|
|
1260
|
+
continue; // reserved for mouse
|
|
1261
|
+
}
|
|
1262
|
+
bool inUse = std::any_of(m_activeTouches.begin(), m_activeTouches.end(), [candidate](const auto &pair) {
|
|
1263
|
+
return pair.second.touch.identifier == candidate;
|
|
1264
|
+
});
|
|
1265
|
+
if (!inUse) {
|
|
1266
|
+
m_touchId = (candidate + 1) % kMaxTouchIdentifier;
|
|
1267
|
+
return candidate;
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
// All non-mouse slots occupied (> 19 simultaneous touch/pen points) — wrap anyway,
|
|
1271
|
+
// skipping the mouse-reserved slot.
|
|
1272
|
+
int fallback = m_touchId;
|
|
1273
|
+
m_touchId = (m_touchId + 1) % kMaxTouchIdentifier;
|
|
1274
|
+
if (fallback == static_cast<int>(MOUSE_POINTER_ID)) {
|
|
1275
|
+
fallback = m_touchId;
|
|
1276
|
+
m_touchId = (m_touchId + 1) % kMaxTouchIdentifier;
|
|
1277
|
+
}
|
|
1278
|
+
return fallback;
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1175
1281
|
void CompositionEventHandler::onPointerPressed(
|
|
1176
1282
|
const winrt::Microsoft::ReactNative::Composition::Input::PointerPoint &pointerPoint,
|
|
1177
1283
|
winrt::Windows::System::VirtualKeyModifiers keyModifiers) noexcept {
|
|
1178
1284
|
namespace Composition = winrt::Microsoft::ReactNative::Composition;
|
|
1179
1285
|
|
|
1180
|
-
RootComponentView()
|
|
1286
|
+
auto *rootView = RootComponentView();
|
|
1287
|
+
if (!rootView)
|
|
1288
|
+
return;
|
|
1289
|
+
rootView->UseKeyboardForProgrammaticFocus(false);
|
|
1181
1290
|
|
|
1182
1291
|
// Clears any active text selection when left pointer is pressed
|
|
1183
1292
|
if (pointerPoint.Properties().PointerUpdateKind() != Composition::Input::PointerUpdateKind::RightButtonPressed) {
|
|
1184
|
-
|
|
1293
|
+
rootView->ClearCurrentTextSelection();
|
|
1185
1294
|
}
|
|
1186
1295
|
|
|
1187
1296
|
PointerId pointerId = pointerPoint.PointerId();
|
|
1188
1297
|
|
|
1189
|
-
auto staleTouch =
|
|
1190
|
-
return pair.second.touch.identifier == pointerId;
|
|
1191
|
-
});
|
|
1298
|
+
auto staleTouch = m_activeTouches.find(pointerId);
|
|
1192
1299
|
|
|
1193
1300
|
if (staleTouch != m_activeTouches.end()) {
|
|
1194
|
-
// A pointer with this ID
|
|
1195
|
-
//
|
|
1196
|
-
|
|
1301
|
+
// A previous pointer with this ID was never properly released (e.g., app lost focus,
|
|
1302
|
+
// pointer left window). Cancel the stale touch and clean it up so the new press can proceed.
|
|
1303
|
+
// Copy and erase before dispatching to avoid holding a reference into m_activeTouches
|
|
1304
|
+
// across DispatchSynthesizedTouchCancelForActiveTouch, which calls HandleIncomingPointerEvent
|
|
1305
|
+
// and iterates m_activeTouches internally.
|
|
1306
|
+
ActiveTouch staleTouchCopy = std::move(staleTouch->second);
|
|
1307
|
+
m_activeTouches.erase(staleTouch);
|
|
1308
|
+
if (staleTouchCopy.eventEmitter) {
|
|
1309
|
+
DispatchSynthesizedTouchCancelForActiveTouch(staleTouchCopy, pointerPoint, keyModifiers);
|
|
1310
|
+
}
|
|
1197
1311
|
}
|
|
1198
1312
|
|
|
1199
1313
|
const auto eventType = TouchEventType::Start;
|
|
@@ -1214,7 +1328,18 @@ void CompositionEventHandler::onPointerPressed(
|
|
|
1214
1328
|
->OnPointerPressed(args);
|
|
1215
1329
|
|
|
1216
1330
|
ActiveTouch activeTouch{0};
|
|
1217
|
-
|
|
1331
|
+
switch (pointerPoint.PointerDeviceType()) {
|
|
1332
|
+
case Composition::Input::PointerDeviceType::Touch:
|
|
1333
|
+
activeTouch.touchType = UITouchType::Touch;
|
|
1334
|
+
break;
|
|
1335
|
+
case Composition::Input::PointerDeviceType::Pen:
|
|
1336
|
+
activeTouch.touchType = UITouchType::Pen;
|
|
1337
|
+
break;
|
|
1338
|
+
case Composition::Input::PointerDeviceType::Mouse:
|
|
1339
|
+
default:
|
|
1340
|
+
activeTouch.touchType = UITouchType::Mouse;
|
|
1341
|
+
break;
|
|
1342
|
+
}
|
|
1218
1343
|
|
|
1219
1344
|
// Map PointerUpdateKind to W3C button value
|
|
1220
1345
|
// https://developer.mozilla.org/docs/Web/API/MouseEvent/button
|
|
@@ -1246,20 +1371,33 @@ void CompositionEventHandler::onPointerPressed(
|
|
|
1246
1371
|
->eventEmitterAtPoint(ptLocal)) {
|
|
1247
1372
|
activeTouch.eventEmitter = eventEmitter;
|
|
1248
1373
|
activeTouch.touch.target = targetComponentView.Tag();
|
|
1249
|
-
|
|
1374
|
+
activeTouch.initialComponentView = targetComponentView;
|
|
1250
1375
|
break;
|
|
1251
1376
|
}
|
|
1252
1377
|
targetComponentView = targetComponentView.Parent();
|
|
1253
1378
|
}
|
|
1254
1379
|
|
|
1380
|
+
// Don't register the touch if no eventEmitter was found — inserting a null-emitter entry
|
|
1381
|
+
// into m_activeTouches would block future presses with the same pointer ID.
|
|
1382
|
+
if (!activeTouch.eventEmitter) {
|
|
1383
|
+
return;
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1255
1386
|
UpdateActiveTouch(activeTouch, ptScaled, ptLocal);
|
|
1256
1387
|
|
|
1257
|
-
|
|
1258
|
-
|
|
1388
|
+
activeTouch.isPrimary = pointerId == 1;
|
|
1389
|
+
// Map the Windows pointer ID to a small identifier (0–19) safe for use as a JS array index.
|
|
1390
|
+
// Windows touch IDs can be arbitrarily large (e.g. 2233), which causes React Native to warn
|
|
1391
|
+
// and corrupts touch state, leaving Pressables stuck after a scroll.
|
|
1392
|
+
// Mouse pointer ID is always 1 (MOUSE_POINTER_ID), which is already within the safe range —
|
|
1393
|
+
// use it directly to preserve stable, predictable identifier assignment for mouse input.
|
|
1394
|
+
activeTouch.touch.identifier = (pointerPoint.PointerDeviceType() == Composition::Input::PointerDeviceType::Mouse)
|
|
1395
|
+
? static_cast<int>(MOUSE_POINTER_ID)
|
|
1396
|
+
: AllocateTouchIdentifier();
|
|
1259
1397
|
|
|
1260
1398
|
// If the pointer has not been marked as hovering over views before the touch started, we register
|
|
1261
1399
|
// that the activeTouch should not maintain its hovered state once the pointer has been lifted.
|
|
1262
|
-
auto currentlyHoveredTags = m_currentlyHoveredViewsPerPointer.find(
|
|
1400
|
+
auto currentlyHoveredTags = m_currentlyHoveredViewsPerPointer.find(pointerId);
|
|
1263
1401
|
if (currentlyHoveredTags == m_currentlyHoveredViewsPerPointer.end() || currentlyHoveredTags->second.empty()) {
|
|
1264
1402
|
activeTouch.shouldLeaveWhenReleased = true;
|
|
1265
1403
|
}
|
|
@@ -1275,11 +1413,12 @@ void CompositionEventHandler::onPointerReleased(
|
|
|
1275
1413
|
winrt::Windows::System::VirtualKeyModifiers keyModifiers) noexcept {
|
|
1276
1414
|
int pointerId = pointerPoint.PointerId();
|
|
1277
1415
|
|
|
1278
|
-
RootComponentView()
|
|
1416
|
+
auto *rootView = RootComponentView();
|
|
1417
|
+
if (!rootView)
|
|
1418
|
+
return;
|
|
1419
|
+
rootView->UseKeyboardForProgrammaticFocus(false);
|
|
1279
1420
|
|
|
1280
|
-
auto activeTouch =
|
|
1281
|
-
return pair.second.touch.identifier == pointerId;
|
|
1282
|
-
});
|
|
1421
|
+
auto activeTouch = m_activeTouches.find(pointerId);
|
|
1283
1422
|
|
|
1284
1423
|
if (activeTouch == m_activeTouches.end()) {
|
|
1285
1424
|
return;
|
|
@@ -1291,8 +1430,13 @@ void CompositionEventHandler::onPointerReleased(
|
|
|
1291
1430
|
facebook::react::Point ptLocal, ptScaled;
|
|
1292
1431
|
getTargetPointerArgs(fabricuiManager, pointerPoint, tag, ptScaled, ptLocal);
|
|
1293
1432
|
|
|
1294
|
-
if (tag == -1)
|
|
1433
|
+
if (tag == -1) {
|
|
1434
|
+
if (activeTouch->second.eventEmitter) {
|
|
1435
|
+
DispatchSynthesizedTouchCancelForActiveTouch(activeTouch->second, pointerPoint, keyModifiers);
|
|
1436
|
+
}
|
|
1437
|
+
m_activeTouches.erase(pointerId);
|
|
1295
1438
|
return;
|
|
1439
|
+
}
|
|
1296
1440
|
|
|
1297
1441
|
auto targetComponentView = fabricuiManager->GetViewRegistry().componentViewDescriptorWithTag(tag).view;
|
|
1298
1442
|
auto args = winrt::make<winrt::Microsoft::ReactNative::Composition::Input::implementation::PointerRoutedEventArgs>(
|
|
@@ -1324,7 +1468,7 @@ bool CompositionEventHandler::CapturePointer(
|
|
|
1324
1468
|
}
|
|
1325
1469
|
|
|
1326
1470
|
m_pointerCapturingComponentTag = tag;
|
|
1327
|
-
m_capturedPointers.
|
|
1471
|
+
m_capturedPointers.insert(pointer.PointerId());
|
|
1328
1472
|
return true;
|
|
1329
1473
|
}
|
|
1330
1474
|
|
|
@@ -1339,11 +1483,9 @@ bool CompositionEventHandler::releasePointerCapture(PointerId pointerId, faceboo
|
|
|
1339
1483
|
bool result = false;
|
|
1340
1484
|
|
|
1341
1485
|
if (m_pointerCapturingComponentTag == tag) {
|
|
1342
|
-
|
|
1343
|
-
if (it == m_capturedPointers.end()) {
|
|
1486
|
+
if (m_capturedPointers.erase(pointerId) == 0) {
|
|
1344
1487
|
return false;
|
|
1345
1488
|
}
|
|
1346
|
-
m_capturedPointers.erase(it);
|
|
1347
1489
|
|
|
1348
1490
|
if (std::shared_ptr<FabricUIManager> fabricuiManager =
|
|
1349
1491
|
::Microsoft::ReactNative::FabricUIManager::FromProperties(m_context.Properties())) {
|
|
@@ -1354,7 +1496,7 @@ bool CompositionEventHandler::releasePointerCapture(PointerId pointerId, faceboo
|
|
|
1354
1496
|
->OnPointerCaptureLost();
|
|
1355
1497
|
}
|
|
1356
1498
|
|
|
1357
|
-
if (m_capturedPointers.
|
|
1499
|
+
if (m_capturedPointers.empty()) {
|
|
1358
1500
|
m_pointerCapturingComponentTag = -1;
|
|
1359
1501
|
return true;
|
|
1360
1502
|
}
|
|
@@ -1459,11 +1601,83 @@ facebook::react::PointerEvent CompositionEventHandler::CreatePointerEventFromAct
|
|
|
1459
1601
|
|
|
1460
1602
|
// event.tangentialPressure = 0.0;
|
|
1461
1603
|
// event.twist = 0;
|
|
1462
|
-
|
|
1604
|
+
event.isPrimary = activeTouch.isPrimary;
|
|
1463
1605
|
|
|
1464
1606
|
return event;
|
|
1465
1607
|
}
|
|
1466
1608
|
|
|
1609
|
+
bool CompositionEventHandler::IsPointerWithinInitialTree(const ActiveTouch &activeTouch) noexcept {
|
|
1610
|
+
auto initialComponentView = activeTouch.initialComponentView.view();
|
|
1611
|
+
if (!initialComponentView)
|
|
1612
|
+
return false;
|
|
1613
|
+
|
|
1614
|
+
auto *rootView = RootComponentView();
|
|
1615
|
+
if (!rootView)
|
|
1616
|
+
return false;
|
|
1617
|
+
|
|
1618
|
+
facebook::react::Point ptLocal;
|
|
1619
|
+
auto currentTag = rootView->hitTest(activeTouch.touch.pagePoint, ptLocal);
|
|
1620
|
+
if (currentTag == -1)
|
|
1621
|
+
return false;
|
|
1622
|
+
|
|
1623
|
+
auto fabricuiManager = ::Microsoft::ReactNative::FabricUIManager::FromProperties(m_context.Properties());
|
|
1624
|
+
if (!fabricuiManager)
|
|
1625
|
+
return false;
|
|
1626
|
+
|
|
1627
|
+
auto initialTag = initialComponentView.Tag();
|
|
1628
|
+
auto &viewRegistry = fabricuiManager->GetViewRegistry();
|
|
1629
|
+
auto currentView = viewRegistry.componentViewDescriptorWithTag(currentTag).view;
|
|
1630
|
+
while (currentView) {
|
|
1631
|
+
if (currentView.Tag() == initialTag)
|
|
1632
|
+
return true;
|
|
1633
|
+
currentView = currentView.Parent();
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1636
|
+
return false;
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
void CompositionEventHandler::DispatchSynthesizedTouchCancelForActiveTouch(
|
|
1640
|
+
const ActiveTouch &cancelledTouch,
|
|
1641
|
+
const winrt::Microsoft::ReactNative::Composition::Input::PointerPoint &pointerPoint,
|
|
1642
|
+
winrt::Windows::System::VirtualKeyModifiers keyModifiers) {
|
|
1643
|
+
if (!cancelledTouch.eventEmitter) {
|
|
1644
|
+
return;
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
facebook::react::PointerEvent pointerEvent =
|
|
1648
|
+
CreatePointerEventFromActiveTouch(cancelledTouch, TouchEventType::Cancel);
|
|
1649
|
+
winrt::Microsoft::ReactNative::ComponentView targetView{nullptr};
|
|
1650
|
+
facebook::react::SharedTouchEventEmitter emitter = cancelledTouch.eventEmitter;
|
|
1651
|
+
auto pointerHandler = [emitter, pointerEvent](std::vector<winrt::Microsoft::ReactNative::ComponentView> &) {
|
|
1652
|
+
emitter->onPointerCancel(pointerEvent);
|
|
1653
|
+
};
|
|
1654
|
+
HandleIncomingPointerEvent(pointerEvent, targetView, pointerPoint, keyModifiers, pointerHandler);
|
|
1655
|
+
|
|
1656
|
+
facebook::react::TouchEvent touchEvent;
|
|
1657
|
+
touchEvent.changedTouches.insert(cancelledTouch.touch);
|
|
1658
|
+
|
|
1659
|
+
for (const auto &pair : m_activeTouches) {
|
|
1660
|
+
if (!pair.second.eventEmitter) {
|
|
1661
|
+
continue;
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
if (touchEvent.changedTouches.find(pair.second.touch) != touchEvent.changedTouches.end()) {
|
|
1665
|
+
continue;
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1668
|
+
touchEvent.touches.insert(pair.second.touch);
|
|
1669
|
+
}
|
|
1670
|
+
|
|
1671
|
+
for (const auto &pair : m_activeTouches) {
|
|
1672
|
+
if (pair.second.eventEmitter == cancelledTouch.eventEmitter &&
|
|
1673
|
+
touchEvent.changedTouches.find(pair.second.touch) == touchEvent.changedTouches.end()) {
|
|
1674
|
+
touchEvent.targetTouches.insert(pair.second.touch);
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
1677
|
+
|
|
1678
|
+
cancelledTouch.eventEmitter->onTouchCancel(touchEvent);
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1467
1681
|
// If we have events that include multiple pointer updates, we should change arg from pointerId to vector<pointerId>
|
|
1468
1682
|
void CompositionEventHandler::DispatchTouchEvent(
|
|
1469
1683
|
TouchEventType eventType,
|
|
@@ -1480,7 +1694,15 @@ void CompositionEventHandler::DispatchTouchEvent(
|
|
|
1480
1694
|
|
|
1481
1695
|
facebook::react::TouchEvent event;
|
|
1482
1696
|
|
|
1483
|
-
|
|
1697
|
+
// First pass: build changedTouches and the set of unique emitters from every active
|
|
1698
|
+
// touch. The per-pointer PointerEvent dispatch (onPointerDown/Move/Up/Cancel/Click) is
|
|
1699
|
+
// fired only for the touch whose state actually changed — non-changed touches contribute
|
|
1700
|
+
// to the W3C TouchEvent's touches/targetTouches sets in the loops below but must not
|
|
1701
|
+
// re-fire pointer events of their own. Previously we dispatched the per-pointer event
|
|
1702
|
+
// for every entry in m_activeTouches, which produced duplicated onPointerMove on
|
|
1703
|
+
// non-moving fingers and replayed onPointerUp/onClick on stale targets after the OS
|
|
1704
|
+
// reclaimed a pointer (e.g. ScrollView manipulation redirect leaving a zombie touch).
|
|
1705
|
+
const ActiveTouch *changedTouch = nullptr;
|
|
1484
1706
|
for (const auto &pair : m_activeTouches) {
|
|
1485
1707
|
const auto &activeTouch = pair.second;
|
|
1486
1708
|
|
|
@@ -1488,42 +1710,55 @@ void CompositionEventHandler::DispatchTouchEvent(
|
|
|
1488
1710
|
continue;
|
|
1489
1711
|
}
|
|
1490
1712
|
|
|
1491
|
-
if (
|
|
1713
|
+
if (pair.first == pointerId) {
|
|
1714
|
+
changedTouch = &activeTouch;
|
|
1492
1715
|
event.changedTouches.insert(activeTouch.touch);
|
|
1493
1716
|
}
|
|
1494
1717
|
uniqueEventEmitters.insert(activeTouch.eventEmitter);
|
|
1718
|
+
}
|
|
1495
1719
|
|
|
1496
|
-
|
|
1720
|
+
if (changedTouch) {
|
|
1721
|
+
facebook::react::PointerEvent pointerEvent = CreatePointerEventFromActiveTouch(*changedTouch, eventType);
|
|
1497
1722
|
|
|
1498
1723
|
winrt::Microsoft::ReactNative::ComponentView targetView{nullptr};
|
|
1499
|
-
bool shouldLeave = (eventType == TouchEventType::End &&
|
|
1724
|
+
bool shouldLeave = (eventType == TouchEventType::End && changedTouch->shouldLeaveWhenReleased) ||
|
|
1500
1725
|
eventType == TouchEventType::Cancel;
|
|
1501
1726
|
if (!shouldLeave) {
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
auto
|
|
1507
|
-
|
|
1727
|
+
auto *rootViewForHit = RootComponentView();
|
|
1728
|
+
if (rootViewForHit) {
|
|
1729
|
+
const auto &viewRegistry = fabricuiManager->GetViewRegistry();
|
|
1730
|
+
facebook::react::Point ptLocal;
|
|
1731
|
+
auto targetTag = rootViewForHit->hitTest(pointerEvent.clientPoint, ptLocal);
|
|
1732
|
+
if (targetTag != -1) {
|
|
1733
|
+
auto targetComponentViewDescriptor = viewRegistry.componentViewDescriptorWithTag(targetTag);
|
|
1734
|
+
targetView = FindClosestFabricManagedTouchableView(targetComponentViewDescriptor.view);
|
|
1735
|
+
}
|
|
1508
1736
|
}
|
|
1509
1737
|
}
|
|
1510
1738
|
|
|
1511
|
-
auto handler = [
|
|
1739
|
+
auto handler = [this, changedTouch, eventType, &pointerEvent](
|
|
1512
1740
|
std::vector<winrt::Microsoft::ReactNative::ComponentView> &eventPathViews) {
|
|
1513
1741
|
switch (eventType) {
|
|
1514
1742
|
case TouchEventType::Start:
|
|
1515
|
-
|
|
1743
|
+
changedTouch->eventEmitter->onPointerDown(pointerEvent);
|
|
1516
1744
|
break;
|
|
1517
1745
|
case TouchEventType::Move: {
|
|
1518
|
-
|
|
1746
|
+
changedTouch->eventEmitter->onPointerMove(pointerEvent);
|
|
1519
1747
|
break;
|
|
1520
1748
|
}
|
|
1521
1749
|
case TouchEventType::End:
|
|
1522
|
-
|
|
1750
|
+
changedTouch->eventEmitter->onPointerUp(pointerEvent);
|
|
1751
|
+
if (pointerEvent.isPrimary && pointerEvent.button == 0) {
|
|
1752
|
+
if (IsPointerWithinInitialTree(*changedTouch)) {
|
|
1753
|
+
changedTouch->eventEmitter->onClick(pointerEvent);
|
|
1754
|
+
}
|
|
1755
|
+
} /* else if (IsPointerWithinInitialTree(*changedTouch)) {
|
|
1756
|
+
changedTouch->eventEmitter->onAuxClick(pointerEvent);
|
|
1757
|
+
} */
|
|
1523
1758
|
break;
|
|
1524
1759
|
case TouchEventType::Cancel:
|
|
1525
1760
|
case TouchEventType::CaptureLost:
|
|
1526
|
-
|
|
1761
|
+
changedTouch->eventEmitter->onPointerCancel(pointerEvent);
|
|
1527
1762
|
break;
|
|
1528
1763
|
}
|
|
1529
1764
|
};
|