react-native-windows 0.74.5 → 0.74.6
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/Microsoft.ReactNative/ComponentView.idl +26 -0
- package/Microsoft.ReactNative/CompositionComponentView.idl +2 -0
- package/Microsoft.ReactNative/Fabric/ComponentView.cpp +83 -12
- package/Microsoft.ReactNative/Fabric/ComponentView.h +33 -2
- package/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.cpp +26 -11
- package/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.h +2 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +33 -23
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +6 -2
- package/Microsoft.ReactNative/Fabric/Composition/FocusManager.cpp +152 -0
- package/Microsoft.ReactNative/Fabric/Composition/FocusManager.h +85 -0
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +40 -40
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +5 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +7 -5
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +2 -2
- package/Microsoft.ReactNative/FocusManager.idl +22 -0
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/Shared/Shared.vcxitems +6 -0
- package/package.json +1 -1
|
@@ -67,6 +67,26 @@ namespace Microsoft.ReactNative
|
|
|
67
67
|
IReactContext ReactContext { get;};
|
|
68
68
|
};
|
|
69
69
|
|
|
70
|
+
[experimental]
|
|
71
|
+
[webhosthidden]
|
|
72
|
+
runtimeclass LosingFocusEventArgs : Microsoft.ReactNative.Composition.Input.RoutedEventArgs {
|
|
73
|
+
Microsoft.ReactNative.ComponentView NewFocusedComponent { get; };
|
|
74
|
+
Microsoft.ReactNative.ComponentView OldFocusedComponent { get; };
|
|
75
|
+
|
|
76
|
+
void TryCancel();
|
|
77
|
+
void TrySetNewFocusedComponent(Microsoft.ReactNative.ComponentView component);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
[experimental]
|
|
81
|
+
[webhosthidden]
|
|
82
|
+
runtimeclass GettingFocusEventArgs : Microsoft.ReactNative.Composition.Input.RoutedEventArgs {
|
|
83
|
+
Microsoft.ReactNative.ComponentView NewFocusedComponent { get; };
|
|
84
|
+
Microsoft.ReactNative.ComponentView OldFocusedComponent { get; };
|
|
85
|
+
|
|
86
|
+
void TryCancel();
|
|
87
|
+
void TrySetNewFocusedComponent(Microsoft.ReactNative.ComponentView component);
|
|
88
|
+
};
|
|
89
|
+
|
|
70
90
|
[experimental]
|
|
71
91
|
[webhosthidden]
|
|
72
92
|
unsealed runtimeclass ComponentView {
|
|
@@ -101,6 +121,12 @@ namespace Microsoft.ReactNative
|
|
|
101
121
|
overridable void OnPointerExited(Microsoft.ReactNative.Composition.Input.PointerRoutedEventArgs args);
|
|
102
122
|
overridable void OnPointerCaptureLost();
|
|
103
123
|
|
|
124
|
+
Boolean TryFocus();
|
|
125
|
+
|
|
126
|
+
event Windows.Foundation.EventHandler<LosingFocusEventArgs> LosingFocus;
|
|
127
|
+
event Windows.Foundation.EventHandler<GettingFocusEventArgs> GettingFocus;
|
|
128
|
+
event Windows.Foundation.EventHandler<Microsoft.ReactNative.Composition.Input.RoutedEventArgs> LostFocus;
|
|
129
|
+
event Windows.Foundation.EventHandler<Microsoft.ReactNative.Composition.Input.RoutedEventArgs> GotFocus;
|
|
104
130
|
};
|
|
105
131
|
|
|
106
132
|
} // namespace Microsoft.ReactNative
|
|
@@ -48,6 +48,7 @@ namespace Microsoft.ReactNative.Composition
|
|
|
48
48
|
ComponentView(CreateCompositionComponentViewArgs args);
|
|
49
49
|
|
|
50
50
|
Microsoft.UI.Composition.Compositor Compositor { get; };
|
|
51
|
+
RootComponentView Root { get; };
|
|
51
52
|
Theme Theme;
|
|
52
53
|
overridable void OnThemeChanged();
|
|
53
54
|
Boolean CapturePointer(Microsoft.ReactNative.Composition.Input.Pointer pointer);
|
|
@@ -88,6 +89,7 @@ namespace Microsoft.ReactNative.Composition
|
|
|
88
89
|
[webhosthidden]
|
|
89
90
|
[default_interface]
|
|
90
91
|
unsealed runtimeclass RootComponentView : ViewComponentView {
|
|
92
|
+
Microsoft.ReactNative.ComponentView GetFocusedComponent();
|
|
91
93
|
};
|
|
92
94
|
|
|
93
95
|
[experimental]
|
|
@@ -143,19 +143,16 @@ ComponentView::rootComponentView() noexcept {
|
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
void ComponentView::parent(const winrt::Microsoft::ReactNative::ComponentView &parent) noexcept {
|
|
146
|
-
if (!parent) {
|
|
147
|
-
auto root = rootComponentView();
|
|
148
|
-
winrt::Microsoft::ReactNative::ComponentView view{nullptr};
|
|
149
|
-
winrt::check_hresult(
|
|
150
|
-
QueryInterface(winrt::guid_of<winrt::Microsoft::ReactNative::ComponentView>(), winrt::put_abi(view)));
|
|
151
|
-
if (root && root->GetFocusedComponent() == view) {
|
|
152
|
-
root->SetFocusedComponent(nullptr); // TODO need move focus logic - where should focus go?
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
146
|
if (m_parent != parent) {
|
|
147
|
+
auto oldRootView = rootComponentView();
|
|
157
148
|
m_rootView = nullptr;
|
|
149
|
+
auto oldParent = m_parent;
|
|
158
150
|
m_parent = parent;
|
|
151
|
+
if (!parent) {
|
|
152
|
+
if (oldRootView && oldRootView->GetFocusedComponent() == *this) {
|
|
153
|
+
oldRootView->TrySetFocusedComponent(oldParent);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
159
156
|
if (parent) {
|
|
160
157
|
theme(winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(parent)->theme());
|
|
161
158
|
}
|
|
@@ -220,9 +217,83 @@ facebook::react::Point ComponentView::getClientOffset() const noexcept {
|
|
|
220
217
|
return {};
|
|
221
218
|
}
|
|
222
219
|
|
|
223
|
-
void ComponentView::
|
|
220
|
+
void ComponentView::onLostFocus(
|
|
221
|
+
const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept {
|
|
222
|
+
m_lostFocusEvent(*this, args);
|
|
223
|
+
if (m_parent) {
|
|
224
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(m_parent)->onLostFocus(args);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
void ComponentView::onGotFocus(
|
|
229
|
+
const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept {
|
|
230
|
+
m_gotFocusEvent(*this, args);
|
|
231
|
+
if (m_parent) {
|
|
232
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(m_parent)->onGotFocus(args);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
void ComponentView::onLosingFocus(const winrt::Microsoft::ReactNative::LosingFocusEventArgs &args) noexcept {
|
|
237
|
+
m_losingFocusEvent(*this, args);
|
|
238
|
+
if (m_parent) {
|
|
239
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(m_parent)->onLosingFocus(args);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
void ComponentView::onGettingFocus(const winrt::Microsoft::ReactNative::GettingFocusEventArgs &args) noexcept {
|
|
244
|
+
m_gettingFocusEvent(*this, args);
|
|
245
|
+
if (m_parent) {
|
|
246
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(m_parent)->onGettingFocus(args);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
224
249
|
|
|
225
|
-
|
|
250
|
+
winrt::event_token ComponentView::LosingFocus(
|
|
251
|
+
winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::LosingFocusEventArgs> const
|
|
252
|
+
&handler) noexcept {
|
|
253
|
+
return m_losingFocusEvent.add(handler);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
void ComponentView::LosingFocus(winrt::event_token const &token) noexcept {
|
|
257
|
+
m_losingFocusEvent.remove(token);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
winrt::event_token ComponentView::GettingFocus(
|
|
261
|
+
winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::GettingFocusEventArgs> const
|
|
262
|
+
&handler) noexcept {
|
|
263
|
+
return m_gettingFocusEvent.add(handler);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
void ComponentView::GettingFocus(winrt::event_token const &token) noexcept {
|
|
267
|
+
m_gettingFocusEvent.remove(token);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
winrt::event_token ComponentView::LostFocus(
|
|
271
|
+
winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs> const
|
|
272
|
+
&handler) noexcept {
|
|
273
|
+
return m_lostFocusEvent.add(handler);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
void ComponentView::LostFocus(winrt::event_token const &token) noexcept {
|
|
277
|
+
m_lostFocusEvent.remove(token);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
winrt::event_token ComponentView::GotFocus(
|
|
281
|
+
winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs> const
|
|
282
|
+
&handler) noexcept {
|
|
283
|
+
return m_gotFocusEvent.add(handler);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
void ComponentView::GotFocus(winrt::event_token const &token) noexcept {
|
|
287
|
+
m_gotFocusEvent.remove(token);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
bool ComponentView::TryFocus() noexcept {
|
|
291
|
+
if (auto root = rootComponentView()) {
|
|
292
|
+
return root->TrySetFocusedComponent(*get_strong());
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
226
297
|
|
|
227
298
|
void ComponentView::OnPointerEntered(
|
|
228
299
|
const winrt::Microsoft::ReactNative::Composition::Input::PointerRoutedEventArgs &args) noexcept {}
|
|
@@ -87,8 +87,29 @@ struct ComponentView : public ComponentViewT<ComponentView> {
|
|
|
87
87
|
virtual RECT getClientRect() const noexcept;
|
|
88
88
|
// The offset from this elements parent to its children (accounts for things like scroll position)
|
|
89
89
|
virtual facebook::react::Point getClientOffset() const noexcept;
|
|
90
|
-
virtual void
|
|
91
|
-
virtual void
|
|
90
|
+
virtual void onLosingFocus(const winrt::Microsoft::ReactNative::LosingFocusEventArgs &args) noexcept;
|
|
91
|
+
virtual void onGettingFocus(const winrt::Microsoft::ReactNative::GettingFocusEventArgs &args) noexcept;
|
|
92
|
+
virtual void onLostFocus(const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept;
|
|
93
|
+
virtual void onGotFocus(const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept;
|
|
94
|
+
|
|
95
|
+
winrt::event_token LosingFocus(
|
|
96
|
+
winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::LosingFocusEventArgs> const
|
|
97
|
+
&handler) noexcept;
|
|
98
|
+
void LosingFocus(winrt::event_token const &token) noexcept;
|
|
99
|
+
winrt::event_token GettingFocus(
|
|
100
|
+
winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::GettingFocusEventArgs> const
|
|
101
|
+
&handler) noexcept;
|
|
102
|
+
void GettingFocus(winrt::event_token const &token) noexcept;
|
|
103
|
+
winrt::event_token LostFocus(
|
|
104
|
+
winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs> const
|
|
105
|
+
&handler) noexcept;
|
|
106
|
+
void LostFocus(winrt::event_token const &token) noexcept;
|
|
107
|
+
winrt::event_token GotFocus(
|
|
108
|
+
winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs> const
|
|
109
|
+
&handler) noexcept;
|
|
110
|
+
void GotFocus(winrt::event_token const &token) noexcept;
|
|
111
|
+
|
|
112
|
+
bool TryFocus() noexcept;
|
|
92
113
|
|
|
93
114
|
virtual bool focusable() const noexcept;
|
|
94
115
|
virtual facebook::react::SharedViewEventEmitter eventEmitterAtPoint(facebook::react::Point pt) noexcept;
|
|
@@ -158,6 +179,16 @@ struct ComponentView : public ComponentViewT<ComponentView> {
|
|
|
158
179
|
winrt::Microsoft::ReactNative::ComponentView m_parent{nullptr};
|
|
159
180
|
winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::ReactNative::ComponentView> m_children{
|
|
160
181
|
winrt::single_threaded_vector<winrt::Microsoft::ReactNative::ComponentView>()};
|
|
182
|
+
winrt::event<winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::LosingFocusEventArgs>>
|
|
183
|
+
m_losingFocusEvent;
|
|
184
|
+
winrt::event<winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::GettingFocusEventArgs>>
|
|
185
|
+
m_gettingFocusEvent;
|
|
186
|
+
winrt::event<
|
|
187
|
+
winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs>>
|
|
188
|
+
m_lostFocusEvent;
|
|
189
|
+
winrt::event<
|
|
190
|
+
winrt::Windows::Foundation::EventHandler<winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs>>
|
|
191
|
+
m_gotFocusEvent;
|
|
161
192
|
};
|
|
162
193
|
|
|
163
194
|
// Run fn on all nodes of the component view tree starting from this one until fn returns true
|
|
@@ -132,6 +132,12 @@ CompositionRootView::CompositionRootView(const winrt::Microsoft::UI::Composition
|
|
|
132
132
|
#endif
|
|
133
133
|
|
|
134
134
|
CompositionRootView::~CompositionRootView() noexcept {
|
|
135
|
+
#ifdef USE_WINUI3
|
|
136
|
+
if (m_island && m_island.IsConnected()) {
|
|
137
|
+
m_island.AutomationProviderRequested(m_islandAutomationProviderRequestedToken);
|
|
138
|
+
}
|
|
139
|
+
#endif
|
|
140
|
+
|
|
135
141
|
if (m_uiDispatcher) {
|
|
136
142
|
assert(m_uiDispatcher.HasThreadAccess());
|
|
137
143
|
UninitRootView();
|
|
@@ -193,7 +199,7 @@ void CompositionRootView::RemoveRenderedVisual(
|
|
|
193
199
|
|
|
194
200
|
bool CompositionRootView::TrySetFocus() noexcept {
|
|
195
201
|
#ifdef USE_WINUI3
|
|
196
|
-
if (m_island) {
|
|
202
|
+
if (m_island && m_island.IsConnected()) {
|
|
197
203
|
auto focusController = winrt::Microsoft::UI::Input::InputFocusController::GetForIsland(m_island);
|
|
198
204
|
return focusController.TrySetFocus();
|
|
199
205
|
}
|
|
@@ -655,20 +661,29 @@ winrt::Microsoft::UI::Content::ContentIsland CompositionRootView::Island() noexc
|
|
|
655
661
|
rootVisual));
|
|
656
662
|
m_island = winrt::Microsoft::UI::Content::ContentIsland::Create(rootVisual);
|
|
657
663
|
|
|
658
|
-
|
|
659
|
-
|
|
664
|
+
// ContentIsland does not support weak_ref, so we cannot use auto_revoke for these events
|
|
665
|
+
m_islandAutomationProviderRequestedToken = m_island.AutomationProviderRequested(
|
|
666
|
+
[weakThis = get_weak()](
|
|
660
667
|
winrt::Microsoft::UI::Content::ContentIsland const &,
|
|
661
668
|
winrt::Microsoft::UI::Content::ContentIslandAutomationProviderRequestedEventArgs const &args) {
|
|
662
|
-
auto
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
pRootProvider
|
|
669
|
+
if (auto pThis = weakThis.get()) {
|
|
670
|
+
auto provider = pThis->GetUiaProvider();
|
|
671
|
+
auto pRootProvider =
|
|
672
|
+
static_cast<winrt::Microsoft::ReactNative::implementation::CompositionRootAutomationProvider *>(
|
|
673
|
+
provider.as<IRawElementProviderSimple>().get());
|
|
674
|
+
if (pRootProvider != nullptr) {
|
|
675
|
+
pRootProvider->SetIsland(pThis->m_island);
|
|
676
|
+
}
|
|
677
|
+
args.AutomationProvider(std::move(provider));
|
|
678
|
+
args.Handled(true);
|
|
668
679
|
}
|
|
669
|
-
args.AutomationProvider(std::move(provider));
|
|
670
|
-
args.Handled(true);
|
|
671
680
|
});
|
|
681
|
+
|
|
682
|
+
m_islandFrameworkClosedToken = m_island.FrameworkClosed([weakThis = get_weak()]() {
|
|
683
|
+
if (auto pThis = weakThis.get()) {
|
|
684
|
+
pThis->m_island = nullptr;
|
|
685
|
+
}
|
|
686
|
+
});
|
|
672
687
|
}
|
|
673
688
|
return m_island;
|
|
674
689
|
}
|
|
@@ -121,6 +121,8 @@ struct CompositionRootView
|
|
|
121
121
|
#ifdef USE_WINUI3
|
|
122
122
|
winrt::Microsoft::UI::Composition::Compositor m_compositor{nullptr};
|
|
123
123
|
winrt::Microsoft::UI::Content::ContentIsland m_island{nullptr};
|
|
124
|
+
winrt::event_token m_islandFrameworkClosedToken;
|
|
125
|
+
winrt::event_token m_islandAutomationProviderRequestedToken;
|
|
124
126
|
#endif
|
|
125
127
|
|
|
126
128
|
HWND m_hwnd{0};
|
|
@@ -121,6 +121,10 @@ winrt::Microsoft::ReactNative::Composition::Theme ComponentView::Theme() const n
|
|
|
121
121
|
return theme()->get_strong().as<winrt::Microsoft::ReactNative::Composition::Theme>();
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
+
winrt::Microsoft::ReactNative::Composition::RootComponentView ComponentView::Root() noexcept {
|
|
125
|
+
return *rootComponentView();
|
|
126
|
+
}
|
|
127
|
+
|
|
124
128
|
winrt::Microsoft::UI::Composition::Compositor ComponentView::Compositor() const noexcept {
|
|
125
129
|
return winrt::Microsoft::ReactNative::Composition::Experimental::MicrosoftCompositionContextHelper::InnerCompositor(
|
|
126
130
|
m_compContext);
|
|
@@ -179,32 +183,38 @@ void ComponentView::FinalizeUpdates(winrt::Microsoft::ReactNative::ComponentView
|
|
|
179
183
|
base_type::FinalizeUpdates(updateMask);
|
|
180
184
|
}
|
|
181
185
|
|
|
182
|
-
void ComponentView::
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
186
|
+
void ComponentView::onLostFocus(
|
|
187
|
+
const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept {
|
|
188
|
+
if (args.OriginalSource() == Tag()) {
|
|
189
|
+
m_eventEmitter->onBlur();
|
|
190
|
+
showFocusVisual(false);
|
|
191
|
+
if (m_uiaProvider) {
|
|
192
|
+
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
|
|
193
|
+
m_uiaProvider, UIA_HasKeyboardFocusPropertyId, true, false);
|
|
194
|
+
}
|
|
188
195
|
}
|
|
189
|
-
base_type::
|
|
196
|
+
base_type::onLostFocus(args);
|
|
190
197
|
}
|
|
191
198
|
|
|
192
|
-
void ComponentView::
|
|
193
|
-
|
|
194
|
-
if (
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
if (
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
199
|
+
void ComponentView::onGotFocus(
|
|
200
|
+
const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept {
|
|
201
|
+
if (args.OriginalSource() == Tag()) {
|
|
202
|
+
m_eventEmitter->onFocus();
|
|
203
|
+
if (m_enableFocusVisual) {
|
|
204
|
+
showFocusVisual(true);
|
|
205
|
+
}
|
|
206
|
+
if (m_uiaProvider) {
|
|
207
|
+
auto spProviderSimple = m_uiaProvider.try_as<IRawElementProviderSimple>();
|
|
208
|
+
if (spProviderSimple != nullptr) {
|
|
209
|
+
winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
|
|
210
|
+
m_uiaProvider, UIA_HasKeyboardFocusPropertyId, false, true);
|
|
211
|
+
UiaRaiseAutomationEvent(spProviderSimple.get(), UIA_AutomationFocusChangedEventId);
|
|
212
|
+
}
|
|
203
213
|
}
|
|
204
|
-
}
|
|
205
214
|
|
|
206
|
-
|
|
207
|
-
|
|
215
|
+
StartBringIntoView({});
|
|
216
|
+
}
|
|
217
|
+
base_type::onGotFocus(args);
|
|
208
218
|
}
|
|
209
219
|
|
|
210
220
|
void ComponentView::StartBringIntoView(
|
|
@@ -234,13 +244,13 @@ void ComponentView::HandleCommand(
|
|
|
234
244
|
const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept {
|
|
235
245
|
if (commandName == L"focus") {
|
|
236
246
|
if (auto root = rootComponentView()) {
|
|
237
|
-
root->
|
|
247
|
+
root->TrySetFocusedComponent(*get_strong());
|
|
238
248
|
}
|
|
239
249
|
return;
|
|
240
250
|
}
|
|
241
251
|
if (commandName == L"blur") {
|
|
242
252
|
if (auto root = rootComponentView()) {
|
|
243
|
-
root->
|
|
253
|
+
root->TrySetFocusedComponent(nullptr); // Todo store this component as previously focused element
|
|
244
254
|
}
|
|
245
255
|
return;
|
|
246
256
|
}
|
|
@@ -69,11 +69,14 @@ struct ComponentView
|
|
|
69
69
|
assert(false);
|
|
70
70
|
return emptyProps;
|
|
71
71
|
};
|
|
72
|
+
|
|
73
|
+
winrt::Microsoft::ReactNative::Composition::RootComponentView Root() noexcept;
|
|
74
|
+
|
|
72
75
|
void Theme(const winrt::Microsoft::ReactNative::Composition::Theme &theme) noexcept;
|
|
73
76
|
winrt::Microsoft::ReactNative::Composition::Theme Theme() const noexcept;
|
|
74
77
|
void onThemeChanged() noexcept override;
|
|
75
|
-
void
|
|
76
|
-
void
|
|
78
|
+
void onLostFocus(const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept override;
|
|
79
|
+
void onGotFocus(const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept override;
|
|
77
80
|
bool CapturePointer(const winrt::Microsoft::ReactNative::Composition::Input::Pointer &pointer) noexcept;
|
|
78
81
|
void ReleasePointerCapture(const winrt::Microsoft::ReactNative::Composition::Input::Pointer &pointer) noexcept;
|
|
79
82
|
|
|
@@ -189,6 +192,7 @@ struct ViewComponentView : public ViewComponentViewT<ViewComponentView, Componen
|
|
|
189
192
|
facebook::react::LayoutMetrics const &layoutMetrics,
|
|
190
193
|
facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept override;
|
|
191
194
|
void prepareForRecycle() noexcept override;
|
|
195
|
+
bool TryFocus() noexcept;
|
|
192
196
|
bool focusable() const noexcept override;
|
|
193
197
|
void OnKeyDown(
|
|
194
198
|
const winrt::Microsoft::ReactNative::Composition::Input::KeyboardSource &source,
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#include "pch.h"
|
|
5
|
+
#include "FocusManager.h"
|
|
6
|
+
#include "Composition.FocusManager.g.cpp"
|
|
7
|
+
#include <Fabric/FabricUIManagerModule.h>
|
|
8
|
+
|
|
9
|
+
namespace winrt::Microsoft::ReactNative::implementation {
|
|
10
|
+
|
|
11
|
+
LostFocusEventArgs::LostFocusEventArgs(const winrt::Microsoft::ReactNative::ComponentView &originalSource)
|
|
12
|
+
: m_originalSource(originalSource ? originalSource.Tag() : -1) {}
|
|
13
|
+
int32_t LostFocusEventArgs::OriginalSource() noexcept {
|
|
14
|
+
return m_originalSource;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
GotFocusEventArgs::GotFocusEventArgs(const winrt::Microsoft::ReactNative::ComponentView &originalSource)
|
|
18
|
+
: m_originalSource(originalSource ? originalSource.Tag() : -1) {}
|
|
19
|
+
int32_t GotFocusEventArgs::OriginalSource() noexcept {
|
|
20
|
+
return m_originalSource;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
LosingFocusEventArgs::LosingFocusEventArgs(
|
|
24
|
+
const winrt::Microsoft::ReactNative::ComponentView &originalSource,
|
|
25
|
+
const winrt::Microsoft::ReactNative::ComponentView &oldFocusedComponent,
|
|
26
|
+
const winrt::Microsoft::ReactNative::ComponentView &newFocusedComponent)
|
|
27
|
+
: m_originalSource(originalSource ? originalSource.Tag() : -1),
|
|
28
|
+
m_old(oldFocusedComponent),
|
|
29
|
+
m_new(newFocusedComponent) {}
|
|
30
|
+
|
|
31
|
+
int32_t LosingFocusEventArgs::OriginalSource() noexcept {
|
|
32
|
+
return m_originalSource;
|
|
33
|
+
}
|
|
34
|
+
winrt::Microsoft::ReactNative::ComponentView LosingFocusEventArgs::NewFocusedComponent() noexcept {
|
|
35
|
+
return m_new;
|
|
36
|
+
}
|
|
37
|
+
winrt::Microsoft::ReactNative::ComponentView LosingFocusEventArgs::OldFocusedComponent() noexcept {
|
|
38
|
+
return m_old;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
void LosingFocusEventArgs::TryCancel() noexcept {
|
|
42
|
+
m_new = m_old;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
void LosingFocusEventArgs::TrySetNewFocusedComponent(
|
|
46
|
+
const winrt::Microsoft::ReactNative::ComponentView &newFocusedComponent) noexcept {
|
|
47
|
+
auto selfView = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(newFocusedComponent);
|
|
48
|
+
if (selfView->focusable()) {
|
|
49
|
+
m_new = newFocusedComponent;
|
|
50
|
+
} else {
|
|
51
|
+
auto target =
|
|
52
|
+
winrt::Microsoft::ReactNative::Composition::FocusManager::FindFirstFocusableElement(newFocusedComponent);
|
|
53
|
+
if (!target)
|
|
54
|
+
return;
|
|
55
|
+
m_new = target;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
GettingFocusEventArgs::GettingFocusEventArgs(
|
|
60
|
+
const winrt::Microsoft::ReactNative::ComponentView &originalSource,
|
|
61
|
+
const winrt::Microsoft::ReactNative::ComponentView &oldFocusedComponent,
|
|
62
|
+
const winrt::Microsoft::ReactNative::ComponentView &newFocusedComponent)
|
|
63
|
+
: m_originalSource(originalSource ? originalSource.Tag() : -1),
|
|
64
|
+
m_old(oldFocusedComponent),
|
|
65
|
+
m_new(newFocusedComponent) {}
|
|
66
|
+
|
|
67
|
+
int32_t GettingFocusEventArgs::OriginalSource() noexcept {
|
|
68
|
+
return m_originalSource;
|
|
69
|
+
}
|
|
70
|
+
winrt::Microsoft::ReactNative::ComponentView GettingFocusEventArgs::NewFocusedComponent() noexcept {
|
|
71
|
+
return m_new;
|
|
72
|
+
}
|
|
73
|
+
winrt::Microsoft::ReactNative::ComponentView GettingFocusEventArgs::OldFocusedComponent() noexcept {
|
|
74
|
+
return m_old;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
void GettingFocusEventArgs::TryCancel() noexcept {
|
|
78
|
+
m_new = m_old;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
void GettingFocusEventArgs::TrySetNewFocusedComponent(
|
|
82
|
+
const winrt::Microsoft::ReactNative::ComponentView &newFocusedComponent) noexcept {
|
|
83
|
+
auto selfView = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(newFocusedComponent);
|
|
84
|
+
if (selfView->focusable()) {
|
|
85
|
+
m_new = newFocusedComponent;
|
|
86
|
+
} else {
|
|
87
|
+
auto target =
|
|
88
|
+
winrt::Microsoft::ReactNative::Composition::FocusManager::FindFirstFocusableElement(newFocusedComponent);
|
|
89
|
+
if (!target)
|
|
90
|
+
return;
|
|
91
|
+
m_new = target;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
} // namespace winrt::Microsoft::ReactNative::implementation
|
|
96
|
+
|
|
97
|
+
namespace winrt::Microsoft::ReactNative::Composition::implementation {
|
|
98
|
+
|
|
99
|
+
winrt::Microsoft::ReactNative::implementation::ComponentView *NavigateFocusHelper(
|
|
100
|
+
winrt::Microsoft::ReactNative::implementation::ComponentView &view,
|
|
101
|
+
winrt::Microsoft::ReactNative::FocusNavigationReason reason) {
|
|
102
|
+
if (reason == winrt::Microsoft::ReactNative::FocusNavigationReason::First) {
|
|
103
|
+
if (view.focusable()) {
|
|
104
|
+
return &view;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
winrt::Microsoft::ReactNative::implementation::ComponentView *toFocus = nullptr;
|
|
108
|
+
|
|
109
|
+
Mso::Functor<bool(::winrt::Microsoft::ReactNative::implementation::ComponentView & v)> fn =
|
|
110
|
+
[reason, &toFocus](::winrt::Microsoft::ReactNative::implementation::ComponentView &v) noexcept
|
|
111
|
+
-> bool { return (toFocus = NavigateFocusHelper(v, reason)); };
|
|
112
|
+
|
|
113
|
+
if (view.runOnChildren(reason == winrt::Microsoft::ReactNative::FocusNavigationReason::First, fn)) {
|
|
114
|
+
return toFocus;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (reason == winrt::Microsoft::ReactNative::FocusNavigationReason::Last) {
|
|
118
|
+
if (view.focusable()) {
|
|
119
|
+
return &view;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return nullptr;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
winrt::Microsoft::ReactNative::ComponentView FocusManager::FindFirstFocusableElement(
|
|
127
|
+
const winrt::Microsoft::ReactNative::ComponentView &searchScope) noexcept {
|
|
128
|
+
auto selfSearchScope = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(searchScope);
|
|
129
|
+
auto view = NavigateFocusHelper(*selfSearchScope, winrt::Microsoft::ReactNative::FocusNavigationReason::First);
|
|
130
|
+
if (view) {
|
|
131
|
+
winrt::Microsoft::ReactNative::ComponentView component{nullptr};
|
|
132
|
+
winrt::check_hresult(view->QueryInterface(
|
|
133
|
+
winrt::guid_of<winrt::Microsoft::ReactNative::ComponentView>(), winrt::put_abi(component)));
|
|
134
|
+
return *view;
|
|
135
|
+
}
|
|
136
|
+
return nullptr;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
winrt::Microsoft::ReactNative::ComponentView FocusManager::FindLastFocusableElement(
|
|
140
|
+
const winrt::Microsoft::ReactNative::ComponentView &searchScope) noexcept {
|
|
141
|
+
auto selfSearchScope = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(searchScope);
|
|
142
|
+
auto view = NavigateFocusHelper(*selfSearchScope, winrt::Microsoft::ReactNative::FocusNavigationReason::Last);
|
|
143
|
+
if (view) {
|
|
144
|
+
winrt::Microsoft::ReactNative::ComponentView component{nullptr};
|
|
145
|
+
winrt::check_hresult(view->QueryInterface(
|
|
146
|
+
winrt::guid_of<winrt::Microsoft::ReactNative::ComponentView>(), winrt::put_abi(component)));
|
|
147
|
+
return *view;
|
|
148
|
+
}
|
|
149
|
+
return nullptr;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
} // namespace winrt::Microsoft::ReactNative::Composition::implementation
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#pragma once
|
|
5
|
+
#include "Composition.FocusManager.g.h"
|
|
6
|
+
#include "GettingFocusEventArgs.g.h"
|
|
7
|
+
#include "LosingFocusEventArgs.g.h"
|
|
8
|
+
#include <winrt/Microsoft.ReactNative.Composition.Experimental.h>
|
|
9
|
+
#include <winrt/Microsoft.ReactNative.Composition.Input.h>
|
|
10
|
+
|
|
11
|
+
namespace winrt::Microsoft::ReactNative::implementation {
|
|
12
|
+
|
|
13
|
+
struct LostFocusEventArgs
|
|
14
|
+
: winrt::implements<LostFocusEventArgs, winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs> {
|
|
15
|
+
LostFocusEventArgs(const winrt::Microsoft::ReactNative::ComponentView &originalSource);
|
|
16
|
+
int32_t OriginalSource() noexcept;
|
|
17
|
+
|
|
18
|
+
private:
|
|
19
|
+
const int32_t m_originalSource;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
struct GotFocusEventArgs
|
|
23
|
+
: winrt::implements<GotFocusEventArgs, winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs> {
|
|
24
|
+
GotFocusEventArgs(const winrt::Microsoft::ReactNative::ComponentView &originalSource);
|
|
25
|
+
int32_t OriginalSource() noexcept;
|
|
26
|
+
|
|
27
|
+
private:
|
|
28
|
+
const int32_t m_originalSource;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
struct LosingFocusEventArgs
|
|
32
|
+
: winrt::Microsoft::ReactNative::implementation::LosingFocusEventArgsT<LosingFocusEventArgs> {
|
|
33
|
+
LosingFocusEventArgs(
|
|
34
|
+
const winrt::Microsoft::ReactNative::ComponentView &originalSource,
|
|
35
|
+
const winrt::Microsoft::ReactNative::ComponentView &oldFocusedComponent,
|
|
36
|
+
const winrt::Microsoft::ReactNative::ComponentView &newFocusedComponent);
|
|
37
|
+
int32_t OriginalSource() noexcept;
|
|
38
|
+
winrt::Microsoft::ReactNative::ComponentView NewFocusedComponent() noexcept;
|
|
39
|
+
winrt::Microsoft::ReactNative::ComponentView OldFocusedComponent() noexcept;
|
|
40
|
+
|
|
41
|
+
void TryCancel() noexcept;
|
|
42
|
+
void TrySetNewFocusedComponent(const winrt::Microsoft::ReactNative::ComponentView &newFocusedComponent) noexcept;
|
|
43
|
+
|
|
44
|
+
private:
|
|
45
|
+
const int32_t m_originalSource;
|
|
46
|
+
winrt::Microsoft::ReactNative::ComponentView m_old{nullptr};
|
|
47
|
+
winrt::Microsoft::ReactNative::ComponentView m_new{nullptr};
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
struct GettingFocusEventArgs
|
|
51
|
+
: winrt::Microsoft::ReactNative::implementation::GettingFocusEventArgsT<GettingFocusEventArgs> {
|
|
52
|
+
GettingFocusEventArgs(
|
|
53
|
+
const winrt::Microsoft::ReactNative::ComponentView &originalSource,
|
|
54
|
+
const winrt::Microsoft::ReactNative::ComponentView &oldFocusedComponent,
|
|
55
|
+
const winrt::Microsoft::ReactNative::ComponentView &newFocusedComponent);
|
|
56
|
+
int32_t OriginalSource() noexcept;
|
|
57
|
+
winrt::Microsoft::ReactNative::ComponentView NewFocusedComponent() noexcept;
|
|
58
|
+
winrt::Microsoft::ReactNative::ComponentView OldFocusedComponent() noexcept;
|
|
59
|
+
|
|
60
|
+
void TryCancel() noexcept;
|
|
61
|
+
void TrySetNewFocusedComponent(const winrt::Microsoft::ReactNative::ComponentView &newFocusedComponent) noexcept;
|
|
62
|
+
|
|
63
|
+
private:
|
|
64
|
+
const int32_t m_originalSource;
|
|
65
|
+
winrt::Microsoft::ReactNative::ComponentView m_old{nullptr};
|
|
66
|
+
winrt::Microsoft::ReactNative::ComponentView m_new{nullptr};
|
|
67
|
+
};
|
|
68
|
+
} // namespace winrt::Microsoft::ReactNative::implementation
|
|
69
|
+
|
|
70
|
+
namespace winrt::Microsoft::ReactNative::Composition::implementation {
|
|
71
|
+
|
|
72
|
+
struct FocusManager : FocusManagerT<FocusManager> {
|
|
73
|
+
FocusManager() = default;
|
|
74
|
+
|
|
75
|
+
static winrt::Microsoft::ReactNative::ComponentView FindFirstFocusableElement(
|
|
76
|
+
const winrt::Microsoft::ReactNative::ComponentView &searchScope) noexcept;
|
|
77
|
+
static winrt::Microsoft::ReactNative::ComponentView FindLastFocusableElement(
|
|
78
|
+
const winrt::Microsoft::ReactNative::ComponentView &searchScope) noexcept;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
} // namespace winrt::Microsoft::ReactNative::Composition::implementation
|
|
82
|
+
|
|
83
|
+
namespace winrt::Microsoft::ReactNative::Composition::factory_implementation {
|
|
84
|
+
struct FocusManager : FocusManagerT<FocusManager, implementation::FocusManager> {};
|
|
85
|
+
} // namespace winrt::Microsoft::ReactNative::Composition::factory_implementation
|
|
@@ -45,7 +45,7 @@ RootComponentView *RootComponentView::rootComponentView() noexcept {
|
|
|
45
45
|
return this;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
winrt::Microsoft::ReactNative::ComponentView
|
|
48
|
+
winrt::Microsoft::ReactNative::ComponentView RootComponentView::GetFocusedComponent() noexcept {
|
|
49
49
|
return m_focusedComponent;
|
|
50
50
|
}
|
|
51
51
|
void RootComponentView::SetFocusedComponent(const winrt::Microsoft::ReactNative::ComponentView &value) noexcept {
|
|
@@ -53,69 +53,69 @@ void RootComponentView::SetFocusedComponent(const winrt::Microsoft::ReactNative:
|
|
|
53
53
|
return;
|
|
54
54
|
|
|
55
55
|
if (m_focusedComponent) {
|
|
56
|
-
winrt::
|
|
56
|
+
auto args = winrt::make<winrt::Microsoft::ReactNative::implementation::LostFocusEventArgs>(m_focusedComponent);
|
|
57
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(m_focusedComponent)
|
|
58
|
+
->onLostFocus(args);
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
if (value) {
|
|
60
62
|
if (auto rootView = m_wkRootView.get()) {
|
|
61
63
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::CompositionRootView>(rootView)->TrySetFocus();
|
|
62
64
|
}
|
|
63
|
-
winrt::
|
|
65
|
+
auto args = winrt::make<winrt::Microsoft::ReactNative::implementation::GotFocusEventArgs>(value);
|
|
66
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(value)->onGotFocus(args);
|
|
64
67
|
}
|
|
65
68
|
|
|
66
69
|
m_focusedComponent = value;
|
|
67
70
|
}
|
|
68
71
|
|
|
69
|
-
winrt::Microsoft::ReactNative::implementation::ComponentView *NavigateFocusHelper(
|
|
70
|
-
winrt::Microsoft::ReactNative::implementation::ComponentView &view,
|
|
71
|
-
winrt::Microsoft::ReactNative::FocusNavigationReason reason) {
|
|
72
|
-
if (reason == winrt::Microsoft::ReactNative::FocusNavigationReason::First) {
|
|
73
|
-
if (view.focusable()) {
|
|
74
|
-
return &view;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
winrt::Microsoft::ReactNative::implementation::ComponentView *toFocus = nullptr;
|
|
78
|
-
|
|
79
|
-
Mso::Functor<bool(::winrt::Microsoft::ReactNative::implementation::ComponentView & v)> fn =
|
|
80
|
-
[reason, &toFocus](::winrt::Microsoft::ReactNative::implementation::ComponentView &v) noexcept
|
|
81
|
-
-> bool { return (toFocus = NavigateFocusHelper(v, reason)); };
|
|
82
|
-
|
|
83
|
-
if (view.runOnChildren(reason == winrt::Microsoft::ReactNative::FocusNavigationReason::First, fn)) {
|
|
84
|
-
return toFocus;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if (reason == winrt::Microsoft::ReactNative::FocusNavigationReason::Last) {
|
|
88
|
-
if (view.focusable()) {
|
|
89
|
-
return &view;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return nullptr;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
72
|
bool RootComponentView::NavigateFocus(const winrt::Microsoft::ReactNative::FocusNavigationRequest &request) noexcept {
|
|
97
73
|
if (request.Reason() == winrt::Microsoft::ReactNative::FocusNavigationReason::Restore) {
|
|
98
74
|
// No-op for now
|
|
99
75
|
return m_focusedComponent != nullptr;
|
|
100
76
|
}
|
|
101
77
|
|
|
102
|
-
auto view =
|
|
78
|
+
auto view = (request.Reason() == winrt::Microsoft::ReactNative::FocusNavigationReason::First)
|
|
79
|
+
? FocusManager::FindFirstFocusableElement(*this)
|
|
80
|
+
: FocusManager::FindLastFocusableElement(*this);
|
|
103
81
|
if (view) {
|
|
104
|
-
|
|
105
|
-
winrt::check_hresult(view->QueryInterface(
|
|
106
|
-
winrt::guid_of<winrt::Microsoft::ReactNative::ComponentView>(), winrt::put_abi(component)));
|
|
107
|
-
SetFocusedComponent(component);
|
|
82
|
+
TrySetFocusedComponent(view);
|
|
108
83
|
}
|
|
109
84
|
return view != nullptr;
|
|
110
85
|
}
|
|
111
86
|
|
|
112
87
|
bool RootComponentView::TrySetFocusedComponent(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
|
|
113
|
-
auto
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
88
|
+
auto target = view;
|
|
89
|
+
auto selfView = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(target);
|
|
90
|
+
if (selfView && !selfView->focusable()) {
|
|
91
|
+
target = FocusManager::FindFirstFocusableElement(target);
|
|
92
|
+
if (!target)
|
|
93
|
+
return false;
|
|
94
|
+
selfView = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(target);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (selfView && selfView->rootComponentView() != this)
|
|
98
|
+
return false;
|
|
99
|
+
|
|
100
|
+
auto losingFocusArgs = winrt::make<winrt::Microsoft::ReactNative::implementation::LosingFocusEventArgs>(
|
|
101
|
+
target, m_focusedComponent, target);
|
|
102
|
+
if (m_focusedComponent) {
|
|
103
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(m_focusedComponent)
|
|
104
|
+
->onLosingFocus(losingFocusArgs);
|
|
117
105
|
}
|
|
118
|
-
|
|
106
|
+
|
|
107
|
+
if (losingFocusArgs.NewFocusedComponent()) {
|
|
108
|
+
auto gettingFocusArgs = winrt::make<winrt::Microsoft::ReactNative::implementation::GettingFocusEventArgs>(
|
|
109
|
+
target, m_focusedComponent, losingFocusArgs.NewFocusedComponent());
|
|
110
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(losingFocusArgs.NewFocusedComponent())
|
|
111
|
+
->onGettingFocus(gettingFocusArgs);
|
|
112
|
+
|
|
113
|
+
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(losingFocusArgs.NewFocusedComponent())
|
|
114
|
+
->rootComponentView()
|
|
115
|
+
->SetFocusedComponent(gettingFocusArgs.NewFocusedComponent());
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return true;
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
bool RootComponentView::TryMoveFocus(bool next) noexcept {
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
#include <Microsoft.ReactNative.Cxx/ReactContext.h>
|
|
9
9
|
|
|
10
10
|
#include "CompositionViewComponentView.h"
|
|
11
|
+
#include "FocusManager.h"
|
|
11
12
|
#include "Theme.h"
|
|
12
13
|
|
|
13
14
|
#include "Composition.RootComponentView.g.h"
|
|
@@ -25,7 +26,7 @@ struct RootComponentView : RootComponentViewT<RootComponentView, ViewComponentVi
|
|
|
25
26
|
facebook::react::Tag tag,
|
|
26
27
|
winrt::Microsoft::ReactNative::ReactContext const &reactContext) noexcept;
|
|
27
28
|
|
|
28
|
-
winrt::Microsoft::ReactNative::ComponentView
|
|
29
|
+
winrt::Microsoft::ReactNative::ComponentView GetFocusedComponent() noexcept;
|
|
29
30
|
void SetFocusedComponent(const winrt::Microsoft::ReactNative::ComponentView &value) noexcept;
|
|
30
31
|
bool TrySetFocusedComponent(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept;
|
|
31
32
|
|
|
@@ -51,6 +52,9 @@ struct RootComponentView : RootComponentViewT<RootComponentView, ViewComponentVi
|
|
|
51
52
|
|
|
52
53
|
virtual ~RootComponentView();
|
|
53
54
|
|
|
55
|
+
winrt::Microsoft::ReactNative::ComponentView FindFirstFocusableElement() noexcept;
|
|
56
|
+
winrt::Microsoft::ReactNative::ComponentView FindLastFocusableElement() noexcept;
|
|
57
|
+
|
|
54
58
|
private:
|
|
55
59
|
// should this be a ReactTaggedView? - It shouldn't actually matter since if the view is going away it should always
|
|
56
60
|
// be clearing its focus But being a reactTaggedView might make it easier to identify cases where that isn't
|
package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp
CHANGED
|
@@ -224,7 +224,7 @@ struct CompTextHost : public winrt::implements<CompTextHost, ITextHost> {
|
|
|
224
224
|
winrt::Microsoft::ReactNative::ComponentView view{nullptr};
|
|
225
225
|
winrt::check_hresult(
|
|
226
226
|
m_outer->QueryInterface(winrt::guid_of<winrt::Microsoft::ReactNative::ComponentView>(), winrt::put_abi(view)));
|
|
227
|
-
m_outer->rootComponentView()->
|
|
227
|
+
m_outer->rootComponentView()->TrySetFocusedComponent(view);
|
|
228
228
|
// assert(false);
|
|
229
229
|
// TODO focus
|
|
230
230
|
}
|
|
@@ -929,8 +929,9 @@ void WindowsTextInputComponentView::UnmountChildComponentView(
|
|
|
929
929
|
base_type::UnmountChildComponentView(childComponentView, index);
|
|
930
930
|
}
|
|
931
931
|
|
|
932
|
-
void WindowsTextInputComponentView::
|
|
933
|
-
|
|
932
|
+
void WindowsTextInputComponentView::onLostFocus(
|
|
933
|
+
const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept {
|
|
934
|
+
Super::onLostFocus(args);
|
|
934
935
|
if (m_textServices) {
|
|
935
936
|
LRESULT lresult;
|
|
936
937
|
DrawBlock db(*this);
|
|
@@ -939,8 +940,9 @@ void WindowsTextInputComponentView::onFocusLost() noexcept {
|
|
|
939
940
|
m_caretVisual.IsVisible(false);
|
|
940
941
|
}
|
|
941
942
|
|
|
942
|
-
void WindowsTextInputComponentView::
|
|
943
|
-
|
|
943
|
+
void WindowsTextInputComponentView::onGotFocus(
|
|
944
|
+
const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept {
|
|
945
|
+
Super::onGotFocus(args);
|
|
944
946
|
if (m_textServices) {
|
|
945
947
|
LRESULT lresult;
|
|
946
948
|
DrawBlock db(*this);
|
|
@@ -49,8 +49,8 @@ struct WindowsTextInputComponentView
|
|
|
49
49
|
void HandleCommand(winrt::hstring commandName, const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept
|
|
50
50
|
override;
|
|
51
51
|
void OnRenderingDeviceLost() noexcept override;
|
|
52
|
-
void
|
|
53
|
-
void
|
|
52
|
+
void onLostFocus(const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept override;
|
|
53
|
+
void onGotFocus(const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept override;
|
|
54
54
|
std::string DefaultControlType() const noexcept override;
|
|
55
55
|
std::string DefaultAccessibleName() const noexcept override;
|
|
56
56
|
std::string DefaultHelpText() const noexcept override;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
import "ComponentView.idl";
|
|
5
|
+
#include "DocString.h"
|
|
6
|
+
|
|
7
|
+
namespace Microsoft.ReactNative.Composition
|
|
8
|
+
{
|
|
9
|
+
|
|
10
|
+
[default_interface]
|
|
11
|
+
[webhosthidden]
|
|
12
|
+
[experimental]
|
|
13
|
+
runtimeclass FocusManager
|
|
14
|
+
{
|
|
15
|
+
DOC_STRING("Retrieves the first component that can receive focus based on the specified scope.")
|
|
16
|
+
static Microsoft.ReactNative.ComponentView FindFirstFocusableElement(Microsoft.ReactNative.ComponentView searchScope);
|
|
17
|
+
|
|
18
|
+
DOC_STRING("Retrieves the last component that can receive focus based on the specified scope.")
|
|
19
|
+
static Microsoft.ReactNative.ComponentView FindLastFocusableElement(Microsoft.ReactNative.ComponentView searchScope);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
} // namespace Microsoft.ReactNative.Composition
|
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
-->
|
|
11
11
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
12
12
|
<PropertyGroup>
|
|
13
|
-
<ReactNativeWindowsVersion>0.74.
|
|
13
|
+
<ReactNativeWindowsVersion>0.74.6</ReactNativeWindowsVersion>
|
|
14
14
|
<ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
|
|
15
15
|
<ReactNativeWindowsMinor>74</ReactNativeWindowsMinor>
|
|
16
|
-
<ReactNativeWindowsPatch>
|
|
16
|
+
<ReactNativeWindowsPatch>6</ReactNativeWindowsPatch>
|
|
17
17
|
<ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
|
|
18
|
-
<ReactNativeWindowsCommitId>
|
|
18
|
+
<ReactNativeWindowsCommitId>c93d7314ed1689c74689990641fbf3c1a54aa8cc</ReactNativeWindowsCommitId>
|
|
19
19
|
</PropertyGroup>
|
|
20
20
|
</Project>
|
package/Shared/Shared.vcxitems
CHANGED
|
@@ -84,6 +84,11 @@
|
|
|
84
84
|
<DependentUpon>$(ReactNativeWindowsDir)Microsoft.ReactNative\CompositionUIService.idl</DependentUpon>
|
|
85
85
|
<SubType>Code</SubType>
|
|
86
86
|
</ClCompile>
|
|
87
|
+
<ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\Composition\FocusManager.cpp">
|
|
88
|
+
<ExcludedFromBuild Condition="'$(UseFabric)' != 'true'">true</ExcludedFromBuild>
|
|
89
|
+
<DependentUpon>$(ReactNativeWindowsDir)Microsoft.ReactNative\FocusManager.idl</DependentUpon>
|
|
90
|
+
<SubType>Code</SubType>
|
|
91
|
+
</ClCompile>
|
|
87
92
|
<ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\Composition\UriImageManager.cpp">
|
|
88
93
|
<ExcludedFromBuild Condition="'$(UseFabric)' != 'true'">true</ExcludedFromBuild>
|
|
89
94
|
<DependentUpon>$(ReactNativeWindowsDir)Microsoft.ReactNative\UriImageManager.idl</DependentUpon>
|
|
@@ -635,6 +640,7 @@
|
|
|
635
640
|
<Midl Condition="'$(UseFabric)' == 'true' OR '$(IncludeFabricInterface)' == 'true'" Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\ComponentView.idl" />
|
|
636
641
|
<Midl Condition="'$(UseFabric)' == 'true' OR '$(IncludeFabricInterface)' == 'true'" Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\Composition.Input.idl" />
|
|
637
642
|
<Midl Condition="'$(UseFabric)' == 'true' OR '$(IncludeFabricInterface)' == 'true'" Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\CompositionComponentView.idl" />
|
|
643
|
+
<Midl Condition="'$(UseFabric)' == 'true' OR '$(IncludeFabricInterface)' == 'true'" Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\FocusManager.idl" />
|
|
638
644
|
<Midl Condition="'$(UseFabric)' == 'true' OR '$(IncludeFabricInterface)' == 'true'" Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\CompositionContext.idl" />
|
|
639
645
|
<Midl Condition="'$(UseFabric)' == 'true' OR '$(IncludeFabricInterface)' == 'true'" Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\CompositionHwndHost.idl" />
|
|
640
646
|
<Midl Condition="'$(UseFabric)' == 'true' OR '$(IncludeFabricInterface)' == 'true'" Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\CompositionRootView.idl" />
|