react-native-windows 0.81.2 → 0.81.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Libraries/Components/Pressable/Pressable.d.ts +8 -0
- package/Libraries/Components/Pressable/Pressable.windows.js +21 -2
- package/Microsoft.ReactNative/ABIViewManager.cpp +12 -1
- package/Microsoft.ReactNative/CompositionSwitcher.idl +16 -9
- package/Microsoft.ReactNative/Fabric/ComponentView.cpp +26 -0
- package/Microsoft.ReactNative/Fabric/ComponentView.h +2 -0
- package/Microsoft.ReactNative/Fabric/Composition/ActivityIndicatorComponentView.cpp +0 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionAnnotationProvider.cpp +2 -5
- package/Microsoft.ReactNative/Fabric/Composition/CompositionAnnotationProvider.h +1 -4
- package/Microsoft.ReactNative/Fabric/Composition/CompositionContextHelper.cpp +15 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +65 -32
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +9 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +8 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +2 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionTextProvider.cpp +4 -7
- package/Microsoft.ReactNative/Fabric/Composition/CompositionTextProvider.h +1 -5
- package/Microsoft.ReactNative/Fabric/Composition/CompositionTextRangeProvider.cpp +68 -53
- package/Microsoft.ReactNative/Fabric/Composition/CompositionTextRangeProvider.h +1 -5
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +98 -15
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +10 -3
- package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp +73 -10
- package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.h +11 -1
- package/Microsoft.ReactNative/Fabric/Composition/DebuggingOverlayComponentView.cpp +3 -2
- package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp +0 -1
- package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +609 -4
- package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.h +63 -0
- package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.cpp +8 -0
- package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.h +3 -0
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +53 -2
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +8 -1
- package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +0 -1
- package/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.cpp +0 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +3 -1
- package/Microsoft.ReactNative/Fabric/Composition/Theme.cpp +6 -0
- package/Microsoft.ReactNative/Fabric/Composition/TooltipService.cpp +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +36 -14
- package/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.cpp +0 -1
- package/Microsoft.ReactNative/Fabric/ReactTaggedView.h +1 -1
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/WindowsTextLayoutManager.h +2 -1
- package/Microsoft.ReactNative/IReactViewComponentBuilder.idl +8 -0
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +1 -0
- package/Microsoft.ReactNative/Modules/ImageViewManagerModule.cpp +41 -15
- package/Microsoft.ReactNative/Utils/IcuUtils.cpp +84 -0
- package/Microsoft.ReactNative/Utils/IcuUtils.h +42 -0
- package/Microsoft.ReactNative.Cxx/StructInfo.h +8 -1
- package/Mso/src/dispatchQueue/queueService.cpp +3 -1
- package/Mso/src/dispatchQueue/uiScheduler_winrt.cpp +2 -1
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/Shared/Networking/OriginPolicyHttpFilter.cpp +2 -1
- package/Shared/Shared.vcxitems +1 -0
- package/Shared/Shared.vcxitems.filters +1 -0
- package/codegen/react/components/rnwcore/ActivityIndicatorView.g.h +14 -0
- package/codegen/react/components/rnwcore/AndroidDrawerLayout.g.h +34 -20
- package/codegen/react/components/rnwcore/AndroidHorizontalScrollContentView.g.h +14 -0
- package/codegen/react/components/rnwcore/AndroidProgressBar.g.h +14 -0
- package/codegen/react/components/rnwcore/AndroidSwipeRefreshLayout.g.h +18 -4
- package/codegen/react/components/rnwcore/AndroidSwitch.g.h +18 -4
- package/codegen/react/components/rnwcore/DebuggingOverlay.g.h +14 -0
- package/codegen/react/components/rnwcore/InputAccessory.g.h +14 -0
- package/codegen/react/components/rnwcore/ModalHostView.g.h +32 -18
- package/codegen/react/components/rnwcore/PullToRefreshView.g.h +18 -4
- package/codegen/react/components/rnwcore/SafeAreaView.g.h +14 -0
- package/codegen/react/components/rnwcore/Switch.g.h +18 -4
- package/codegen/react/components/rnwcore/UnimplementedNativeView.g.h +14 -0
- package/codegen/react/components/rnwcore/VirtualView.g.h +48 -6
- package/package.json +3 -3
|
@@ -11,18 +11,14 @@
|
|
|
11
11
|
namespace winrt::Microsoft::ReactNative::implementation {
|
|
12
12
|
|
|
13
13
|
CompositionTextRangeProvider::CompositionTextRangeProvider(
|
|
14
|
-
const winrt::Microsoft::ReactNative::
|
|
15
|
-
|
|
16
|
-
: m_view{componentView} {
|
|
17
|
-
m_parentProvider.copy_from(parentProvider);
|
|
18
|
-
}
|
|
14
|
+
const winrt::Microsoft::ReactNative::ComponentView &componentView) noexcept
|
|
15
|
+
: m_view{componentView} {}
|
|
19
16
|
|
|
20
17
|
HRESULT __stdcall CompositionTextRangeProvider::Clone(ITextRangeProvider **pRetVal) {
|
|
21
18
|
if (pRetVal == nullptr)
|
|
22
19
|
return E_POINTER;
|
|
23
20
|
|
|
24
|
-
auto clone = winrt::make<winrt::Microsoft::ReactNative::implementation::CompositionTextRangeProvider>(
|
|
25
|
-
m_view.view().as<winrt::Microsoft::ReactNative::Composition::ComponentView>(), m_parentProvider.get());
|
|
21
|
+
auto clone = winrt::make<winrt::Microsoft::ReactNative::implementation::CompositionTextRangeProvider>(m_view.view());
|
|
26
22
|
*pRetVal = clone.detach();
|
|
27
23
|
return S_OK;
|
|
28
24
|
}
|
|
@@ -91,13 +87,13 @@ HRESULT __stdcall CompositionTextRangeProvider::GetAttributeValue(TEXTATTRIBUTEI
|
|
|
91
87
|
if (!strongView)
|
|
92
88
|
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
93
89
|
|
|
94
|
-
auto props = std::static_pointer_cast<const facebook::react::
|
|
90
|
+
auto props = std::static_pointer_cast<const facebook::react::BaseViewProps>(
|
|
95
91
|
winrt::get_self<ComponentView>(strongView)->props());
|
|
96
92
|
|
|
97
|
-
auto
|
|
98
|
-
winrt::
|
|
93
|
+
auto asParagraph =
|
|
94
|
+
strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ParagraphComponentView>();
|
|
99
95
|
|
|
100
|
-
auto
|
|
96
|
+
auto asTextInput =
|
|
101
97
|
strongView.try_as<winrt::Microsoft::ReactNative::Composition::implementation::WindowsTextInputComponentView>();
|
|
102
98
|
|
|
103
99
|
if (props == nullptr)
|
|
@@ -106,15 +102,16 @@ HRESULT __stdcall CompositionTextRangeProvider::GetAttributeValue(TEXTATTRIBUTEI
|
|
|
106
102
|
if (attributeId == UIA_BackgroundColorAttributeId) {
|
|
107
103
|
pRetVal->vt = VT_I4;
|
|
108
104
|
pRetVal->lVal = (*props->backgroundColor).AsColorRefWithAlpha();
|
|
109
|
-
} else if (attributeId == UIA_CapStyleAttributeId) {
|
|
105
|
+
} else if (attributeId == UIA_CapStyleAttributeId && asParagraph) {
|
|
110
106
|
pRetVal->vt = VT_I4;
|
|
111
107
|
auto fontVariant = facebook::react::FontVariant::Default;
|
|
112
108
|
auto textTransform = facebook::react::TextTransform::None;
|
|
113
|
-
|
|
114
|
-
|
|
109
|
+
|
|
110
|
+
if (asParagraph->paragraphProps().textAttributes.fontVariant.has_value()) {
|
|
111
|
+
fontVariant = asParagraph->paragraphProps().textAttributes.fontVariant.value();
|
|
115
112
|
}
|
|
116
|
-
if (
|
|
117
|
-
textTransform =
|
|
113
|
+
if (asParagraph->paragraphProps().textAttributes.textTransform.has_value()) {
|
|
114
|
+
textTransform = asParagraph->paragraphProps().textAttributes.textTransform.value();
|
|
118
115
|
}
|
|
119
116
|
if (fontVariant == facebook::react::FontVariant::SmallCaps) {
|
|
120
117
|
pRetVal->lVal = CapStyle_SmallCap;
|
|
@@ -125,39 +122,44 @@ HRESULT __stdcall CompositionTextRangeProvider::GetAttributeValue(TEXTATTRIBUTEI
|
|
|
125
122
|
} else if (textTransform == facebook::react::TextTransform::Uppercase) {
|
|
126
123
|
pRetVal->lVal = CapStyle_AllCap;
|
|
127
124
|
}
|
|
128
|
-
} else if (attributeId == UIA_FontNameAttributeId) {
|
|
125
|
+
} else if (attributeId == UIA_FontNameAttributeId && asParagraph) {
|
|
129
126
|
pRetVal->vt = VT_BSTR;
|
|
130
|
-
auto fontName =
|
|
127
|
+
auto fontName = asParagraph->paragraphProps().textAttributes.fontFamily;
|
|
131
128
|
if (fontName.empty()) {
|
|
132
129
|
fontName = "Segoe UI";
|
|
133
130
|
}
|
|
134
131
|
std::wstring wfontName(fontName.begin(), fontName.end());
|
|
135
132
|
pRetVal->bstrVal = SysAllocString(wfontName.c_str());
|
|
136
|
-
} else if (attributeId == UIA_FontSizeAttributeId) {
|
|
133
|
+
} else if (attributeId == UIA_FontSizeAttributeId && asParagraph) {
|
|
137
134
|
pRetVal->vt = VT_R8;
|
|
138
|
-
pRetVal->dblVal =
|
|
139
|
-
} else if (attributeId == UIA_FontWeightAttributeId) {
|
|
140
|
-
if (
|
|
135
|
+
pRetVal->dblVal = asParagraph->paragraphProps().textAttributes.fontSize;
|
|
136
|
+
} else if (attributeId == UIA_FontWeightAttributeId && asParagraph) {
|
|
137
|
+
if (asParagraph->paragraphProps().textAttributes.fontWeight.has_value()) {
|
|
141
138
|
pRetVal->vt = VT_I4;
|
|
142
|
-
pRetVal->lVal = static_cast<long>(
|
|
139
|
+
pRetVal->lVal = static_cast<long>(asParagraph->paragraphProps().textAttributes.fontWeight.value());
|
|
143
140
|
}
|
|
144
|
-
} else if (attributeId == UIA_ForegroundColorAttributeId) {
|
|
141
|
+
} else if (attributeId == UIA_ForegroundColorAttributeId && asParagraph) {
|
|
145
142
|
pRetVal->vt = VT_I4;
|
|
146
|
-
pRetVal->lVal = (*
|
|
147
|
-
} else if (attributeId == UIA_IsItalicAttributeId) {
|
|
143
|
+
pRetVal->lVal = (*asParagraph->paragraphProps().textAttributes.foregroundColor).AsColorRefWithAlpha();
|
|
144
|
+
} else if (attributeId == UIA_IsItalicAttributeId && asParagraph) {
|
|
148
145
|
pRetVal->vt = VT_BOOL;
|
|
149
|
-
pRetVal->boolVal =
|
|
150
|
-
|
|
146
|
+
pRetVal->boolVal =
|
|
147
|
+
(asParagraph->paragraphProps().textAttributes.fontStyle.has_value() &&
|
|
148
|
+
asParagraph->paragraphProps().textAttributes.fontStyle.value() == facebook::react::FontStyle::Italic)
|
|
151
149
|
? VARIANT_TRUE
|
|
152
150
|
: VARIANT_FALSE;
|
|
153
151
|
} else if (attributeId == UIA_IsReadOnlyAttributeId) {
|
|
154
152
|
pRetVal->vt = VT_BOOL;
|
|
155
|
-
|
|
156
|
-
|
|
153
|
+
if (asTextInput) {
|
|
154
|
+
pRetVal->boolVal = asTextInput->windowsTextInputProps().editable ? VARIANT_FALSE : VARIANT_TRUE;
|
|
155
|
+
} else {
|
|
156
|
+
pRetVal->boolVal = VARIANT_TRUE;
|
|
157
|
+
}
|
|
158
|
+
} else if (attributeId == UIA_HorizontalTextAlignmentAttributeId && asParagraph) {
|
|
157
159
|
pRetVal->vt = VT_I4;
|
|
158
160
|
auto textAlign = facebook::react::TextAlignment::Center;
|
|
159
|
-
if (
|
|
160
|
-
textAlign =
|
|
161
|
+
if (asParagraph->paragraphProps().textAttributes.alignment.has_value()) {
|
|
162
|
+
textAlign = asParagraph->paragraphProps().textAttributes.alignment.value();
|
|
161
163
|
}
|
|
162
164
|
if (textAlign == facebook::react::TextAlignment::Left) {
|
|
163
165
|
pRetVal->lVal = HorizontalTextAlignment_Left;
|
|
@@ -170,40 +172,42 @@ HRESULT __stdcall CompositionTextRangeProvider::GetAttributeValue(TEXTATTRIBUTEI
|
|
|
170
172
|
} else if (textAlign == facebook::react::TextAlignment::Natural) {
|
|
171
173
|
pRetVal->lVal = HorizontalTextAlignment_Left;
|
|
172
174
|
}
|
|
173
|
-
} else if (attributeId == UIA_StrikethroughColorAttributeId) {
|
|
174
|
-
if (
|
|
175
|
-
(
|
|
175
|
+
} else if (attributeId == UIA_StrikethroughColorAttributeId && asParagraph) {
|
|
176
|
+
if (asParagraph->paragraphProps().textAttributes.textDecorationLineType.has_value() &&
|
|
177
|
+
(asParagraph->paragraphProps().textAttributes.textDecorationLineType.value() ==
|
|
176
178
|
facebook::react::TextDecorationLineType::Strikethrough ||
|
|
177
|
-
|
|
179
|
+
asParagraph->paragraphProps().textAttributes.textDecorationLineType.value() ==
|
|
178
180
|
facebook::react::TextDecorationLineType::UnderlineStrikethrough)) {
|
|
179
181
|
pRetVal->vt = VT_I4;
|
|
180
|
-
pRetVal->lVal = (*
|
|
182
|
+
pRetVal->lVal = (*asParagraph->paragraphProps().textAttributes.textDecorationColor).AsColorRefWithAlpha();
|
|
181
183
|
}
|
|
182
|
-
} else if (attributeId == UIA_StrikethroughStyleAttributeId) {
|
|
183
|
-
if (
|
|
184
|
-
(
|
|
184
|
+
} else if (attributeId == UIA_StrikethroughStyleAttributeId && asParagraph) {
|
|
185
|
+
if (asParagraph->paragraphProps().textAttributes.textDecorationLineType.has_value() &&
|
|
186
|
+
(asParagraph->paragraphProps().textAttributes.textDecorationLineType.value() ==
|
|
185
187
|
facebook::react::TextDecorationLineType::Strikethrough ||
|
|
186
|
-
|
|
188
|
+
asParagraph->paragraphProps().textAttributes.textDecorationLineType.value() ==
|
|
187
189
|
facebook::react::TextDecorationLineType::UnderlineStrikethrough)) {
|
|
188
190
|
pRetVal->vt = VT_I4;
|
|
189
|
-
auto style =
|
|
191
|
+
auto style = asParagraph->paragraphProps().textAttributes.textDecorationStyle.value();
|
|
190
192
|
pRetVal->lVal = GetTextDecorationLineStyle(style);
|
|
191
193
|
}
|
|
192
|
-
} else if (attributeId == UIA_UnderlineColorAttributeId) {
|
|
193
|
-
if (
|
|
194
|
-
(
|
|
195
|
-
|
|
194
|
+
} else if (attributeId == UIA_UnderlineColorAttributeId && asParagraph) {
|
|
195
|
+
if (asParagraph->paragraphProps().textAttributes.textDecorationLineType.has_value() &&
|
|
196
|
+
(asParagraph->paragraphProps().textAttributes.textDecorationLineType.value() ==
|
|
197
|
+
facebook::react::TextDecorationLineType::Underline ||
|
|
198
|
+
asParagraph->paragraphProps().textAttributes.textDecorationLineType.value() ==
|
|
196
199
|
facebook::react::TextDecorationLineType::UnderlineStrikethrough)) {
|
|
197
200
|
pRetVal->vt = VT_I4;
|
|
198
|
-
pRetVal->lVal = (*
|
|
201
|
+
pRetVal->lVal = (*asParagraph->paragraphProps().textAttributes.textDecorationColor).AsColorRefWithAlpha();
|
|
199
202
|
}
|
|
200
|
-
} else if (attributeId == UIA_UnderlineStyleAttributeId) {
|
|
201
|
-
if (
|
|
202
|
-
(
|
|
203
|
-
|
|
203
|
+
} else if (attributeId == UIA_UnderlineStyleAttributeId && asParagraph) {
|
|
204
|
+
if (asParagraph->paragraphProps().textAttributes.textDecorationLineType.has_value() &&
|
|
205
|
+
(asParagraph->paragraphProps().textAttributes.textDecorationLineType.value() ==
|
|
206
|
+
facebook::react::TextDecorationLineType::Underline ||
|
|
207
|
+
asParagraph->paragraphProps().textAttributes.textDecorationLineType.value() ==
|
|
204
208
|
facebook::react::TextDecorationLineType::UnderlineStrikethrough)) {
|
|
205
209
|
pRetVal->vt = VT_I4;
|
|
206
|
-
auto style =
|
|
210
|
+
auto style = asParagraph->paragraphProps().textAttributes.textDecorationStyle.value();
|
|
207
211
|
pRetVal->lVal = GetTextDecorationLineStyle(style);
|
|
208
212
|
}
|
|
209
213
|
}
|
|
@@ -214,7 +218,18 @@ HRESULT __stdcall CompositionTextRangeProvider::GetBoundingRectangles(SAFEARRAY
|
|
|
214
218
|
if (pRetVal == nullptr)
|
|
215
219
|
return E_POINTER;
|
|
216
220
|
UiaRect rect;
|
|
217
|
-
|
|
221
|
+
|
|
222
|
+
auto strongView = m_view.view();
|
|
223
|
+
if (!strongView)
|
|
224
|
+
return UIA_E_ELEMENTNOTAVAILABLE;
|
|
225
|
+
|
|
226
|
+
auto componentView = strongView.as<winrt::Microsoft::ReactNative::implementation::ComponentView>();
|
|
227
|
+
auto provider = componentView->EnsureUiaProvider();
|
|
228
|
+
auto repf = provider.try_as<IRawElementProviderFragment>();
|
|
229
|
+
if (!repf)
|
|
230
|
+
return E_FAIL;
|
|
231
|
+
|
|
232
|
+
auto hr = repf->get_BoundingRectangle(&rect);
|
|
218
233
|
if (FAILED(hr))
|
|
219
234
|
return hr;
|
|
220
235
|
*pRetVal = SafeArrayCreateVector(VT_R8, 0, 4);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
-
#include <Fabric/Composition/CompositionDynamicAutomationProvider.h>
|
|
4
3
|
#include <Fabric/Composition/CompositionTextProvider.h>
|
|
5
4
|
#include <Fabric/Composition/CompositionViewComponentView.h>
|
|
6
5
|
#include <Fabric/ReactTaggedView.h>
|
|
@@ -12,9 +11,7 @@ namespace winrt::Microsoft::ReactNative::implementation {
|
|
|
12
11
|
|
|
13
12
|
class CompositionTextRangeProvider : public winrt::implements<CompositionTextRangeProvider, ITextRangeProvider> {
|
|
14
13
|
public:
|
|
15
|
-
CompositionTextRangeProvider(
|
|
16
|
-
const winrt::Microsoft::ReactNative::Composition::ComponentView &componentView,
|
|
17
|
-
CompositionDynamicAutomationProvider *parentProvider) noexcept;
|
|
14
|
+
CompositionTextRangeProvider(const winrt::Microsoft::ReactNative::ComponentView &componentView) noexcept;
|
|
18
15
|
|
|
19
16
|
// inherited via ITextRangeProvider
|
|
20
17
|
virtual HRESULT __stdcall Clone(ITextRangeProvider **pRetVal) override;
|
|
@@ -53,7 +50,6 @@ class CompositionTextRangeProvider : public winrt::implements<CompositionTextRan
|
|
|
53
50
|
|
|
54
51
|
private:
|
|
55
52
|
::Microsoft::ReactNative::ReactTaggedView m_view;
|
|
56
|
-
winrt::com_ptr<CompositionDynamicAutomationProvider> m_parentProvider;
|
|
57
53
|
};
|
|
58
54
|
|
|
59
55
|
} // namespace winrt::Microsoft::ReactNative::implementation
|
|
@@ -710,7 +710,86 @@ void ComponentView::applyShadowProps(const facebook::react::ViewProps &viewProps
|
|
|
710
710
|
shadow.Color(theme()->Color(*viewProps.shadowColor));
|
|
711
711
|
}
|
|
712
712
|
|
|
713
|
-
|
|
713
|
+
// Check if any border radius is set
|
|
714
|
+
auto borderMetrics = BorderPrimitive::resolveAndAlignBorderMetrics(m_layoutMetrics, viewProps);
|
|
715
|
+
bool hasBorderRadius = borderMetrics.borderRadii.topLeft.horizontal != 0 ||
|
|
716
|
+
borderMetrics.borderRadii.topRight.horizontal != 0 || borderMetrics.borderRadii.bottomLeft.horizontal != 0 ||
|
|
717
|
+
borderMetrics.borderRadii.bottomRight.horizontal != 0 || borderMetrics.borderRadii.topLeft.vertical != 0 ||
|
|
718
|
+
borderMetrics.borderRadii.topRight.vertical != 0 || borderMetrics.borderRadii.bottomLeft.vertical != 0 ||
|
|
719
|
+
borderMetrics.borderRadii.bottomRight.vertical != 0;
|
|
720
|
+
|
|
721
|
+
if (hasBorderRadius) {
|
|
722
|
+
// When borderRadius is set, we need to create a shadow mask that follows the rounded rectangle shape.
|
|
723
|
+
// Use CompositionVisualSurface to capture the clipped visual's appearance as the shadow mask.
|
|
724
|
+
bool maskSet = false;
|
|
725
|
+
|
|
726
|
+
// Try Microsoft (WinUI3) Composition first
|
|
727
|
+
auto msCompositor =
|
|
728
|
+
winrt::Microsoft::ReactNative::Composition::Experimental::MicrosoftCompositionContextHelper::InnerCompositor(
|
|
729
|
+
m_compContext);
|
|
730
|
+
if (msCompositor) {
|
|
731
|
+
auto innerVisual =
|
|
732
|
+
winrt::Microsoft::ReactNative::Composition::Experimental::MicrosoftCompositionContextHelper::InnerVisual(
|
|
733
|
+
Visual());
|
|
734
|
+
if (innerVisual) {
|
|
735
|
+
// Create a VisualSurface that captures the visual (with its clip applied)
|
|
736
|
+
auto visualSurface = msCompositor.CreateVisualSurface();
|
|
737
|
+
visualSurface.SourceVisual(innerVisual);
|
|
738
|
+
visualSurface.SourceSize(
|
|
739
|
+
{m_layoutMetrics.frame.size.width * m_layoutMetrics.pointScaleFactor,
|
|
740
|
+
m_layoutMetrics.frame.size.height * m_layoutMetrics.pointScaleFactor});
|
|
741
|
+
|
|
742
|
+
// Create a brush from the visual surface to use as shadow mask
|
|
743
|
+
auto maskBrush = msCompositor.CreateSurfaceBrush(visualSurface);
|
|
744
|
+
maskBrush.Stretch(winrt::Microsoft::UI::Composition::CompositionStretch::Fill);
|
|
745
|
+
|
|
746
|
+
// Get the inner shadow and set the mask
|
|
747
|
+
auto innerShadow = winrt::Microsoft::ReactNative::Composition::Experimental::MicrosoftCompositionContextHelper::
|
|
748
|
+
InnerDropShadow(shadow);
|
|
749
|
+
if (innerShadow) {
|
|
750
|
+
innerShadow.Mask(maskBrush);
|
|
751
|
+
maskSet = true;
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
// Fallback to System (Windows.UI) Composition if Microsoft Composition is not available
|
|
757
|
+
if (!maskSet) {
|
|
758
|
+
auto sysCompositor =
|
|
759
|
+
winrt::Microsoft::ReactNative::Composition::Experimental::SystemCompositionContextHelper::InnerCompositor(
|
|
760
|
+
m_compContext);
|
|
761
|
+
if (sysCompositor) {
|
|
762
|
+
auto innerVisual =
|
|
763
|
+
winrt::Microsoft::ReactNative::Composition::Experimental::SystemCompositionContextHelper::InnerVisual(
|
|
764
|
+
Visual());
|
|
765
|
+
if (innerVisual) {
|
|
766
|
+
auto visualSurface = sysCompositor.CreateVisualSurface();
|
|
767
|
+
visualSurface.SourceVisual(innerVisual);
|
|
768
|
+
visualSurface.SourceSize(
|
|
769
|
+
{m_layoutMetrics.frame.size.width * m_layoutMetrics.pointScaleFactor,
|
|
770
|
+
m_layoutMetrics.frame.size.height * m_layoutMetrics.pointScaleFactor});
|
|
771
|
+
|
|
772
|
+
auto maskBrush = sysCompositor.CreateSurfaceBrush(visualSurface);
|
|
773
|
+
maskBrush.Stretch(winrt::Windows::UI::Composition::CompositionStretch::Fill);
|
|
774
|
+
|
|
775
|
+
auto innerShadow =
|
|
776
|
+
winrt::Microsoft::ReactNative::Composition::Experimental::SystemCompositionContextHelper::InnerDropShadow(
|
|
777
|
+
shadow);
|
|
778
|
+
if (innerShadow) {
|
|
779
|
+
innerShadow.Mask(maskBrush);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
// Apply shadow to OuterVisual (which is not clipped) so the shadow can extend beyond the clip
|
|
786
|
+
OuterVisual().as<winrt::Microsoft::ReactNative::Composition::Experimental::ISpriteVisual>().Shadow(shadow);
|
|
787
|
+
Visual().as<winrt::Microsoft::ReactNative::Composition::Experimental::ISpriteVisual>().Shadow(nullptr);
|
|
788
|
+
} else {
|
|
789
|
+
// No border radius - apply shadow directly to Visual (original behavior)
|
|
790
|
+
Visual().as<winrt::Microsoft::ReactNative::Composition::Experimental::ISpriteVisual>().Shadow(shadow);
|
|
791
|
+
OuterVisual().as<winrt::Microsoft::ReactNative::Composition::Experimental::ISpriteVisual>().Shadow(nullptr);
|
|
792
|
+
}
|
|
714
793
|
}
|
|
715
794
|
|
|
716
795
|
void ComponentView::updateTransformProps(
|
|
@@ -801,8 +880,8 @@ void ComponentView::updateAccessibilityProps(
|
|
|
801
880
|
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
|
|
802
881
|
EnsureUiaProvider(),
|
|
803
882
|
UIA_LiveSettingPropertyId,
|
|
804
|
-
oldViewProps.accessibilityLiveRegion,
|
|
805
|
-
newViewProps.accessibilityLiveRegion);
|
|
883
|
+
winrt::Microsoft::ReactNative::implementation::GetLiveSetting(oldViewProps.accessibilityLiveRegion),
|
|
884
|
+
winrt::Microsoft::ReactNative::implementation::GetLiveSetting(newViewProps.accessibilityLiveRegion));
|
|
806
885
|
|
|
807
886
|
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
|
|
808
887
|
EnsureUiaProvider(), UIA_LevelPropertyId, oldViewProps.accessibilityLevel, newViewProps.accessibilityLevel);
|
|
@@ -857,14 +936,13 @@ void ComponentView::updateAccessibilityProps(
|
|
|
857
936
|
|
|
858
937
|
if ((oldViewProps.accessibilityState.has_value() && oldViewProps.accessibilityState->selected.has_value()) !=
|
|
859
938
|
((newViewProps.accessibilityState.has_value() && newViewProps.accessibilityState->selected.has_value()))) {
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
.try_as<winrt::Microsoft::ReactNative::implementation::CompositionDynamicAutomationProvider>();
|
|
863
|
-
if (compProvider) {
|
|
939
|
+
EnsureUiaProvider();
|
|
940
|
+
if (m_innerAutomationProvider) {
|
|
864
941
|
if ((newViewProps.accessibilityState.has_value() && newViewProps.accessibilityState->selected.has_value())) {
|
|
865
|
-
winrt::Microsoft::ReactNative::implementation::AddSelectionItemsToContainer(
|
|
942
|
+
winrt::Microsoft::ReactNative::implementation::AddSelectionItemsToContainer(m_innerAutomationProvider.get());
|
|
866
943
|
} else {
|
|
867
|
-
winrt::Microsoft::ReactNative::implementation::RemoveSelectionItemsFromContainer(
|
|
944
|
+
winrt::Microsoft::ReactNative::implementation::RemoveSelectionItemsFromContainer(
|
|
945
|
+
m_innerAutomationProvider.get());
|
|
868
946
|
}
|
|
869
947
|
}
|
|
870
948
|
}
|
|
@@ -1354,12 +1432,17 @@ std::string ViewComponentView::DefaultControlType() const noexcept {
|
|
|
1354
1432
|
return "group";
|
|
1355
1433
|
}
|
|
1356
1434
|
|
|
1357
|
-
winrt::IInspectable ComponentView::
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
return
|
|
1435
|
+
winrt::Windows::Foundation::IInspectable ComponentView::CreateAutomationProvider() noexcept {
|
|
1436
|
+
Assert(!m_innerAutomationProvider);
|
|
1437
|
+
m_innerAutomationProvider =
|
|
1438
|
+
winrt::make_self<winrt::Microsoft::ReactNative::implementation::CompositionDynamicAutomationProvider>(
|
|
1439
|
+
*get_strong());
|
|
1440
|
+
return *m_innerAutomationProvider;
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
const winrt::com_ptr<winrt::Microsoft::ReactNative::implementation::CompositionDynamicAutomationProvider>
|
|
1444
|
+
&ComponentView::InnerAutomationProvider() const noexcept {
|
|
1445
|
+
return m_innerAutomationProvider;
|
|
1363
1446
|
}
|
|
1364
1447
|
|
|
1365
1448
|
bool IntersectRect(RECT *prcDst, const RECT &prcSrc1, const RECT &prcSrc2) {
|
|
@@ -19,8 +19,11 @@ namespace Microsoft::ReactNative {
|
|
|
19
19
|
struct CompContext;
|
|
20
20
|
} // namespace Microsoft::ReactNative
|
|
21
21
|
|
|
22
|
-
namespace winrt::Microsoft::ReactNative::
|
|
22
|
+
namespace winrt::Microsoft::ReactNative::implementation {
|
|
23
|
+
class CompositionDynamicAutomationProvider;
|
|
24
|
+
}
|
|
23
25
|
|
|
26
|
+
namespace winrt::Microsoft::ReactNative::Composition::implementation {
|
|
24
27
|
struct FocusPrimitive {
|
|
25
28
|
std::shared_ptr<BorderPrimitive> m_focusInnerPrimitive;
|
|
26
29
|
std::shared_ptr<BorderPrimitive> m_focusOuterPrimitive;
|
|
@@ -100,7 +103,9 @@ struct ComponentView : public ComponentViewT<
|
|
|
100
103
|
comp::CompositionPropertySet EnsureCenterPointPropertySet() noexcept;
|
|
101
104
|
void EnsureTransformMatrixFacade() noexcept;
|
|
102
105
|
|
|
103
|
-
winrt::IInspectable
|
|
106
|
+
winrt::Windows::Foundation::IInspectable CreateAutomationProvider() noexcept override;
|
|
107
|
+
const winrt::com_ptr<winrt::Microsoft::ReactNative::implementation::CompositionDynamicAutomationProvider>
|
|
108
|
+
&InnerAutomationProvider() const noexcept;
|
|
104
109
|
std::optional<std::string> getAccessiblityValue() noexcept override;
|
|
105
110
|
void setAcccessiblityValue(std::string &&value) noexcept override;
|
|
106
111
|
bool getAcccessiblityIsReadOnly() noexcept override;
|
|
@@ -130,7 +135,9 @@ struct ComponentView : public ComponentViewT<
|
|
|
130
135
|
facebook::react::Point &ptContent,
|
|
131
136
|
facebook::react::Point &localPt) const noexcept;
|
|
132
137
|
|
|
133
|
-
|
|
138
|
+
// Most access should be through EnsureUIAProvider, instead of direct access to this.
|
|
139
|
+
winrt::com_ptr<winrt::Microsoft::ReactNative::implementation::CompositionDynamicAutomationProvider>
|
|
140
|
+
m_innerAutomationProvider;
|
|
134
141
|
winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext m_compContext;
|
|
135
142
|
comp::CompositionPropertySet m_centerPropSet{nullptr};
|
|
136
143
|
facebook::react::SharedViewEventEmitter m_eventEmitter;
|
|
@@ -43,9 +43,19 @@ ContentIslandComponentView::ContentIslandComponentView(
|
|
|
43
43
|
});
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
winrt::Microsoft::UI::Content::ContentIsland ContentIslandComponentView::ParentContentIsland() noexcept {
|
|
47
|
+
auto root = rootComponentView();
|
|
48
|
+
if (!root)
|
|
49
|
+
return nullptr;
|
|
50
|
+
return root->parentContentIsland();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
void ContentIslandComponentView::ConnectInternal() noexcept {
|
|
54
|
+
if (!m_islandToConnect)
|
|
55
|
+
return;
|
|
56
|
+
|
|
47
57
|
m_childSiteLink = winrt::Microsoft::UI::Content::ChildSiteLink::Create(
|
|
48
|
-
|
|
58
|
+
m_parentContentIsland,
|
|
49
59
|
winrt::Microsoft::ReactNative::Composition::Experimental::CompositionContextHelper::InnerVisual(Visual())
|
|
50
60
|
.as<winrt::Microsoft::UI::Composition::ContainerVisual>());
|
|
51
61
|
m_childSiteLink.ActualSize({m_layoutMetrics.frame.size.width, m_layoutMetrics.frame.size.height});
|
|
@@ -69,6 +79,7 @@ void ContentIslandComponentView::OnMounted() noexcept {
|
|
|
69
79
|
m_childSiteLink.Connect(m_islandToConnect);
|
|
70
80
|
m_islandToConnect = nullptr;
|
|
71
81
|
}
|
|
82
|
+
UnregisterForRootIslandEvents();
|
|
72
83
|
|
|
73
84
|
ParentLayoutChanged();
|
|
74
85
|
auto view = Parent();
|
|
@@ -85,12 +96,42 @@ void ContentIslandComponentView::OnMounted() noexcept {
|
|
|
85
96
|
}
|
|
86
97
|
}
|
|
87
98
|
|
|
99
|
+
void ContentIslandComponentView::RegisterForRootIslandEvents() noexcept {
|
|
100
|
+
m_parentContentIsland = ParentContentIsland();
|
|
101
|
+
|
|
102
|
+
if (m_parentContentIsland.IsConnected()) {
|
|
103
|
+
ConnectInternal();
|
|
104
|
+
} else {
|
|
105
|
+
m_islandStateChangedToken = m_parentContentIsland.StateChanged(
|
|
106
|
+
[wkThis = get_weak()](
|
|
107
|
+
const winrt::Microsoft::UI::Content::ContentIsland & /*island*/,
|
|
108
|
+
const winrt::Microsoft::UI::Content::ContentIslandStateChangedEventArgs & /*args*/) {
|
|
109
|
+
if (auto strongThis = wkThis.get()) {
|
|
110
|
+
strongThis->ConnectInternal();
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
void ContentIslandComponentView::UnregisterForRootIslandEvents() noexcept {
|
|
117
|
+
if (m_islandStateChangedToken) {
|
|
118
|
+
m_parentContentIsland.StateChanged(m_islandStateChangedToken);
|
|
119
|
+
m_islandStateChangedToken = {};
|
|
120
|
+
m_parentContentIsland = nullptr;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
void ContentIslandComponentView::OnMounted() noexcept {
|
|
125
|
+
RegisterForRootIslandEvents();
|
|
126
|
+
}
|
|
127
|
+
|
|
88
128
|
void ContentIslandComponentView::OnUnmounted() noexcept {
|
|
89
129
|
m_layoutMetricChangedRevokers.clear();
|
|
90
130
|
if (m_navigationHostDepartFocusRequestedToken && m_navigationHost) {
|
|
91
131
|
m_navigationHost.DepartFocusRequested(m_navigationHostDepartFocusRequestedToken);
|
|
92
132
|
m_navigationHostDepartFocusRequestedToken = {};
|
|
93
133
|
}
|
|
134
|
+
UnregisterForRootIslandEvents();
|
|
94
135
|
}
|
|
95
136
|
|
|
96
137
|
void ContentIslandComponentView::ParentLayoutChanged() noexcept {
|
|
@@ -111,12 +152,11 @@ void ContentIslandComponentView::ParentLayoutChanged() noexcept {
|
|
|
111
152
|
});
|
|
112
153
|
}
|
|
113
154
|
|
|
114
|
-
winrt::IInspectable ContentIslandComponentView::
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
return m_uiaProvider;
|
|
155
|
+
winrt::Windows::Foundation::IInspectable ContentIslandComponentView::CreateAutomationProvider() noexcept {
|
|
156
|
+
m_innerAutomationProvider =
|
|
157
|
+
winrt::make_self<winrt::Microsoft::ReactNative::implementation::CompositionDynamicAutomationProvider>(
|
|
158
|
+
*get_strong(), m_childSiteLink);
|
|
159
|
+
return *m_innerAutomationProvider;
|
|
120
160
|
}
|
|
121
161
|
|
|
122
162
|
bool ContentIslandComponentView::focusable() const noexcept {
|
|
@@ -126,6 +166,27 @@ bool ContentIslandComponentView::focusable() const noexcept {
|
|
|
126
166
|
return true;
|
|
127
167
|
}
|
|
128
168
|
|
|
169
|
+
facebook::react::Tag ContentIslandComponentView::hitTest(
|
|
170
|
+
facebook::react::Point pt,
|
|
171
|
+
facebook::react::Point &localPt,
|
|
172
|
+
bool ignorePointerEvents) const noexcept {
|
|
173
|
+
facebook::react::Point ptLocal{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y};
|
|
174
|
+
|
|
175
|
+
// Check if the point is within the bounds of this ContentIslandComponentView.
|
|
176
|
+
// This ensures that hit tests correctly return this view's tag for UIA purposes,
|
|
177
|
+
// even when the actual content (XAML buttons, etc.) is hosted in the ContentIsland.
|
|
178
|
+
auto props = viewProps();
|
|
179
|
+
if ((ignorePointerEvents || props->pointerEvents == facebook::react::PointerEventsMode::Auto ||
|
|
180
|
+
props->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) &&
|
|
181
|
+
ptLocal.x >= 0 && ptLocal.x <= m_layoutMetrics.frame.size.width && ptLocal.y >= 0 &&
|
|
182
|
+
ptLocal.y <= m_layoutMetrics.frame.size.height) {
|
|
183
|
+
localPt = ptLocal;
|
|
184
|
+
return Tag();
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return -1;
|
|
188
|
+
}
|
|
189
|
+
|
|
129
190
|
// Helper to convert a FocusNavigationDirection to a FocusNavigationReason.
|
|
130
191
|
winrt::Microsoft::UI::Input::FocusNavigationReason GetFocusNavigationReason(
|
|
131
192
|
winrt::Microsoft::ReactNative::FocusNavigationDirection direction) noexcept {
|
|
@@ -178,14 +239,12 @@ ContentIslandComponentView::~ContentIslandComponentView() noexcept {
|
|
|
178
239
|
void ContentIslandComponentView::MountChildComponentView(
|
|
179
240
|
const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
|
|
180
241
|
uint32_t index) noexcept {
|
|
181
|
-
assert(false);
|
|
182
242
|
base_type::MountChildComponentView(childComponentView, index);
|
|
183
243
|
}
|
|
184
244
|
|
|
185
245
|
void ContentIslandComponentView::UnmountChildComponentView(
|
|
186
246
|
const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
|
|
187
247
|
uint32_t index) noexcept {
|
|
188
|
-
assert(false);
|
|
189
248
|
base_type::UnmountChildComponentView(childComponentView, index);
|
|
190
249
|
}
|
|
191
250
|
|
|
@@ -262,6 +321,10 @@ void ContentIslandComponentView::ConfigureChildSiteLinkAutomation() noexcept {
|
|
|
262
321
|
args.AutomationProvider(nullptr);
|
|
263
322
|
args.Handled(true);
|
|
264
323
|
});
|
|
324
|
+
|
|
325
|
+
if (m_innerAutomationProvider) {
|
|
326
|
+
m_innerAutomationProvider->SetChildSiteLink(m_childSiteLink);
|
|
327
|
+
}
|
|
265
328
|
}
|
|
266
329
|
|
|
267
330
|
} // namespace winrt::Microsoft::ReactNative::Composition::implementation
|
|
@@ -40,7 +40,10 @@ struct ContentIslandComponentView : ContentIslandComponentViewT<ContentIslandCom
|
|
|
40
40
|
|
|
41
41
|
bool focusable() const noexcept override;
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents)
|
|
44
|
+
const noexcept override;
|
|
45
|
+
|
|
46
|
+
winrt::Windows::Foundation::IInspectable CreateAutomationProvider() noexcept override;
|
|
44
47
|
|
|
45
48
|
void onGotFocus(const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept override;
|
|
46
49
|
|
|
@@ -55,9 +58,16 @@ struct ContentIslandComponentView : ContentIslandComponentViewT<ContentIslandCom
|
|
|
55
58
|
void OnMounted() noexcept;
|
|
56
59
|
void OnUnmounted() noexcept;
|
|
57
60
|
void ParentLayoutChanged() noexcept;
|
|
61
|
+
void ConnectInternal() noexcept;
|
|
62
|
+
void RegisterForRootIslandEvents() noexcept;
|
|
63
|
+
void UnregisterForRootIslandEvents() noexcept;
|
|
64
|
+
winrt::Microsoft::UI::Content::ContentIsland ParentContentIsland() noexcept;
|
|
58
65
|
|
|
59
66
|
bool m_layoutChangePosted{false};
|
|
67
|
+
winrt::Microsoft::UI::Content::ContentIsland m_parentContentIsland{nullptr};
|
|
60
68
|
winrt::Microsoft::UI::Content::ContentIsland m_islandToConnect{nullptr};
|
|
69
|
+
winrt::event_token m_islandStateChangedToken;
|
|
70
|
+
|
|
61
71
|
winrt::event_token m_mountedToken;
|
|
62
72
|
winrt::event_token m_unmountedToken;
|
|
63
73
|
std::vector<winrt::Microsoft::ReactNative::ComponentView::LayoutMetricsChanged_revoker> m_layoutMetricChangedRevokers;
|
|
@@ -86,10 +86,11 @@ void DebuggingOverlayComponentView::HandleCommand(
|
|
|
86
86
|
if (auto root = rootComponentView()) {
|
|
87
87
|
auto rootVisual = root->OuterVisual();
|
|
88
88
|
auto brush = m_compContext.CreateColorBrush({204, 200, 230, 255});
|
|
89
|
+
float scaleFactor = m_layoutMetrics.pointScaleFactor;
|
|
89
90
|
for (auto &element : elements) {
|
|
90
91
|
auto overlayVisual = m_compContext.CreateSpriteVisual();
|
|
91
|
-
overlayVisual.Size({element.width, element.height});
|
|
92
|
-
overlayVisual.Offset({element.x, element.y, 0.0f});
|
|
92
|
+
overlayVisual.Size({element.width * scaleFactor, element.height * scaleFactor});
|
|
93
|
+
overlayVisual.Offset({element.x * scaleFactor, element.y * scaleFactor, 0.0f});
|
|
93
94
|
overlayVisual.Brush(brush);
|
|
94
95
|
|
|
95
96
|
rootVisual.InsertAt(overlayVisual, root->overlayIndex() + m_activeOverlays);
|