react-native-windows 0.78.5 → 0.78.7
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 +6 -4
- package/Folly/Folly.vcxproj +46 -6
- package/Folly/Folly.vcxproj.filters +16 -4
- package/Folly/TEMP_UntilFollyUpdate/ConstexprMath.h +26 -18
- package/Folly/TEMP_UntilFollyUpdate/Conv.cpp +1205 -0
- package/Folly/TEMP_UntilFollyUpdate/chrono/Hardware.h +155 -0
- package/Folly/TEMP_UntilFollyUpdate/concurrency/CacheLocality.cpp +633 -0
- package/Folly/TEMP_UntilFollyUpdate/{dynamic-inl.h → json/dynamic-inl.h} +3 -4
- package/Folly/TEMP_UntilFollyUpdate/{json.cpp → json/json.cpp} +14 -10
- package/Folly/TEMP_UntilFollyUpdate/lang/SafeAssert.h +7 -14
- package/Folly/TEMP_UntilFollyUpdate/lang/ToAscii.h +6 -6
- package/Folly/ThreadNameStub.cpp +10 -0
- package/Folly/cgmanifest.json +11 -1
- package/Libraries/Components/View/View.windows.js +107 -56
- package/Libraries/Components/View/ViewAccessibility.d.ts +60 -1
- package/Libraries/Image/Image.windows.js +42 -21
- package/Libraries/Modal/Modal.d.ts +7 -0
- package/Libraries/Modal/Modal.windows.js +7 -1
- package/Libraries/NativeComponent/BaseViewConfig.windows.js +3 -0
- package/Libraries/Text/Text.d.ts +18 -0
- package/Microsoft.ReactNative/AsynchronousEventBeat.cpp +4 -25
- package/Microsoft.ReactNative/AsynchronousEventBeat.h +0 -3
- package/Microsoft.ReactNative/Base/FollyIncludes.h +1 -0
- package/Microsoft.ReactNative/CallInvoker.cpp +42 -0
- package/Microsoft.ReactNative/CallInvoker.h +34 -0
- package/Microsoft.ReactNative/{JSDispatcherWriter.cpp → CallInvokerWriter.cpp} +35 -47
- package/Microsoft.ReactNative/CallInvokerWriter.h +74 -0
- package/Microsoft.ReactNative/CompositionComponentView.idl +0 -5
- package/Microsoft.ReactNative/CompositionSwitcher.idl +7 -0
- package/Microsoft.ReactNative/Fabric/AbiViewProps.cpp +8 -10
- package/Microsoft.ReactNative/Fabric/ComponentView.cpp +4 -1
- package/Microsoft.ReactNative/Fabric/Composition/ActivityIndicatorComponentView.cpp +12 -2
- package/Microsoft.ReactNative/Fabric/Composition/ActivityIndicatorComponentView.h +2 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionAnnotationProvider.cpp +100 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionAnnotationProvider.h +31 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionContextHelper.cpp +77 -11
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +43 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +7 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +86 -56
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +5 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +0 -4
- package/Microsoft.ReactNative/Fabric/Composition/CompositionUIService.cpp +0 -2
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +118 -63
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +2 -0
- package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp +133 -8
- package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.h +16 -2
- package/Microsoft.ReactNative/Fabric/Composition/FocusManager.cpp +4 -2
- package/Microsoft.ReactNative/Fabric/Composition/FocusManager.h +9 -1
- package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp +34 -11
- package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h +3 -0
- package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +133 -135
- package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +9 -6
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +46 -49
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +6 -1
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +13 -8
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +5 -2
- package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +146 -25
- package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h +14 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +160 -12
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +6 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputEventEmitter.cpp +47 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputEventEmitter.h +15 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputProps.cpp +6 -2
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputProps.h +4 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.cpp +7 -9
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.h +4 -1
- package/Microsoft.ReactNative/Fabric/Composition/Theme.cpp +5 -0
- package/Microsoft.ReactNative/Fabric/Composition/TooltipService.cpp +40 -36
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +68 -0
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +11 -0
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +70 -13
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.h +10 -2
- package/Microsoft.ReactNative/Fabric/ImageManager.cpp +5 -5
- package/Microsoft.ReactNative/Fabric/ImageRequestParams.cpp +26 -0
- package/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp +47 -8
- package/Microsoft.ReactNative/Fabric/WindowsImageManager.h +10 -1
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/CompositionAccessibilityProps.h +67 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewEventEmitter.cpp +22 -4
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewEventEmitter.h +15 -2
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.cpp +20 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.h +5 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/MouseEvent.h +20 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/HostPlatformColor.h +5 -8
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/PlatformColorParser.h +1 -2
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.cpp +247 -45
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.h +15 -0
- package/Microsoft.ReactNative/Fabric/platform/react/threading/MessageQueueThreadImpl.cpp +39 -0
- package/Microsoft.ReactNative/Fabric/platform/react/threading/MessageQueueThreadImpl.h +54 -0
- package/Microsoft.ReactNative/Fabric/platform/react/threading/TaskDispatchThread.cpp +126 -0
- package/Microsoft.ReactNative/Fabric/platform/react/threading/TaskDispatchThread.h +73 -0
- package/Microsoft.ReactNative/IReactContext.cpp +17 -0
- package/Microsoft.ReactNative/IReactContext.h +1 -0
- package/Microsoft.ReactNative/IReactContext.idl +18 -1
- package/Microsoft.ReactNative/IReactDispatcher.idl +1 -0
- package/Microsoft.ReactNative/IReactModuleBuilder.cpp +12 -0
- package/Microsoft.ReactNative/IReactModuleBuilder.h +2 -0
- package/Microsoft.ReactNative/IReactModuleBuilder.idl +8 -0
- package/Microsoft.ReactNative/JsiApi.cpp +10 -2
- package/Microsoft.ReactNative/JsiApi.h +1 -0
- package/Microsoft.ReactNative/JsiApi.idl +1 -0
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +0 -3
- package/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp +2 -3
- package/Microsoft.ReactNative/Modules/AlertModule.cpp +7 -12
- package/Microsoft.ReactNative/Modules/Animated/AnimationDriver.cpp +2 -1
- package/Microsoft.ReactNative/Modules/Animated/NativeAnimatedModule.cpp +4 -8
- package/Microsoft.ReactNative/Modules/AppStateModule.cpp +2 -2
- package/Microsoft.ReactNative/Modules/ClipboardModule.cpp +6 -8
- package/Microsoft.ReactNative/Modules/ClipboardModule.h +1 -1
- package/Microsoft.ReactNative/Modules/ImageViewManagerModule.cpp +6 -15
- package/Microsoft.ReactNative/Modules/NativeUIManager.cpp +13 -24
- package/Microsoft.ReactNative/QuirkSettings.cpp +0 -16
- package/Microsoft.ReactNative/QuirkSettings.h +0 -3
- package/Microsoft.ReactNative/ReactHost/ReactHost.cpp +11 -1
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +78 -68
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +1 -2
- package/Microsoft.ReactNative/ReactInstanceSettings.cpp +12 -0
- package/Microsoft.ReactNative/ReactInstanceSettings.h +2 -0
- package/Microsoft.ReactNative/ReactInstanceSettings.idl +6 -0
- package/Microsoft.ReactNative/ReactNativeIsland.idl +3 -0
- package/Microsoft.ReactNative/ReactSupport.cpp +44 -11
- package/Microsoft.ReactNative/RedBox.cpp +30 -1
- package/Microsoft.ReactNative/SchedulerSettings.cpp +4 -4
- package/Microsoft.ReactNative/SchedulerSettings.h +1 -1
- package/Microsoft.ReactNative/TurboModulesProvider.cpp +30 -12
- package/Microsoft.ReactNative/Utils/ImageUtils.h +1 -0
- package/Microsoft.ReactNative/Utils/LocalBundleReader.cpp +37 -31
- package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.cpp +1 -0
- package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.inc +2 -0
- package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi_posix.cpp +1 -1
- package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp +94 -27
- package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h +27 -6
- package/Microsoft.ReactNative.Cxx/JSI/JsiApiContext.cpp +45 -11
- package/Microsoft.ReactNative.Cxx/JSI/JsiApiContext.h +6 -0
- package/Microsoft.ReactNative.Cxx/JSI/decorator.h +220 -0
- package/Microsoft.ReactNative.Cxx/JSI/instrumentation.h +28 -0
- package/Microsoft.ReactNative.Cxx/JSI/jsi-inl.h +6 -0
- package/Microsoft.ReactNative.Cxx/JSI/jsi.cpp +241 -4
- package/Microsoft.ReactNative.Cxx/JSI/jsi.h +207 -19
- package/Microsoft.ReactNative.Cxx/JSValue.cpp +19 -3
- package/Microsoft.ReactNative.Cxx/JSValue.h +15 -7
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +2 -2
- package/Microsoft.ReactNative.Cxx/NativeModules.h +60 -2
- package/Microsoft.ReactNative.Cxx/NodeApiJsiRuntime.cpp +1267 -614
- package/Microsoft.ReactNative.Cxx/NodeApiJsiRuntime.h +4 -2
- package/Microsoft.ReactNative.Cxx/ReactContext.h +7 -0
- package/Microsoft.ReactNative.Cxx/TurboModuleProvider.cpp +11 -13
- package/Microsoft.ReactNative.Cxx/TurboModuleProvider.h +2 -3
- package/Microsoft.ReactNative.Cxx/node-api/js_native_api.h +81 -20
- package/Microsoft.ReactNative.Cxx/node-api/js_native_api_types.h +47 -2
- package/Microsoft.ReactNative.Cxx/node-api/js_runtime_api.h +13 -0
- package/Microsoft.ReactNative.Cxx/stubs/glog/logging.h +1 -1
- package/Microsoft.ReactNative.Managed/ReactContext.cs +3 -1
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/PropertySheets/JSEngine.props +1 -1
- package/PropertySheets/React.Cpp.props +2 -1
- package/PropertySheets/WebView2.props +1 -1
- package/PropertySheets/WinUI.props +2 -2
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jserrorhandler/JsErrorHandler.cpp +429 -0
- package/ReactCommon/cgmanifest.json +1 -1
- package/Shared/HermesRuntimeHolder.cpp +6 -0
- package/Shared/JSI/ChakraRuntime.cpp +4 -0
- package/Shared/JSI/ChakraRuntime.h +2 -0
- package/Shared/Modules/BlobModule.cpp +14 -16
- package/Shared/Modules/BlobModule.h +3 -1
- package/Shared/Shared.vcxitems +11 -7
- package/Shared/Shared.vcxitems.filters +6 -1
- package/Shared/TurboModuleManager.cpp +0 -15
- package/codegen/react/components/rnwcore/ActivityIndicatorView.g.h +6 -6
- package/codegen/react/components/rnwcore/AndroidDrawerLayout.g.h +6 -6
- package/codegen/react/components/rnwcore/AndroidHorizontalScrollContentView.g.h +6 -6
- package/codegen/react/components/rnwcore/AndroidProgressBar.g.h +6 -6
- package/codegen/react/components/rnwcore/AndroidSwipeRefreshLayout.g.h +6 -6
- package/codegen/react/components/rnwcore/AndroidSwitch.g.h +6 -6
- package/codegen/react/components/rnwcore/DebuggingOverlay.g.h +6 -6
- package/codegen/react/components/rnwcore/InputAccessory.g.h +6 -6
- package/codegen/react/components/rnwcore/ModalHostView.g.h +11 -7
- package/codegen/react/components/rnwcore/Props.cpp +2 -1
- package/codegen/react/components/rnwcore/Props.h +1 -0
- package/codegen/react/components/rnwcore/PullToRefreshView.g.h +6 -6
- package/codegen/react/components/rnwcore/SafeAreaView.g.h +6 -6
- package/codegen/react/components/rnwcore/Switch.g.h +6 -6
- package/codegen/react/components/rnwcore/UnimplementedNativeView.g.h +6 -6
- package/index.windows.js +4 -2
- package/package.json +3 -4
- package/src/private/specs/components/RCTModalHostViewNativeComponent.js +8 -0
- package/stubs/glog/logging.h +1 -1
- package/Microsoft.ReactNative/JSDispatcherWriter.h +0 -47
- package/Microsoft.ReactNative/SynchronousEventBeat.cpp +0 -51
- package/Microsoft.ReactNative/SynchronousEventBeat.h +0 -31
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
#include <Utils/KeyboardUtils.h>
|
|
16
16
|
#include <Utils/ValueUtils.h>
|
|
17
17
|
#include <Views/FrameworkElementTransferProperties.h>
|
|
18
|
+
#include <atlcomcli.h>
|
|
18
19
|
#include <winrt/Microsoft.ReactNative.Composition.Experimental.h>
|
|
19
20
|
#include <winrt/Microsoft.UI.Input.h>
|
|
20
21
|
#include <winrt/Windows.UI.Composition.h>
|
|
@@ -33,6 +34,7 @@
|
|
|
33
34
|
namespace winrt::Microsoft::ReactNative::Composition::implementation {
|
|
34
35
|
|
|
35
36
|
constexpr float FOCUS_VISUAL_WIDTH = 2.0f;
|
|
37
|
+
constexpr float FOCUS_VISUAL_RADIUS = 3.0f;
|
|
36
38
|
|
|
37
39
|
// m_outerVisual
|
|
38
40
|
// |
|
|
@@ -182,7 +184,7 @@ void ComponentView::updateProps(
|
|
|
182
184
|
updateShadowProps(oldViewProps, newViewProps);
|
|
183
185
|
}
|
|
184
186
|
if (oldViewProps.tooltip != newViewProps.tooltip) {
|
|
185
|
-
if (!m_tooltipTracked && newViewProps.tooltip) {
|
|
187
|
+
if (!m_tooltipTracked && newViewProps.tooltip && !newViewProps.tooltip->empty()) {
|
|
186
188
|
TooltipService::GetCurrent(m_reactContext.Properties())->StartTracking(*this);
|
|
187
189
|
m_tooltipTracked = true;
|
|
188
190
|
} else if (m_tooltipTracked && !newViewProps.tooltip) {
|
|
@@ -228,29 +230,11 @@ void ComponentView::updateFocusLayoutMetrics() noexcept {
|
|
|
228
230
|
facebook::react::RectangleEdges<bool> nudgeEdges;
|
|
229
231
|
auto scaleFactor = m_focusPrimitive->m_focusVisualComponent->m_layoutMetrics.pointScaleFactor;
|
|
230
232
|
if (m_focusPrimitive) {
|
|
233
|
+
auto nudgeEdges = m_focusPrimitive->m_focusVisualComponent->focusNudges();
|
|
231
234
|
if (m_focusPrimitive->m_focusOuterPrimitive) {
|
|
232
235
|
auto outerFocusMetrics = m_focusPrimitive->m_focusVisualComponent->focusLayoutMetrics(false /*inner*/);
|
|
233
|
-
|
|
234
|
-
if (outerFocusMetrics.frame.origin.x < 0) {
|
|
235
|
-
nudgeEdges.left = true;
|
|
236
|
-
}
|
|
237
|
-
if (outerFocusMetrics.frame.origin.y < 0) {
|
|
238
|
-
nudgeEdges.top = true;
|
|
239
|
-
}
|
|
240
|
-
if (outerFocusMetrics.frame.getMaxX() > m_layoutMetrics.frame.getMaxX()) {
|
|
241
|
-
nudgeEdges.right = true;
|
|
242
|
-
}
|
|
243
|
-
if (outerFocusMetrics.frame.getMaxY() > m_layoutMetrics.frame.getMaxY()) {
|
|
244
|
-
nudgeEdges.bottom = true;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
236
|
m_focusPrimitive->m_focusOuterPrimitive->RootVisual().Size(
|
|
248
|
-
{outerFocusMetrics.frame.size.width * scaleFactor
|
|
249
|
-
(nudgeEdges.left ? (FOCUS_VISUAL_WIDTH * 2 * scaleFactor) : 0) -
|
|
250
|
-
(nudgeEdges.right ? (FOCUS_VISUAL_WIDTH * 2 * scaleFactor) : 0),
|
|
251
|
-
outerFocusMetrics.frame.size.height * scaleFactor -
|
|
252
|
-
(nudgeEdges.top ? (FOCUS_VISUAL_WIDTH * 2 * scaleFactor) : 0) -
|
|
253
|
-
(nudgeEdges.bottom ? (FOCUS_VISUAL_WIDTH * 2 * scaleFactor) : 0)});
|
|
237
|
+
{outerFocusMetrics.frame.size.width * scaleFactor, outerFocusMetrics.frame.size.height * scaleFactor});
|
|
254
238
|
m_focusPrimitive->m_focusOuterPrimitive->RootVisual().Offset(
|
|
255
239
|
{nudgeEdges.left ? 0 : -(FOCUS_VISUAL_WIDTH * 2 * scaleFactor),
|
|
256
240
|
nudgeEdges.top ? 0 : -(FOCUS_VISUAL_WIDTH * 2 * scaleFactor),
|
|
@@ -261,15 +245,10 @@ void ComponentView::updateFocusLayoutMetrics() noexcept {
|
|
|
261
245
|
if (m_focusPrimitive->m_focusInnerPrimitive) {
|
|
262
246
|
auto innerFocusMetrics = m_focusPrimitive->m_focusVisualComponent->focusLayoutMetrics(true /*inner*/);
|
|
263
247
|
m_focusPrimitive->m_focusInnerPrimitive->RootVisual().Size(
|
|
264
|
-
{innerFocusMetrics.frame.size.width * scaleFactor
|
|
265
|
-
(nudgeEdges.left ? (FOCUS_VISUAL_WIDTH * scaleFactor) : 0) -
|
|
266
|
-
(nudgeEdges.right ? (FOCUS_VISUAL_WIDTH * scaleFactor) : 0),
|
|
267
|
-
innerFocusMetrics.frame.size.height * scaleFactor -
|
|
268
|
-
(nudgeEdges.top ? (FOCUS_VISUAL_WIDTH * scaleFactor) : 0) -
|
|
269
|
-
(nudgeEdges.bottom ? (FOCUS_VISUAL_WIDTH * scaleFactor) : 0)});
|
|
248
|
+
{innerFocusMetrics.frame.size.width * scaleFactor, innerFocusMetrics.frame.size.height * scaleFactor});
|
|
270
249
|
m_focusPrimitive->m_focusInnerPrimitive->RootVisual().Offset(
|
|
271
|
-
{nudgeEdges.left ?
|
|
272
|
-
nudgeEdges.top ?
|
|
250
|
+
{nudgeEdges.left ? (FOCUS_VISUAL_WIDTH * scaleFactor) : (-FOCUS_VISUAL_WIDTH * scaleFactor),
|
|
251
|
+
nudgeEdges.top ? (FOCUS_VISUAL_WIDTH * scaleFactor) : (-FOCUS_VISUAL_WIDTH * scaleFactor),
|
|
273
252
|
0.0f});
|
|
274
253
|
m_focusPrimitive->m_focusInnerPrimitive->markNeedsUpdate();
|
|
275
254
|
}
|
|
@@ -353,9 +332,9 @@ void ComponentView::onLostFocus(
|
|
|
353
332
|
|
|
354
333
|
m_componentHostingFocusVisual->hostFocusVisual(false, get_strong());
|
|
355
334
|
}
|
|
356
|
-
if (
|
|
335
|
+
if (UiaClientsAreListening()) {
|
|
357
336
|
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
|
|
358
|
-
|
|
337
|
+
EnsureUiaProvider(), UIA_HasKeyboardFocusPropertyId, true, false);
|
|
359
338
|
}
|
|
360
339
|
}
|
|
361
340
|
base_type::onLostFocus(args);
|
|
@@ -403,8 +382,8 @@ void ComponentView::onGotFocus(
|
|
|
403
382
|
focusRect.size.height += (FOCUS_VISUAL_WIDTH * 2);
|
|
404
383
|
focusVisualRoot(focusRect)->hostFocusVisual(true, get_strong());
|
|
405
384
|
}
|
|
406
|
-
if (
|
|
407
|
-
auto spProviderSimple =
|
|
385
|
+
if (UiaClientsAreListening()) {
|
|
386
|
+
auto spProviderSimple = EnsureUiaProvider().try_as<IRawElementProviderSimple>();
|
|
408
387
|
if (spProviderSimple != nullptr) {
|
|
409
388
|
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
|
|
410
389
|
m_uiaProvider, UIA_HasKeyboardFocusPropertyId, false, true);
|
|
@@ -538,7 +517,33 @@ winrt::Microsoft::ReactNative::Composition::Experimental::IVisual ComponentView:
|
|
|
538
517
|
return m_outerVisual ? m_outerVisual : Visual();
|
|
539
518
|
}
|
|
540
519
|
|
|
541
|
-
|
|
520
|
+
// If the focus visual would extend past the bounds of the hosting visual,
|
|
521
|
+
// then we will nudge the focus visual back inside the hosting visuals bounds.
|
|
522
|
+
facebook::react::RectangleEdges<bool> ComponentView::focusNudges() const noexcept {
|
|
523
|
+
facebook::react::RectangleEdges<bool> nudgeEdges;
|
|
524
|
+
|
|
525
|
+
// Always use outer focus metrics to determine if we need to nudge the focus rect over to fit
|
|
526
|
+
facebook::react::LayoutMetrics layoutMetrics = focusLayoutMetricsNoNudge(false /*inner*/);
|
|
527
|
+
|
|
528
|
+
Assert(m_componentHostingFocusVisual);
|
|
529
|
+
|
|
530
|
+
if (layoutMetrics.frame.origin.x < 0) {
|
|
531
|
+
nudgeEdges.left = true;
|
|
532
|
+
}
|
|
533
|
+
if (layoutMetrics.frame.origin.y < 0) {
|
|
534
|
+
nudgeEdges.top = true;
|
|
535
|
+
}
|
|
536
|
+
if (layoutMetrics.frame.getMaxX() > m_componentHostingFocusVisual->m_layoutMetrics.frame.getMaxX()) {
|
|
537
|
+
nudgeEdges.right = true;
|
|
538
|
+
}
|
|
539
|
+
if (layoutMetrics.frame.getMaxY() > m_componentHostingFocusVisual->m_layoutMetrics.frame.getMaxY()) {
|
|
540
|
+
nudgeEdges.bottom = true;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
return nudgeEdges;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
facebook::react::LayoutMetrics ComponentView::focusLayoutMetricsNoNudge(bool inner) const noexcept {
|
|
542
547
|
facebook::react::LayoutMetrics layoutMetrics = m_layoutMetrics;
|
|
543
548
|
layoutMetrics.frame.origin.x -= FOCUS_VISUAL_WIDTH * (inner ? 1 : 2);
|
|
544
549
|
layoutMetrics.frame.origin.y -= FOCUS_VISUAL_WIDTH * (inner ? 1 : 2);
|
|
@@ -547,6 +552,28 @@ facebook::react::LayoutMetrics ComponentView::focusLayoutMetrics(bool inner) con
|
|
|
547
552
|
return layoutMetrics;
|
|
548
553
|
}
|
|
549
554
|
|
|
555
|
+
facebook::react::LayoutMetrics ComponentView::focusLayoutMetrics(bool inner) const noexcept {
|
|
556
|
+
auto nudgeEdges = focusNudges();
|
|
557
|
+
auto layoutMetrics = focusLayoutMetricsNoNudge(inner);
|
|
558
|
+
|
|
559
|
+
if (nudgeEdges.left) {
|
|
560
|
+
layoutMetrics.frame.origin.x += FOCUS_VISUAL_WIDTH * 2;
|
|
561
|
+
layoutMetrics.frame.size.width -= FOCUS_VISUAL_WIDTH * 2;
|
|
562
|
+
}
|
|
563
|
+
if (nudgeEdges.top) {
|
|
564
|
+
layoutMetrics.frame.origin.y += FOCUS_VISUAL_WIDTH * 2;
|
|
565
|
+
layoutMetrics.frame.size.height -= FOCUS_VISUAL_WIDTH * 2;
|
|
566
|
+
}
|
|
567
|
+
if (nudgeEdges.right) {
|
|
568
|
+
layoutMetrics.frame.size.width -= FOCUS_VISUAL_WIDTH * 2;
|
|
569
|
+
}
|
|
570
|
+
if (nudgeEdges.bottom) {
|
|
571
|
+
layoutMetrics.frame.size.height -= FOCUS_VISUAL_WIDTH * 2;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
return layoutMetrics;
|
|
575
|
+
}
|
|
576
|
+
|
|
550
577
|
facebook::react::BorderMetrics ComponentView::focusBorderMetrics(
|
|
551
578
|
bool inner,
|
|
552
579
|
const facebook::react::LayoutMetrics &layoutMetrics) const noexcept {
|
|
@@ -556,22 +583,31 @@ facebook::react::BorderMetrics ComponentView::focusBorderMetrics(
|
|
|
556
583
|
innerColor.m_platformColor.push_back(inner ? "FocusVisualSecondary" : "FocusVisualPrimary");
|
|
557
584
|
metrics.borderColors.bottom = metrics.borderColors.left = metrics.borderColors.right = metrics.borderColors.top =
|
|
558
585
|
innerColor;
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
586
|
+
|
|
587
|
+
metrics.borderRadii.bottomLeft.horizontal =
|
|
588
|
+
(metrics.borderRadii.bottomLeft.horizontal ? metrics.borderRadii.bottomLeft.horizontal : FOCUS_VISUAL_RADIUS) +
|
|
589
|
+
FOCUS_VISUAL_WIDTH * (inner ? 1 : 2);
|
|
590
|
+
metrics.borderRadii.bottomLeft.vertical =
|
|
591
|
+
(metrics.borderRadii.bottomLeft.vertical ? metrics.borderRadii.bottomLeft.vertical : FOCUS_VISUAL_RADIUS) +
|
|
592
|
+
FOCUS_VISUAL_WIDTH * (inner ? 1 : 2);
|
|
593
|
+
metrics.borderRadii.bottomRight.horizontal =
|
|
594
|
+
(metrics.borderRadii.bottomRight.horizontal ? metrics.borderRadii.bottomRight.horizontal : FOCUS_VISUAL_RADIUS) +
|
|
595
|
+
FOCUS_VISUAL_WIDTH * (inner ? 1 : 2);
|
|
596
|
+
metrics.borderRadii.bottomRight.vertical =
|
|
597
|
+
(metrics.borderRadii.bottomRight.vertical ? metrics.borderRadii.bottomRight.vertical : FOCUS_VISUAL_RADIUS) +
|
|
598
|
+
FOCUS_VISUAL_WIDTH * (inner ? 1 : 2);
|
|
599
|
+
metrics.borderRadii.topLeft.horizontal =
|
|
600
|
+
(metrics.borderRadii.topLeft.horizontal ? metrics.borderRadii.topLeft.horizontal : FOCUS_VISUAL_RADIUS) +
|
|
601
|
+
FOCUS_VISUAL_WIDTH * (inner ? 1 : 2);
|
|
602
|
+
metrics.borderRadii.topLeft.vertical =
|
|
603
|
+
(metrics.borderRadii.topLeft.vertical ? metrics.borderRadii.topLeft.vertical : FOCUS_VISUAL_RADIUS) +
|
|
604
|
+
FOCUS_VISUAL_WIDTH * (inner ? 1 : 2);
|
|
605
|
+
metrics.borderRadii.topRight.horizontal =
|
|
606
|
+
(metrics.borderRadii.topRight.horizontal ? metrics.borderRadii.topRight.horizontal : FOCUS_VISUAL_RADIUS) +
|
|
607
|
+
FOCUS_VISUAL_WIDTH * (inner ? 1 : 2);
|
|
608
|
+
metrics.borderRadii.topRight.vertical =
|
|
609
|
+
(metrics.borderRadii.topRight.vertical ? metrics.borderRadii.topRight.vertical : FOCUS_VISUAL_RADIUS) +
|
|
610
|
+
FOCUS_VISUAL_WIDTH * (inner ? 1 : 2);
|
|
575
611
|
|
|
576
612
|
metrics.borderStyles.bottom = metrics.borderStyles.left = metrics.borderStyles.right = metrics.borderStyles.top =
|
|
577
613
|
facebook::react::BorderStyle::Solid;
|
|
@@ -708,67 +744,86 @@ void ComponentView::updateTransformProps(
|
|
|
708
744
|
void ComponentView::updateAccessibilityProps(
|
|
709
745
|
const facebook::react::ViewProps &oldViewProps,
|
|
710
746
|
const facebook::react::ViewProps &newViewProps) noexcept {
|
|
711
|
-
if (!
|
|
747
|
+
if (!UiaClientsAreListening())
|
|
712
748
|
return;
|
|
713
749
|
|
|
714
750
|
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
|
|
715
|
-
|
|
751
|
+
EnsureUiaProvider(), UIA_IsKeyboardFocusablePropertyId, oldViewProps.focusable, newViewProps.focusable);
|
|
716
752
|
|
|
717
753
|
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
|
|
718
|
-
|
|
754
|
+
EnsureUiaProvider(),
|
|
719
755
|
UIA_NamePropertyId,
|
|
720
756
|
oldViewProps.accessibilityLabel,
|
|
721
757
|
newViewProps.accessibilityLabel.empty() ? DefaultAccessibleName() : newViewProps.accessibilityLabel);
|
|
722
758
|
|
|
723
759
|
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
|
|
724
|
-
|
|
760
|
+
EnsureUiaProvider(),
|
|
725
761
|
UIA_IsContentElementPropertyId,
|
|
726
762
|
(oldViewProps.accessible && oldViewProps.accessibilityRole != "none"),
|
|
727
763
|
(newViewProps.accessible && newViewProps.accessibilityRole != "none"));
|
|
728
764
|
|
|
729
765
|
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
|
|
730
|
-
|
|
766
|
+
EnsureUiaProvider(),
|
|
731
767
|
UIA_IsControlElementPropertyId,
|
|
732
768
|
(oldViewProps.accessible && oldViewProps.accessibilityRole != "none"),
|
|
733
769
|
(newViewProps.accessible && newViewProps.accessibilityRole != "none"));
|
|
734
770
|
|
|
735
771
|
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
|
|
736
|
-
|
|
772
|
+
EnsureUiaProvider(),
|
|
737
773
|
UIA_IsEnabledPropertyId,
|
|
738
774
|
!(oldViewProps.accessibilityState && oldViewProps.accessibilityState->disabled),
|
|
739
775
|
!(newViewProps.accessibilityState && newViewProps.accessibilityState->disabled));
|
|
740
776
|
|
|
741
777
|
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
|
|
742
|
-
|
|
778
|
+
EnsureUiaProvider(),
|
|
743
779
|
UIA_IsEnabledPropertyId,
|
|
744
780
|
!(oldViewProps.accessibilityState && oldViewProps.accessibilityState->busy),
|
|
745
781
|
!(newViewProps.accessibilityState && newViewProps.accessibilityState->busy));
|
|
746
782
|
|
|
747
783
|
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
|
|
748
|
-
|
|
784
|
+
EnsureUiaProvider(), UIA_ControlTypePropertyId, oldViewProps.accessibilityRole, newViewProps.accessibilityRole);
|
|
749
785
|
|
|
750
786
|
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
|
|
751
|
-
|
|
787
|
+
EnsureUiaProvider(), UIA_HelpTextPropertyId, oldViewProps.accessibilityHint, newViewProps.accessibilityHint);
|
|
752
788
|
|
|
753
789
|
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
|
|
754
|
-
|
|
790
|
+
EnsureUiaProvider(),
|
|
755
791
|
UIA_PositionInSetPropertyId,
|
|
756
792
|
oldViewProps.accessibilityPosInSet,
|
|
757
793
|
newViewProps.accessibilityPosInSet);
|
|
758
794
|
|
|
759
795
|
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
|
|
760
|
-
|
|
796
|
+
EnsureUiaProvider(),
|
|
797
|
+
UIA_SizeOfSetPropertyId,
|
|
798
|
+
oldViewProps.accessibilitySetSize,
|
|
799
|
+
newViewProps.accessibilitySetSize);
|
|
761
800
|
|
|
762
801
|
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
|
|
763
|
-
|
|
802
|
+
EnsureUiaProvider(),
|
|
764
803
|
UIA_LiveSettingPropertyId,
|
|
765
804
|
oldViewProps.accessibilityLiveRegion,
|
|
766
805
|
newViewProps.accessibilityLiveRegion);
|
|
767
806
|
|
|
807
|
+
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
|
|
808
|
+
EnsureUiaProvider(), UIA_LevelPropertyId, oldViewProps.accessibilityLevel, newViewProps.accessibilityLevel);
|
|
809
|
+
|
|
810
|
+
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
|
|
811
|
+
EnsureUiaProvider(),
|
|
812
|
+
UIA_AccessKeyPropertyId,
|
|
813
|
+
oldViewProps.accessibilityAccessKey,
|
|
814
|
+
newViewProps.accessibilityAccessKey);
|
|
815
|
+
|
|
816
|
+
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
|
|
817
|
+
EnsureUiaProvider(),
|
|
818
|
+
UIA_ItemTypePropertyId,
|
|
819
|
+
oldViewProps.accessibilityItemType,
|
|
820
|
+
newViewProps.accessibilityItemType);
|
|
821
|
+
|
|
768
822
|
if ((oldViewProps.accessibilityState.has_value() && oldViewProps.accessibilityState->selected.has_value()) !=
|
|
769
823
|
((newViewProps.accessibilityState.has_value() && newViewProps.accessibilityState->selected.has_value()))) {
|
|
770
824
|
auto compProvider =
|
|
771
|
-
|
|
825
|
+
EnsureUiaProvider()
|
|
826
|
+
.try_as<winrt::Microsoft::ReactNative::implementation::CompositionDynamicAutomationProvider>();
|
|
772
827
|
if (compProvider) {
|
|
773
828
|
if ((newViewProps.accessibilityState.has_value() && newViewProps.accessibilityState->selected.has_value())) {
|
|
774
829
|
winrt::Microsoft::ReactNative::implementation::AddSelectionItemsToContainer(compProvider.get());
|
|
@@ -143,6 +143,8 @@ struct ComponentView : public ComponentViewT<
|
|
|
143
143
|
void FinalizeTransform(
|
|
144
144
|
facebook::react::LayoutMetrics const &layoutMetrics,
|
|
145
145
|
const facebook::react::ViewProps &viewProps) noexcept;
|
|
146
|
+
facebook::react::RectangleEdges<bool> focusNudges() const noexcept;
|
|
147
|
+
facebook::react::LayoutMetrics focusLayoutMetricsNoNudge(bool inner) const noexcept;
|
|
146
148
|
facebook::react::LayoutMetrics focusLayoutMetrics(bool inner) const noexcept;
|
|
147
149
|
facebook::react::BorderMetrics focusBorderMetrics(bool inner, const facebook::react::LayoutMetrics &layoutMetrics)
|
|
148
150
|
const noexcept;
|
|
@@ -11,12 +11,15 @@
|
|
|
11
11
|
#include <UI.Xaml.Controls.h>
|
|
12
12
|
#include <Utils/ValueUtils.h>
|
|
13
13
|
#include <winrt/Microsoft.UI.Content.h>
|
|
14
|
+
#include <winrt/Microsoft.UI.Input.h>
|
|
14
15
|
#include <winrt/Windows.UI.Composition.h>
|
|
15
16
|
#include "CompositionContextHelper.h"
|
|
16
17
|
#include "RootComponentView.h"
|
|
17
18
|
|
|
18
19
|
#include "Composition.ContentIslandComponentView.g.cpp"
|
|
19
20
|
|
|
21
|
+
#include "CompositionDynamicAutomationProvider.h"
|
|
22
|
+
|
|
20
23
|
namespace winrt::Microsoft::ReactNative::Composition::implementation {
|
|
21
24
|
|
|
22
25
|
ContentIslandComponentView::ContentIslandComponentView(
|
|
@@ -41,12 +44,27 @@ ContentIslandComponentView::ContentIslandComponentView(
|
|
|
41
44
|
}
|
|
42
45
|
|
|
43
46
|
void ContentIslandComponentView::OnMounted() noexcept {
|
|
44
|
-
#ifdef USE_EXPERIMENTAL_WINUI3
|
|
45
47
|
m_childSiteLink = winrt::Microsoft::UI::Content::ChildSiteLink::Create(
|
|
46
48
|
rootComponentView()->parentContentIsland(),
|
|
47
49
|
winrt::Microsoft::ReactNative::Composition::Experimental::CompositionContextHelper::InnerVisual(Visual())
|
|
48
50
|
.as<winrt::Microsoft::UI::Composition::ContainerVisual>());
|
|
49
51
|
m_childSiteLink.ActualSize({m_layoutMetrics.frame.size.width, m_layoutMetrics.frame.size.height});
|
|
52
|
+
|
|
53
|
+
m_navigationHost = winrt::Microsoft::UI::Input::InputFocusNavigationHost::GetForSiteLink(m_childSiteLink);
|
|
54
|
+
|
|
55
|
+
m_navigationHostDepartFocusRequestedToken =
|
|
56
|
+
m_navigationHost.DepartFocusRequested([wkThis = get_weak()](const auto &, const auto &args) {
|
|
57
|
+
if (auto strongThis = wkThis.get()) {
|
|
58
|
+
const bool next = (args.Request().Reason() != winrt::Microsoft::UI::Input::FocusNavigationReason::Last);
|
|
59
|
+
strongThis->rootComponentView()->TryMoveFocus(next);
|
|
60
|
+
args.Result(winrt::Microsoft::UI::Input::FocusNavigationResult::Moved);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// We configure automation even if there's no UIA client at this point, because it's possible the first UIA
|
|
65
|
+
// request we'll get will be for a child of this island calling upward in the UIA tree.
|
|
66
|
+
ConfigureChildSiteLinkAutomation();
|
|
67
|
+
|
|
50
68
|
if (m_islandToConnect) {
|
|
51
69
|
m_childSiteLink.Connect(m_islandToConnect);
|
|
52
70
|
m_islandToConnect = nullptr;
|
|
@@ -65,15 +83,17 @@ void ContentIslandComponentView::OnMounted() noexcept {
|
|
|
65
83
|
}));
|
|
66
84
|
view = view.Parent();
|
|
67
85
|
}
|
|
68
|
-
#endif
|
|
69
86
|
}
|
|
70
87
|
|
|
71
88
|
void ContentIslandComponentView::OnUnmounted() noexcept {
|
|
72
89
|
m_layoutMetricChangedRevokers.clear();
|
|
90
|
+
if (m_navigationHostDepartFocusRequestedToken && m_navigationHost) {
|
|
91
|
+
m_navigationHost.DepartFocusRequested(m_navigationHostDepartFocusRequestedToken);
|
|
92
|
+
m_navigationHostDepartFocusRequestedToken = {};
|
|
93
|
+
}
|
|
73
94
|
}
|
|
74
95
|
|
|
75
96
|
void ContentIslandComponentView::ParentLayoutChanged() noexcept {
|
|
76
|
-
#ifdef USE_EXPERIMENTAL_WINUI3
|
|
77
97
|
if (m_layoutChangePosted)
|
|
78
98
|
return;
|
|
79
99
|
|
|
@@ -89,10 +109,67 @@ void ContentIslandComponentView::ParentLayoutChanged() noexcept {
|
|
|
89
109
|
strongThis->m_layoutChangePosted = false;
|
|
90
110
|
}
|
|
91
111
|
});
|
|
92
|
-
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
winrt::IInspectable ContentIslandComponentView::EnsureUiaProvider() noexcept {
|
|
115
|
+
if (m_uiaProvider == nullptr) {
|
|
116
|
+
m_uiaProvider = winrt::make<winrt::Microsoft::ReactNative::implementation::CompositionDynamicAutomationProvider>(
|
|
117
|
+
*get_strong(), m_childSiteLink);
|
|
118
|
+
}
|
|
119
|
+
return m_uiaProvider;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
bool ContentIslandComponentView::focusable() const noexcept {
|
|
123
|
+
// We don't have a way to check to see if the ContentIsland has focusable content,
|
|
124
|
+
// so we'll always return true. We'll have to handle the case where the content doesn't have
|
|
125
|
+
// focusable content in the OnGotFocus handler.
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Helper to convert a FocusNavigationDirection to a FocusNavigationReason.
|
|
130
|
+
winrt::Microsoft::UI::Input::FocusNavigationReason GetFocusNavigationReason(
|
|
131
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection direction) noexcept {
|
|
132
|
+
switch (direction) {
|
|
133
|
+
case winrt::Microsoft::ReactNative::FocusNavigationDirection::First:
|
|
134
|
+
case winrt::Microsoft::ReactNative::FocusNavigationDirection::Next:
|
|
135
|
+
return winrt::Microsoft::UI::Input::FocusNavigationReason::First;
|
|
136
|
+
case winrt::Microsoft::ReactNative::FocusNavigationDirection::Last:
|
|
137
|
+
case winrt::Microsoft::ReactNative::FocusNavigationDirection::Previous:
|
|
138
|
+
return winrt::Microsoft::UI::Input::FocusNavigationReason::Last;
|
|
139
|
+
}
|
|
140
|
+
return winrt::Microsoft::UI::Input::FocusNavigationReason::Restore;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
void ContentIslandComponentView::onGotFocus(
|
|
144
|
+
const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept {
|
|
145
|
+
auto gotFocusEventArgs = args.as<winrt::Microsoft::ReactNative::implementation::GotFocusEventArgs>();
|
|
146
|
+
const auto navigationReason = GetFocusNavigationReason(gotFocusEventArgs->Direction());
|
|
147
|
+
m_navigationHost.NavigateFocus(winrt::Microsoft::UI::Input::FocusNavigationRequest::Create(navigationReason));
|
|
93
148
|
}
|
|
94
149
|
|
|
95
150
|
ContentIslandComponentView::~ContentIslandComponentView() noexcept {
|
|
151
|
+
if (m_navigationHostDepartFocusRequestedToken && m_navigationHost) {
|
|
152
|
+
m_navigationHost.DepartFocusRequested(m_navigationHostDepartFocusRequestedToken);
|
|
153
|
+
m_navigationHostDepartFocusRequestedToken = {};
|
|
154
|
+
}
|
|
155
|
+
if (m_childSiteLink) {
|
|
156
|
+
if (m_fragmentRootAutomationProviderRequestedToken) {
|
|
157
|
+
m_childSiteLink.FragmentRootAutomationProviderRequested(m_fragmentRootAutomationProviderRequestedToken);
|
|
158
|
+
m_fragmentRootAutomationProviderRequestedToken = {};
|
|
159
|
+
}
|
|
160
|
+
if (m_parentAutomationProviderRequestedToken) {
|
|
161
|
+
m_childSiteLink.ParentAutomationProviderRequested(m_parentAutomationProviderRequestedToken);
|
|
162
|
+
m_parentAutomationProviderRequestedToken = {};
|
|
163
|
+
}
|
|
164
|
+
if (m_nextSiblingAutomationProviderRequestedToken) {
|
|
165
|
+
m_childSiteLink.NextSiblingAutomationProviderRequested(m_nextSiblingAutomationProviderRequestedToken);
|
|
166
|
+
m_nextSiblingAutomationProviderRequestedToken = {};
|
|
167
|
+
}
|
|
168
|
+
if (m_previousSiblingAutomationProviderRequestedToken) {
|
|
169
|
+
m_childSiteLink.PreviousSiblingAutomationProviderRequested(m_previousSiblingAutomationProviderRequestedToken);
|
|
170
|
+
m_previousSiblingAutomationProviderRequestedToken = {};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
96
173
|
if (m_islandToConnect) {
|
|
97
174
|
m_islandToConnect.Close();
|
|
98
175
|
}
|
|
@@ -115,28 +192,76 @@ void ContentIslandComponentView::UnmountChildComponentView(
|
|
|
115
192
|
void ContentIslandComponentView::updateLayoutMetrics(
|
|
116
193
|
facebook::react::LayoutMetrics const &layoutMetrics,
|
|
117
194
|
facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept {
|
|
118
|
-
#ifdef USE_EXPERIMENTAL_WINUI3
|
|
119
195
|
if (m_childSiteLink) {
|
|
120
196
|
m_childSiteLink.ActualSize({layoutMetrics.frame.size.width, layoutMetrics.frame.size.height});
|
|
121
197
|
ParentLayoutChanged();
|
|
122
198
|
}
|
|
123
|
-
#endif
|
|
124
199
|
base_type::updateLayoutMetrics(layoutMetrics, oldLayoutMetrics);
|
|
125
200
|
}
|
|
126
201
|
|
|
127
202
|
void ContentIslandComponentView::Connect(const winrt::Microsoft::UI::Content::ContentIsland &contentIsland) noexcept {
|
|
128
|
-
#ifdef USE_EXPERIMENTAL_WINUI3
|
|
129
203
|
if (m_childSiteLink) {
|
|
130
204
|
m_islandToConnect = nullptr;
|
|
131
205
|
m_childSiteLink.Connect(contentIsland);
|
|
132
206
|
} else {
|
|
133
207
|
m_islandToConnect = contentIsland;
|
|
134
208
|
}
|
|
135
|
-
#endif
|
|
136
209
|
}
|
|
137
210
|
|
|
138
211
|
void ContentIslandComponentView::prepareForRecycle() noexcept {
|
|
139
212
|
Super::prepareForRecycle();
|
|
140
213
|
}
|
|
141
214
|
|
|
215
|
+
void ContentIslandComponentView::ConfigureChildSiteLinkAutomation() noexcept {
|
|
216
|
+
// This automation mode must be set before connecting the child ContentIsland.
|
|
217
|
+
// It puts the child content into a mode where it won't own its own framework root. Instead, the child island's
|
|
218
|
+
// automation peers will use the same framework root as the automation peer of this ContentIslandComponentView.
|
|
219
|
+
m_childSiteLink.AutomationOption(winrt::Microsoft::UI::Content::ContentAutomationOptions::FragmentBased);
|
|
220
|
+
|
|
221
|
+
// These events are raised in response to the child ContentIsland asking for providers.
|
|
222
|
+
// For example, the ContentIsland.FragmentRootAutomationProvider property will return
|
|
223
|
+
// the provider we provide here in FragmentRootAutomationProviderRequested.
|
|
224
|
+
|
|
225
|
+
// We capture "this" as a raw pointer because ContentIslandComponentView doesn't currently support weak ptrs.
|
|
226
|
+
// It's safe because we disconnect these events in the destructor.
|
|
227
|
+
|
|
228
|
+
m_fragmentRootAutomationProviderRequestedToken = m_childSiteLink.FragmentRootAutomationProviderRequested(
|
|
229
|
+
[this](
|
|
230
|
+
const winrt::Microsoft::UI::Content::IContentSiteAutomation &,
|
|
231
|
+
const winrt::Microsoft::UI::Content::ContentSiteAutomationProviderRequestedEventArgs &args) {
|
|
232
|
+
// The child island's fragment tree doesn't have its own fragment root.
|
|
233
|
+
// Here's how we can provide the correct fragment root to the child's UIA logic.
|
|
234
|
+
winrt::com_ptr<IRawElementProviderFragmentRoot> fragmentRoot{nullptr};
|
|
235
|
+
auto uiaProvider = this->EnsureUiaProvider();
|
|
236
|
+
uiaProvider.as<IRawElementProviderFragment>()->get_FragmentRoot(fragmentRoot.put());
|
|
237
|
+
args.AutomationProvider(fragmentRoot.as<IInspectable>());
|
|
238
|
+
args.Handled(true);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
m_parentAutomationProviderRequestedToken = m_childSiteLink.ParentAutomationProviderRequested(
|
|
242
|
+
[this](
|
|
243
|
+
const winrt::Microsoft::UI::Content::IContentSiteAutomation &,
|
|
244
|
+
const winrt::Microsoft::UI::Content::ContentSiteAutomationProviderRequestedEventArgs &args) {
|
|
245
|
+
auto uiaProvider = this->EnsureUiaProvider();
|
|
246
|
+
args.AutomationProvider(uiaProvider);
|
|
247
|
+
args.Handled(true);
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
m_nextSiblingAutomationProviderRequestedToken = m_childSiteLink.NextSiblingAutomationProviderRequested(
|
|
251
|
+
[](const winrt::Microsoft::UI::Content::IContentSiteAutomation &,
|
|
252
|
+
const winrt::Microsoft::UI::Content::ContentSiteAutomationProviderRequestedEventArgs &args) {
|
|
253
|
+
// The ContentIsland will always be the one and only child of this node, so it won't have siblings.
|
|
254
|
+
args.AutomationProvider(nullptr);
|
|
255
|
+
args.Handled(true);
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
m_previousSiblingAutomationProviderRequestedToken = m_childSiteLink.PreviousSiblingAutomationProviderRequested(
|
|
259
|
+
[](const winrt::Microsoft::UI::Content::IContentSiteAutomation &,
|
|
260
|
+
const winrt::Microsoft::UI::Content::ContentSiteAutomationProviderRequestedEventArgs &args) {
|
|
261
|
+
// The ContentIsland will always be the one and only child of this node, so it won't have siblings.
|
|
262
|
+
args.AutomationProvider(nullptr);
|
|
263
|
+
args.Handled(true);
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
|
|
142
267
|
} // namespace winrt::Microsoft::ReactNative::Composition::implementation
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
#include <Microsoft.ReactNative.Cxx/ReactContext.h>
|
|
10
10
|
#include <winrt/Microsoft.UI.Content.h>
|
|
11
|
+
#include <winrt/Microsoft.UI.Input.h>
|
|
11
12
|
#include <winrt/Windows.UI.Composition.h>
|
|
12
13
|
#include "CompositionHelpers.h"
|
|
13
14
|
#include "CompositionViewComponentView.h"
|
|
@@ -37,6 +38,12 @@ struct ContentIslandComponentView : ContentIslandComponentViewT<ContentIslandCom
|
|
|
37
38
|
|
|
38
39
|
void prepareForRecycle() noexcept override;
|
|
39
40
|
|
|
41
|
+
bool focusable() const noexcept override;
|
|
42
|
+
|
|
43
|
+
winrt::IInspectable EnsureUiaProvider() noexcept override;
|
|
44
|
+
|
|
45
|
+
void onGotFocus(const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept override;
|
|
46
|
+
|
|
40
47
|
ContentIslandComponentView(
|
|
41
48
|
const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
|
|
42
49
|
facebook::react::Tag tag,
|
|
@@ -54,9 +61,16 @@ struct ContentIslandComponentView : ContentIslandComponentViewT<ContentIslandCom
|
|
|
54
61
|
winrt::event_token m_mountedToken;
|
|
55
62
|
winrt::event_token m_unmountedToken;
|
|
56
63
|
std::vector<winrt::Microsoft::ReactNative::ComponentView::LayoutMetricsChanged_revoker> m_layoutMetricChangedRevokers;
|
|
57
|
-
#ifdef USE_EXPERIMENTAL_WINUI3
|
|
58
64
|
winrt::Microsoft::UI::Content::ChildSiteLink m_childSiteLink{nullptr};
|
|
59
|
-
|
|
65
|
+
winrt::Microsoft::UI::Input::InputFocusNavigationHost m_navigationHost{nullptr};
|
|
66
|
+
winrt::event_token m_navigationHostDepartFocusRequestedToken{};
|
|
67
|
+
|
|
68
|
+
// Automation
|
|
69
|
+
void ConfigureChildSiteLinkAutomation() noexcept;
|
|
70
|
+
winrt::event_token m_fragmentRootAutomationProviderRequestedToken{};
|
|
71
|
+
winrt::event_token m_parentAutomationProviderRequestedToken{};
|
|
72
|
+
winrt::event_token m_nextSiblingAutomationProviderRequestedToken{};
|
|
73
|
+
winrt::event_token m_previousSiblingAutomationProviderRequestedToken{};
|
|
60
74
|
};
|
|
61
75
|
|
|
62
76
|
} // namespace winrt::Microsoft::ReactNative::Composition::implementation
|
|
@@ -14,8 +14,10 @@ int32_t LostFocusEventArgs::OriginalSource() noexcept {
|
|
|
14
14
|
return m_originalSource;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
GotFocusEventArgs::GotFocusEventArgs(
|
|
18
|
-
|
|
17
|
+
GotFocusEventArgs::GotFocusEventArgs(
|
|
18
|
+
const winrt::Microsoft::ReactNative::ComponentView &originalSource,
|
|
19
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection direction)
|
|
20
|
+
: m_originalSource(originalSource ? originalSource.Tag() : -1), m_direction(direction) {}
|
|
19
21
|
int32_t GotFocusEventArgs::OriginalSource() noexcept {
|
|
20
22
|
return m_originalSource;
|
|
21
23
|
}
|
|
@@ -21,11 +21,19 @@ struct LostFocusEventArgs
|
|
|
21
21
|
|
|
22
22
|
struct GotFocusEventArgs
|
|
23
23
|
: winrt::implements<GotFocusEventArgs, winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs> {
|
|
24
|
-
GotFocusEventArgs(
|
|
24
|
+
GotFocusEventArgs(
|
|
25
|
+
const winrt::Microsoft::ReactNative::ComponentView &originalSource,
|
|
26
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection direction);
|
|
25
27
|
int32_t OriginalSource() noexcept;
|
|
26
28
|
|
|
29
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection Direction() const noexcept {
|
|
30
|
+
return m_direction;
|
|
31
|
+
}
|
|
32
|
+
|
|
27
33
|
private:
|
|
28
34
|
const int32_t m_originalSource;
|
|
35
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection m_direction{
|
|
36
|
+
winrt::Microsoft::ReactNative::FocusNavigationDirection::None};
|
|
29
37
|
};
|
|
30
38
|
|
|
31
39
|
struct LosingFocusEventArgs
|