react-native-windows 0.74.46 → 0.74.48
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/Directory.Build.props +1 -1
- package/Libraries/Components/View/View.windows.js +13 -5
- package/Libraries/Components/View/ViewAccessibility.d.ts +67 -0
- package/Libraries/Components/View/ViewPropTypes.windows.js +2 -0
- package/Libraries/NativeComponent/BaseViewConfig.windows.js +4 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionContextHelper.cpp +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +47 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +1 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +81 -94
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionTextProvider.cpp +115 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionTextProvider.h +41 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionTextRangeProvider.cpp +319 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionTextRangeProvider.h +59 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +48 -1
- package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +43 -34
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +2 -2
- package/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.cpp +11 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +152 -17
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +5 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputProps.cpp +2 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputProps.h +2 -1
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +43 -1
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +27 -2
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewEventEmitter.cpp +22 -4
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewEventEmitter.h +16 -3
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.cpp +24 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.h +4 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/MouseEvent.h +20 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.cpp +133 -32
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.h +12 -0
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +1 -3
- package/Microsoft.ReactNative/packages.lock.json +30 -106
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +1 -1
- package/Microsoft.ReactNative.Managed/packages.lock.json +3 -3
- package/Microsoft.ReactNative.Managed.CodeGen/Microsoft.ReactNative.Managed.CodeGen.csproj +1 -1
- package/Microsoft.ReactNative.Managed.CodeGen/Properties/PublishProfiles/DeployAsTool-Debug.pubxml +1 -1
- package/Microsoft.ReactNative.Managed.CodeGen/Properties/PublishProfiles/DeployAsTool-Release.pubxml +1 -1
- package/Microsoft.ReactNative.Managed.CodeGen/packages.lock.json +3 -3
- package/PropertySheets/External/Microsoft.ReactNative.WindowsSdk.Default.props +4 -4
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/PropertySheets/JSEngine.props +1 -1
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/test/testlib.cpp +4 -4
- package/ReactCommon/cgmanifest.json +1 -1
- package/Scripts/NuGetRestoreForceEvaluateAllSolutions.ps1 +26 -4
- package/Scripts/Tfs/Start-TestServers.ps1 +2 -1
- package/Scripts/rnw-dependencies.ps1 +38 -25
- package/Shared/Shared.vcxitems +6 -0
- package/Shared/Shared.vcxitems.filters +8 -0
- package/package.json +3 -3
- package/fmt/packages.lock.json +0 -13
package/Directory.Build.props
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
<FmtVersion>10.1.0</FmtVersion>
|
|
23
23
|
<FmtCommitHash>ca2e3685b160617d3d95fcd9e789c4e06ca88</FmtCommitHash>
|
|
24
24
|
<!-- Commit hash for https://github.com/microsoft/node-api-jsi code. -->
|
|
25
|
-
<NodeApiJsiCommitHash>
|
|
25
|
+
<NodeApiJsiCommitHash>21b47f08b762b21b1d4d970940ab23f59f43249c</NodeApiJsiCommitHash>
|
|
26
26
|
</PropertyGroup>
|
|
27
27
|
|
|
28
28
|
<!--
|
|
@@ -38,6 +38,7 @@ const View: React.AbstractComponent<
|
|
|
38
38
|
accessibilityLabel,
|
|
39
39
|
accessibilityLabelledBy,
|
|
40
40
|
accessibilityLevel, // Windows
|
|
41
|
+
accessibilityDescription, //Windows
|
|
41
42
|
accessibilityLiveRegion,
|
|
42
43
|
accessibilityPosInSet, // Windows
|
|
43
44
|
accessibilitySetSize, // Windows
|
|
@@ -49,6 +50,7 @@ const View: React.AbstractComponent<
|
|
|
49
50
|
'aria-expanded': ariaExpanded,
|
|
50
51
|
'aria-multiselectable': ariaMultiselectable, // Windows
|
|
51
52
|
'aria-required': ariaRequired, // Windows
|
|
53
|
+
'aria-description': ariaDescription, //Windows
|
|
52
54
|
'aria-hidden': ariaHidden,
|
|
53
55
|
'aria-label': ariaLabel,
|
|
54
56
|
'aria-labelledby': ariaLabelledBy,
|
|
@@ -227,6 +229,13 @@ const View: React.AbstractComponent<
|
|
|
227
229
|
|
|
228
230
|
// Windows]
|
|
229
231
|
|
|
232
|
+
const computedImportantForAccessibility =
|
|
233
|
+
ariaHidden === true ||
|
|
234
|
+
importantForAccessibility === 'no-hide-descendants' ||
|
|
235
|
+
accessibilityElementsHidden === true
|
|
236
|
+
? 'no-hide-descendants'
|
|
237
|
+
: importantForAccessibility;
|
|
238
|
+
|
|
230
239
|
return (
|
|
231
240
|
// [Windows
|
|
232
241
|
// In core this is a TextAncestor.Provider value={false} See
|
|
@@ -248,6 +257,9 @@ const View: React.AbstractComponent<
|
|
|
248
257
|
}
|
|
249
258
|
accessibilityLabel={ariaLabel ?? accessibilityLabel}
|
|
250
259
|
accessibilityLevel={ariaLevel ?? accessibilityLevel}
|
|
260
|
+
accessibilityDescription={
|
|
261
|
+
ariaDescription ?? accessibilityDescription
|
|
262
|
+
}
|
|
251
263
|
accessibilityPosInSet={ariaPosinset ?? accessibilityPosInSet}
|
|
252
264
|
accessibilitySetSize={ariaSetsize ?? accessibilitySetSize}
|
|
253
265
|
focusable={_focusable}
|
|
@@ -258,11 +270,7 @@ const View: React.AbstractComponent<
|
|
|
258
270
|
}
|
|
259
271
|
accessibilityLabelledBy={_accessibilityLabelledBy}
|
|
260
272
|
accessibilityValue={_accessibilityValue}
|
|
261
|
-
importantForAccessibility={
|
|
262
|
-
ariaHidden === true
|
|
263
|
-
? 'no-hide-descendants'
|
|
264
|
-
: importantForAccessibility
|
|
265
|
-
}
|
|
273
|
+
importantForAccessibility={computedImportantForAccessibility}
|
|
266
274
|
nativeID={id ?? nativeID}
|
|
267
275
|
style={style}
|
|
268
276
|
// $FlowFixMe[incompatible-type]
|
|
@@ -14,6 +14,7 @@ import {NativeSyntheticEvent} from '../../Types/CoreEventTypes';
|
|
|
14
14
|
*/
|
|
15
15
|
export interface AccessibilityProps
|
|
16
16
|
extends AccessibilityPropsAndroid,
|
|
17
|
+
AccessibilityPropsWindows,
|
|
17
18
|
AccessibilityPropsIOS {
|
|
18
19
|
/**
|
|
19
20
|
* When true, indicates that the view is an accessibility element.
|
|
@@ -258,6 +259,72 @@ export type AccessibilityRole =
|
|
|
258
259
|
| 'listitem' // Windows
|
|
259
260
|
| 'toolbar';
|
|
260
261
|
|
|
262
|
+
// [Windows]
|
|
263
|
+
export type AnnotationType =
|
|
264
|
+
| 'AdvanceProofingIssue'
|
|
265
|
+
| 'Author'
|
|
266
|
+
| 'CircularReferenceError'
|
|
267
|
+
| 'Comment'
|
|
268
|
+
| 'ConflictingChange'
|
|
269
|
+
| 'DataValidationError'
|
|
270
|
+
| 'DeletionChange'
|
|
271
|
+
| 'EditingLockedChange'
|
|
272
|
+
| 'Endnote'
|
|
273
|
+
| 'ExternalChange'
|
|
274
|
+
| 'Footer'
|
|
275
|
+
| 'Footnote'
|
|
276
|
+
| 'FormatChange'
|
|
277
|
+
| 'FormulaError'
|
|
278
|
+
| 'GrammarError'
|
|
279
|
+
| 'Header'
|
|
280
|
+
| 'Highlighted'
|
|
281
|
+
| 'InsertionChange'
|
|
282
|
+
| 'Mathematics'
|
|
283
|
+
| 'MoveChange'
|
|
284
|
+
| 'SpellingError'
|
|
285
|
+
| 'TrackChanges'
|
|
286
|
+
| 'Unknown'
|
|
287
|
+
| 'UnsyncedChange';
|
|
288
|
+
|
|
289
|
+
// [Windows]
|
|
290
|
+
export type AccessibilityAnnotationInfo = Readonly<{
|
|
291
|
+
typeID: AnnotationType;
|
|
292
|
+
typeName?: string;
|
|
293
|
+
author?: string;
|
|
294
|
+
dateTime?: string;
|
|
295
|
+
target?: string;
|
|
296
|
+
}>;
|
|
297
|
+
export interface AccessibilityPropsWindows {
|
|
298
|
+
/**
|
|
299
|
+
* Tells a person using a screen reader what kind of annotation they
|
|
300
|
+
* have selected. If available, it will also tell a person the author of the annotation and
|
|
301
|
+
* the date and time the annotation was posted.
|
|
302
|
+
*
|
|
303
|
+
* Note: If typeID is 'Unknown', a typeName must be provided.
|
|
304
|
+
*/
|
|
305
|
+
accessibilityAnnotation?: AccessibilityAnnotationInfo; //Windows
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Identifies the ItemType property, which is a text string describing the type of the automation element.
|
|
309
|
+
* ItemType is used to obtain information about items in a list, tree view, or data grid. For example, an item in a file directory view might be a "Document File" or a "Folder".
|
|
310
|
+
*/
|
|
311
|
+
accessibilityItemType?: string; //Windows
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* An access key to hook up to the UIA_AccessKey_Property.
|
|
315
|
+
* Access keys are used in keyboard navigation to allow quick navigation to UI in an application.
|
|
316
|
+
*/
|
|
317
|
+
accessibilityAccessKey?: string; //Windows
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* accessibilityDescription provides more detailed information specific to the element (i.e. last edit date, full location for a file)
|
|
321
|
+
* while accessibilityHint provides information on what will happen when they perform an action.
|
|
322
|
+
*
|
|
323
|
+
*/
|
|
324
|
+
accessibilityDescription?: string; // Windows
|
|
325
|
+
'aria-description'?: string; // Windows
|
|
326
|
+
}
|
|
327
|
+
|
|
261
328
|
export interface AccessibilityPropsAndroid {
|
|
262
329
|
/**
|
|
263
330
|
* Identifies the element that labels the element it is applied to. When the assistive technology focuses on the component with this props,
|
|
@@ -505,6 +505,8 @@ type WindowsViewProps = $ReadOnly<{|
|
|
|
505
505
|
'aria-posinset'?: ?number,
|
|
506
506
|
accessibilitySetSize?: ?number,
|
|
507
507
|
'aria-setsize'?: ?number,
|
|
508
|
+
accessibilityDescription?: ?string,
|
|
509
|
+
'aria-description'?: ?string,
|
|
508
510
|
|
|
509
511
|
/**
|
|
510
512
|
* Specifies if the control should show System focus visuals
|
|
@@ -359,6 +359,10 @@ const validAttributesForNonEventProps = {
|
|
|
359
359
|
accessibilityLiveRegion: true, // [Windows]
|
|
360
360
|
accessibilityPosInSet: true, // [Windows]
|
|
361
361
|
accessibilitySetSize: true, // [Windows]
|
|
362
|
+
accessibilityAnnotation: true, // [Windows]
|
|
363
|
+
accessibilityItemType: true, // [Windows]
|
|
364
|
+
accessibilityAccessKey: true, // [Windows]
|
|
365
|
+
accessibilityDescription: true, // [Windows]
|
|
362
366
|
disabled: true, // [Windows]
|
|
363
367
|
focusable: true, // [Windows]
|
|
364
368
|
keyDownEvents: true, // [Windows]
|
|
@@ -787,7 +787,7 @@ struct CompScrollerVisual : winrt::implements<
|
|
|
787
787
|
m_horizontal ? TTypeRedirects::InteractionSourceMode::Disabled
|
|
788
788
|
: TTypeRedirects::InteractionSourceMode::EnabledWithInertia);
|
|
789
789
|
m_visualInteractionSource.ManipulationRedirectionMode(
|
|
790
|
-
TTypeRedirects::VisualInteractionSourceRedirectionMode::
|
|
790
|
+
TTypeRedirects::VisualInteractionSourceRedirectionMode::CapableTouchpadOnly);
|
|
791
791
|
} else {
|
|
792
792
|
m_visualInteractionSource.PositionXSourceMode(TTypeRedirects::InteractionSourceMode::Disabled);
|
|
793
793
|
m_visualInteractionSource.PositionYSourceMode(TTypeRedirects::InteractionSourceMode::Disabled);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
#include "pch.h"
|
|
2
2
|
#include "CompositionDynamicAutomationProvider.h"
|
|
3
3
|
#include <Fabric/ComponentView.h>
|
|
4
|
+
#include <Fabric/Composition/CompositionTextRangeProvider.h>
|
|
5
|
+
#include <Fabric/Composition/ParagraphComponentView.h>
|
|
4
6
|
#include <Fabric/Composition/SwitchComponentView.h>
|
|
5
7
|
#include <Fabric/Composition/TextInput/WindowsTextInputComponentView.h>
|
|
6
8
|
#include <Unicode.h>
|
|
@@ -26,6 +28,13 @@ CompositionDynamicAutomationProvider::CompositionDynamicAutomationProvider(
|
|
|
26
28
|
if (props->accessibilityState.has_value() && props->accessibilityState->selected.has_value()) {
|
|
27
29
|
AddSelectionItemsToContainer(this);
|
|
28
30
|
}
|
|
31
|
+
|
|
32
|
+
if (strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::WindowsTextInputComponentView>() ||
|
|
33
|
+
strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ParagraphComponentView>()) {
|
|
34
|
+
m_textProvider = winrt::make<CompositionTextProvider>(
|
|
35
|
+
strongView.as<winrt::Microsoft::ReactNative::Composition::ComponentView>(), this)
|
|
36
|
+
.try_as<ITextProvider2>();
|
|
37
|
+
}
|
|
29
38
|
}
|
|
30
39
|
|
|
31
40
|
CompositionDynamicAutomationProvider::CompositionDynamicAutomationProvider(
|
|
@@ -253,6 +262,17 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPatternProvider(PATTE
|
|
|
253
262
|
AddRef();
|
|
254
263
|
}
|
|
255
264
|
|
|
265
|
+
if (patternId == UIA_TextPatternId &&
|
|
266
|
+
(strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::WindowsTextInputComponentView>() ||
|
|
267
|
+
strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ParagraphComponentView>())) {
|
|
268
|
+
m_textProvider.as<IUnknown>().copy_to(pRetVal);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (patternId == UIA_TextPattern2Id &&
|
|
272
|
+
strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::WindowsTextInputComponentView>()) {
|
|
273
|
+
m_textProvider.as<IUnknown>().copy_to(pRetVal);
|
|
274
|
+
}
|
|
275
|
+
|
|
256
276
|
return S_OK;
|
|
257
277
|
}
|
|
258
278
|
|
|
@@ -527,6 +547,29 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPropertyValue(PROPERT
|
|
|
527
547
|
: SysAllocString(L"");
|
|
528
548
|
break;
|
|
529
549
|
}
|
|
550
|
+
case UIA_LevelPropertyId: {
|
|
551
|
+
pRetVal->vt = VT_I4;
|
|
552
|
+
pRetVal->lVal = props->accessibilityLevel;
|
|
553
|
+
break;
|
|
554
|
+
}
|
|
555
|
+
case UIA_AccessKeyPropertyId: {
|
|
556
|
+
pRetVal->vt = VT_BSTR;
|
|
557
|
+
auto accessKey = ::Microsoft::Common::Unicode::Utf8ToUtf16(props->accessibilityAccessKey.value_or(""));
|
|
558
|
+
pRetVal->bstrVal = SysAllocString(accessKey.c_str());
|
|
559
|
+
break;
|
|
560
|
+
}
|
|
561
|
+
case UIA_ItemTypePropertyId: {
|
|
562
|
+
pRetVal->vt = VT_BSTR;
|
|
563
|
+
auto itemtype = ::Microsoft::Common::Unicode::Utf8ToUtf16(props->accessibilityItemType.value_or(""));
|
|
564
|
+
pRetVal->bstrVal = SysAllocString(itemtype.c_str());
|
|
565
|
+
break;
|
|
566
|
+
}
|
|
567
|
+
case UIA_FullDescriptionPropertyId: {
|
|
568
|
+
pRetVal->vt = VT_BSTR;
|
|
569
|
+
auto desc = ::Microsoft::Common::Unicode::Utf8ToUtf16(props->accessibilityDescription.value_or(""));
|
|
570
|
+
pRetVal->bstrVal = SysAllocString(desc.c_str());
|
|
571
|
+
break;
|
|
572
|
+
}
|
|
530
573
|
}
|
|
531
574
|
|
|
532
575
|
return hr;
|
|
@@ -769,7 +812,9 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::Expand() {
|
|
|
769
812
|
|
|
770
813
|
if (!strongView)
|
|
771
814
|
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
815
|
+
|
|
772
816
|
DispatchAccessibilityAction(m_view, "expand");
|
|
817
|
+
|
|
773
818
|
return S_OK;
|
|
774
819
|
}
|
|
775
820
|
|
|
@@ -778,7 +823,9 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::Collapse() {
|
|
|
778
823
|
|
|
779
824
|
if (!strongView)
|
|
780
825
|
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
826
|
+
|
|
781
827
|
DispatchAccessibilityAction(m_view, "collapse");
|
|
828
|
+
|
|
782
829
|
return S_OK;
|
|
783
830
|
}
|
|
784
831
|
|
|
@@ -89,6 +89,7 @@ class CompositionDynamicAutomationProvider : public winrt::implements<
|
|
|
89
89
|
|
|
90
90
|
private:
|
|
91
91
|
::Microsoft::ReactNative::ReactTaggedView m_view;
|
|
92
|
+
winrt::com_ptr<ITextProvider2> m_textProvider;
|
|
92
93
|
std::vector<winrt::com_ptr<IRawElementProviderSimple>> m_selectionItems;
|
|
93
94
|
// Non-null when this UIA node is the peer of a ContentIslandComponentView.
|
|
94
95
|
winrt::Microsoft::UI::Content::ChildSiteLink m_childSiteLink{nullptr};
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
#include <IReactContext.h>
|
|
10
10
|
#include <React.h>
|
|
11
11
|
#include <Views/DevMenu.h>
|
|
12
|
-
#include <Views/ShadowNodeBase.h>
|
|
13
12
|
#include <windows.h>
|
|
14
13
|
#include <windowsx.h>
|
|
15
14
|
#include <winrt/Windows.UI.Core.h>
|
|
@@ -637,17 +636,6 @@ void CompositionEventHandler::HandleIncomingPointerEvent(
|
|
|
637
636
|
|
|
638
637
|
auto eventPathViews = GetTouchableViewsInPathToRoot(targetView);
|
|
639
638
|
|
|
640
|
-
// Over
|
|
641
|
-
if (targetView != nullptr && previousTargetTag != targetView.Tag()) {
|
|
642
|
-
bool shouldEmitOverEvent =
|
|
643
|
-
IsAnyViewInPathListeningToEvent(eventPathViews, facebook::react::ViewEvents::Offset::PointerOver);
|
|
644
|
-
const auto eventEmitter = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(targetView)
|
|
645
|
-
->eventEmitterAtPoint(event.offsetPoint);
|
|
646
|
-
if (shouldEmitOverEvent && eventEmitter != nullptr) {
|
|
647
|
-
eventEmitter->onPointerOver(event);
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
|
|
651
639
|
// Entering
|
|
652
640
|
|
|
653
641
|
// We only want to emit events to JS if there is a view that is currently listening to said event
|
|
@@ -664,7 +652,6 @@ void CompositionEventHandler::HandleIncomingPointerEvent(
|
|
|
664
652
|
auto componentView = *itComponentView;
|
|
665
653
|
bool shouldEmitEvent = componentView != nullptr &&
|
|
666
654
|
(hasParentEnterListener ||
|
|
667
|
-
IsViewListeningToEvent(componentView, facebook::react::ViewEvents::Offset::PointerEnter) ||
|
|
668
655
|
IsViewListeningToEvent(componentView, facebook::react::WindowsViewEvents::Offset::MouseEnter));
|
|
669
656
|
|
|
670
657
|
if (std::find(currentlyHoveredViews.begin(), currentlyHoveredViews.end(), componentView) ==
|
|
@@ -674,16 +661,12 @@ void CompositionEventHandler::HandleIncomingPointerEvent(
|
|
|
674
661
|
m_context, componentView.Tag(), pointerPoint, keyModifiers);
|
|
675
662
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(componentView)
|
|
676
663
|
->OnPointerEntered(args);
|
|
677
|
-
|
|
678
664
|
if (shouldEmitEvent) {
|
|
679
665
|
const auto eventEmitter =
|
|
680
666
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(componentView)
|
|
681
667
|
->eventEmitter();
|
|
682
|
-
if (eventEmitter) {
|
|
683
|
-
eventEmitter->
|
|
684
|
-
if (IsMousePointerEvent(event)) {
|
|
685
|
-
eventEmitter->onMouseEnter(event);
|
|
686
|
-
}
|
|
668
|
+
if (eventEmitter && IsMousePointerEvent(event)) {
|
|
669
|
+
eventEmitter->onMouseEnter(event);
|
|
687
670
|
}
|
|
688
671
|
}
|
|
689
672
|
}
|
|
@@ -696,26 +679,13 @@ void CompositionEventHandler::HandleIncomingPointerEvent(
|
|
|
696
679
|
// Call the underlaying pointer handler
|
|
697
680
|
handler(eventPathViews);
|
|
698
681
|
|
|
699
|
-
// Out
|
|
700
|
-
if (previousTargetTag != -1 && previousTargetTag != (targetView ? targetView.Tag() : -1)) {
|
|
701
|
-
bool shouldEmitOutEvent =
|
|
702
|
-
IsAnyViewInPathListeningToEvent(currentlyHoveredViews, facebook::react::ViewEvents::Offset::PointerOut);
|
|
703
|
-
const auto eventEmitter =
|
|
704
|
-
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(prevTargetView)->eventEmitter();
|
|
705
|
-
if (shouldEmitOutEvent && eventEmitter != nullptr) {
|
|
706
|
-
eventEmitter->onPointerOut(event);
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
|
|
710
682
|
// Leaving
|
|
711
683
|
|
|
712
684
|
// pointerleave events need to be emitted from the deepest target to the root but
|
|
713
685
|
// we also need to efficiently keep track of if a view has a parent which is listening to the leave events,
|
|
714
686
|
// so we first iterate from the root to the target, collecting the views which need events fired for, of which
|
|
715
687
|
// we reverse iterate (now from target to root), actually emitting the events.
|
|
716
|
-
std::vector<winrt::Microsoft::ReactNative::ComponentView>
|
|
717
|
-
viewsToEmitJSLeaveEventsTo; // NSMutableOrderedSet<UIView *> *viewsToEmitLeaveEventsTo =
|
|
718
|
-
// [NSMutableOrderedSet orderedSet];
|
|
688
|
+
std::vector<winrt::Microsoft::ReactNative::ComponentView> viewsToEmitJSLeaveEventsTo;
|
|
719
689
|
|
|
720
690
|
std::vector<winrt::Microsoft::ReactNative::ComponentView> viewsToEmitLeaveEventsTo;
|
|
721
691
|
|
|
@@ -723,14 +693,11 @@ void CompositionEventHandler::HandleIncomingPointerEvent(
|
|
|
723
693
|
|
|
724
694
|
bool hasParentLeaveListener = false;
|
|
725
695
|
for (auto itComponentView = currentlyHoveredViews.rbegin(); itComponentView != currentlyHoveredViews.rend();
|
|
726
|
-
itComponentView++) {
|
|
727
|
-
// reverseObjectEnumerator])
|
|
728
|
-
// {
|
|
696
|
+
itComponentView++) {
|
|
729
697
|
auto componentView = *itComponentView;
|
|
730
698
|
|
|
731
699
|
bool shouldEmitJSEvent = componentView != nullptr &&
|
|
732
700
|
(hasParentLeaveListener ||
|
|
733
|
-
IsViewListeningToEvent(componentView, facebook::react::ViewEvents::Offset::PointerLeave) ||
|
|
734
701
|
IsViewListeningToEvent(componentView, facebook::react::WindowsViewEvents::Offset::MouseLeave));
|
|
735
702
|
|
|
736
703
|
if (std::find(eventPathViews.begin(), eventPathViews.end(), componentView) == eventPathViews.end()) {
|
|
@@ -755,17 +722,13 @@ void CompositionEventHandler::HandleIncomingPointerEvent(
|
|
|
755
722
|
}
|
|
756
723
|
|
|
757
724
|
for (auto itComponentView = viewsToEmitJSLeaveEventsTo.rbegin(); itComponentView != viewsToEmitJSLeaveEventsTo.rend();
|
|
758
|
-
itComponentView++) {
|
|
759
|
-
// reverseObjectEnumerator]) {
|
|
725
|
+
itComponentView++) {
|
|
760
726
|
auto componentView = *itComponentView;
|
|
761
727
|
|
|
762
728
|
const auto eventEmitter =
|
|
763
729
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(componentView)->eventEmitter();
|
|
764
|
-
if (eventEmitter) {
|
|
765
|
-
eventEmitter->
|
|
766
|
-
if (IsMousePointerEvent(event)) {
|
|
767
|
-
eventEmitter->onMouseLeave(event);
|
|
768
|
-
}
|
|
730
|
+
if (eventEmitter && IsMousePointerEvent(event)) {
|
|
731
|
+
eventEmitter->onMouseLeave(event);
|
|
769
732
|
}
|
|
770
733
|
}
|
|
771
734
|
|
|
@@ -815,41 +778,41 @@ void CompositionEventHandler::SetCursor(facebook::react::Cursor cursor, HCURSOR
|
|
|
815
778
|
case facebook::react::Cursor::Pointer:
|
|
816
779
|
type = winrt::Windows::UI::Core::CoreCursorType::Hand;
|
|
817
780
|
break;
|
|
818
|
-
/*
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
781
|
+
/*
|
|
782
|
+
case facebook::react::Cursor::Help:
|
|
783
|
+
type = winrt::Windows::UI::Core::CoreCursorType::Help;
|
|
784
|
+
break;
|
|
785
|
+
case facebook::react::Cursor::NotAllowed:
|
|
786
|
+
type = winrt::Windows::UI::Core::CoreCursorType::UniversalNo;
|
|
787
|
+
break;
|
|
788
|
+
case facebook::react::Cursor::Wait:
|
|
789
|
+
type = winrt::Windows::UI::Core::CoreCursorType::Wait;
|
|
790
|
+
break;
|
|
791
|
+
case facebook::react::Cursor::Move:
|
|
792
|
+
type = winrt::Windows::UI::Core::CoreCursorType::SizeAll;
|
|
793
|
+
break;
|
|
794
|
+
case facebook::react::Cursor::NESWResize:
|
|
795
|
+
type = winrt::Windows::UI::Core::CoreCursorType::SizeNortheastSouthwest;
|
|
796
|
+
break;
|
|
797
|
+
case facebook::react::Cursor::NSResize:
|
|
798
|
+
type = winrt::Windows::UI::Core::CoreCursorType::SizeNorthSouth;
|
|
799
|
+
break;
|
|
800
|
+
case facebook::react::Cursor::NWSEResize:
|
|
801
|
+
type = winrt::Windows::UI::Core::CoreCursorType::SizeNorthwestSoutheast;
|
|
802
|
+
break;
|
|
803
|
+
case facebook::react::Cursor::EWResize:
|
|
804
|
+
type = winrt::Windows::UI::Core::CoreCursorType::SizeWestEast;
|
|
805
|
+
break;
|
|
806
|
+
case facebook::react::Cursor::Text:
|
|
807
|
+
type = winrt::Windows::UI::Core::CoreCursorType::IBeam;
|
|
808
|
+
break;
|
|
809
|
+
case facebook::react::Cursor::Progress:
|
|
810
|
+
type = winrt::Windows::UI::Core::CoreCursorType::Wait; // IDC_APPSTARTING not mapped to CoreCursor?
|
|
811
|
+
break;
|
|
812
|
+
case facebook::react::Cursor::Crosshair:
|
|
813
|
+
type = winrt::Windows::UI::Core::CoreCursorType::Cross;
|
|
814
|
+
break;
|
|
815
|
+
*/
|
|
853
816
|
default:
|
|
854
817
|
break;
|
|
855
818
|
}
|
|
@@ -880,7 +843,7 @@ void CompositionEventHandler::SetCursor(facebook::react::Cursor cursor, HCURSOR
|
|
|
880
843
|
case facebook::react::Cursor::Pointer:
|
|
881
844
|
idc = IDC_HAND;
|
|
882
845
|
break;
|
|
883
|
-
/*
|
|
846
|
+
/*
|
|
884
847
|
case facebook::react::Cursor::Help:
|
|
885
848
|
idc = IDC_HELP;
|
|
886
849
|
break;
|
|
@@ -1064,21 +1027,48 @@ void CompositionEventHandler::onPointerMoved(
|
|
|
1064
1027
|
|
|
1065
1028
|
facebook::react::PointerEvent pointerEvent = CreatePointerEventFromIncompleteHoverData(ptScaled, ptLocal);
|
|
1066
1029
|
|
|
1067
|
-
|
|
1068
|
-
|
|
1030
|
+
// check if this pointer corresponds to active touch that has a responder
|
|
1031
|
+
auto activeTouch = m_activeTouches.find(pointerId);
|
|
1032
|
+
bool isActiveTouch = activeTouch != m_activeTouches.end() && activeTouch->second.eventEmitter != nullptr;
|
|
1033
|
+
|
|
1034
|
+
auto handler = [&, targetView, pointerEvent, isActiveTouch](
|
|
1035
|
+
std::vector<winrt::Microsoft::ReactNative::ComponentView> &eventPathViews) {
|
|
1069
1036
|
const auto eventEmitter = targetView
|
|
1070
1037
|
? winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(targetView)
|
|
1071
1038
|
->eventEmitterAtPoint(pointerEvent.offsetPoint)
|
|
1072
|
-
:
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
IsAnyViewInPathListeningToEvent(eventPathViews, facebook::react::ViewEvents::Offset::PointerMoveCapture);
|
|
1076
|
-
if (eventEmitter != nullptr && hasMoveEventListeners) {
|
|
1039
|
+
: RootComponentView().eventEmitterAtPoint(pointerEvent.offsetPoint);
|
|
1040
|
+
|
|
1041
|
+
if (eventEmitter != nullptr) {
|
|
1077
1042
|
eventEmitter->onPointerMove(pointerEvent);
|
|
1043
|
+
} else {
|
|
1044
|
+
ClearAllHoveredForPointer(pointerEvent);
|
|
1078
1045
|
}
|
|
1079
1046
|
};
|
|
1080
1047
|
|
|
1081
1048
|
HandleIncomingPointerEvent(pointerEvent, targetView, pointerPoint, keyModifiers, handler);
|
|
1049
|
+
|
|
1050
|
+
if (isActiveTouch) {
|
|
1051
|
+
// For active touches with responders, also dispatch through touch event system
|
|
1052
|
+
UpdateActiveTouch(activeTouch->second, ptScaled, ptLocal);
|
|
1053
|
+
DispatchTouchEvent(TouchEventType::Move, pointerId, pointerPoint, keyModifiers);
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
void CompositionEventHandler::ClearAllHoveredForPointer(const facebook::react::PointerEvent &pointerEvent) noexcept {
|
|
1059
|
+
// special case if we have no target
|
|
1060
|
+
// PointerEventsProcessor requires move events to keep track of the hovered components in core.
|
|
1061
|
+
// It also treats a onPointerLeave event as a special case that removes the hover state of all currently hovered
|
|
1062
|
+
// events. If we get null for the targetView, that means that the mouse is no over any components, so we have no
|
|
1063
|
+
// element to send the move event to. However we need to send something so that any previously hovered elements
|
|
1064
|
+
// are no longer hovered.
|
|
1065
|
+
auto children = RootComponentView().Children();
|
|
1066
|
+
if (auto size = children.Size()) {
|
|
1067
|
+
auto firstChild = children.GetAt(0);
|
|
1068
|
+
if (auto childEventEmitter =
|
|
1069
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(firstChild)->eventEmitter()) {
|
|
1070
|
+
childEventEmitter->onPointerLeave(pointerEvent);
|
|
1071
|
+
}
|
|
1082
1072
|
}
|
|
1083
1073
|
}
|
|
1084
1074
|
|
|
@@ -1104,7 +1094,9 @@ void CompositionEventHandler::onPointerExited(
|
|
|
1104
1094
|
|
|
1105
1095
|
facebook::react::PointerEvent pointerEvent = CreatePointerEventFromIncompleteHoverData(ptScaled, ptLocal);
|
|
1106
1096
|
|
|
1107
|
-
auto handler = [](std::vector<winrt::Microsoft::ReactNative::ComponentView> &eventPathViews) {
|
|
1097
|
+
auto handler = [&](std::vector<winrt::Microsoft::ReactNative::ComponentView> &eventPathViews) {
|
|
1098
|
+
ClearAllHoveredForPointer(pointerEvent);
|
|
1099
|
+
};
|
|
1108
1100
|
|
|
1109
1101
|
HandleIncomingPointerEvent(pointerEvent, nullptr, pointerPoint, keyModifiers, handler);
|
|
1110
1102
|
}
|
|
@@ -1392,12 +1384,7 @@ void CompositionEventHandler::DispatchTouchEvent(
|
|
|
1392
1384
|
activeTouch.eventEmitter->onPointerDown(pointerEvent);
|
|
1393
1385
|
break;
|
|
1394
1386
|
case TouchEventType::Move: {
|
|
1395
|
-
|
|
1396
|
-
IsAnyViewInPathListeningToEvent(eventPathViews, facebook::react::ViewEvents::Offset::PointerMove) ||
|
|
1397
|
-
IsAnyViewInPathListeningToEvent(eventPathViews, facebook::react::ViewEvents::Offset::PointerMoveCapture);
|
|
1398
|
-
if (hasMoveEventListeners) {
|
|
1399
|
-
activeTouch.eventEmitter->onPointerMove(pointerEvent);
|
|
1400
|
-
}
|
|
1387
|
+
activeTouch.eventEmitter->onPointerMove(pointerEvent);
|
|
1401
1388
|
break;
|
|
1402
1389
|
}
|
|
1403
1390
|
case TouchEventType::End:
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
#include <winrt/Windows.Devices.Input.h>
|
|
15
15
|
#include <optional>
|
|
16
16
|
#include <set>
|
|
17
|
-
#include "Utils/BatchingEventEmitter.h"
|
|
18
17
|
|
|
19
18
|
namespace winrt {
|
|
20
19
|
using namespace Windows::UI;
|
|
@@ -99,6 +98,7 @@ class CompositionEventHandler : public std::enable_shared_from_this<CompositionE
|
|
|
99
98
|
const winrt::Microsoft::ReactNative::Composition::Input::PointerPoint &pointerPoint,
|
|
100
99
|
winrt::Windows::System::VirtualKeyModifiers keyModifiers,
|
|
101
100
|
std::function<void(std::vector<winrt::Microsoft::ReactNative::ComponentView> &)> handler);
|
|
101
|
+
void ClearAllHoveredForPointer(const facebook::react::PointerEvent &pointerEvent) noexcept;
|
|
102
102
|
|
|
103
103
|
struct ActiveTouch {
|
|
104
104
|
facebook::react::Touch touch;
|