react-native-windows 0.81.4 → 0.81.5
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/Core/ReactNativeVersion.js +1 -1
- package/Libraries/NativeComponent/ViewConfigIgnore.windows.js +45 -0
- package/Libraries/Renderer/implementations/ReactFabric-dev.js +38 -35
- package/Libraries/Renderer/implementations/ReactFabric-prod.js +51 -22
- package/Libraries/Renderer/implementations/ReactFabric-profiling.js +54 -24
- package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +36 -33
- package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +5 -5
- package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +5 -5
- package/Libraries/Renderer/shims/ReactNativeTypes.js +23 -11
- package/Libraries/Renderer/shims/ReactNativeTypes.windows.js +23 -12
- package/Microsoft.ReactNative/ComponentView.idl +2 -0
- package/Microsoft.ReactNative/Composition.Input.idl +7 -0
- package/Microsoft.ReactNative/CompositionComponentView.idl +5 -0
- package/Microsoft.ReactNative/CompositionHwndHost.idl +1 -0
- package/Microsoft.ReactNative/Fabric/ComponentView.cpp +19 -1
- package/Microsoft.ReactNative/Fabric/ComponentView.h +10 -1
- package/Microsoft.ReactNative/Fabric/Composition/Composition.Input.cpp +12 -0
- package/Microsoft.ReactNative/Fabric/Composition/Composition.Input.h +15 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +75 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +1 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionHwndHost.cpp +10 -45
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +86 -98
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +4 -0
- package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp +80 -48
- package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.h +11 -3
- package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +61 -74
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +4 -3
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +2 -1
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeWindow.cpp +245 -0
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeWindow.h +80 -0
- package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +33 -1
- package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h +17 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +47 -23
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +3 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.cpp +3 -1
- package/Microsoft.ReactNative/Modules/LogBoxModule.cpp +20 -95
- package/Microsoft.ReactNative/Modules/LogBoxModule.h +1 -1
- package/Microsoft.ReactNative/ReactNativeAppBuilder.cpp +0 -41
- package/Microsoft.ReactNative/ReactNativeAppBuilder.idl +0 -11
- package/Microsoft.ReactNative/ReactNativeIsland.idl +2 -3
- package/Microsoft.ReactNative/ReactNativeWin32App.cpp +31 -101
- package/Microsoft.ReactNative/ReactNativeWin32App.h +2 -13
- package/Microsoft.ReactNative/ReactNativeWindow.idl +44 -0
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/Shared/Shared.vcxitems +7 -0
- package/Shared/Shared.vcxitems.filters +6 -0
- package/codegen/react/components/rnwcore/ActivityIndicatorView.g.h +2 -1
- package/codegen/react/components/rnwcore/AndroidDrawerLayout.g.h +26 -9
- package/codegen/react/components/rnwcore/AndroidHorizontalScrollContentView.g.h +2 -1
- package/codegen/react/components/rnwcore/AndroidProgressBar.g.h +2 -1
- package/codegen/react/components/rnwcore/AndroidSwipeRefreshLayout.g.h +8 -3
- package/codegen/react/components/rnwcore/AndroidSwitch.g.h +8 -3
- package/codegen/react/components/rnwcore/DebuggingOverlay.g.h +1 -0
- package/codegen/react/components/rnwcore/InputAccessory.g.h +2 -1
- package/codegen/react/components/rnwcore/ModalHostView.g.h +26 -9
- package/codegen/react/components/rnwcore/PullToRefreshView.g.h +8 -3
- package/codegen/react/components/rnwcore/SafeAreaView.g.h +1 -0
- package/codegen/react/components/rnwcore/Switch.g.h +8 -3
- package/codegen/react/components/rnwcore/UnimplementedNativeView.g.h +2 -1
- package/codegen/react/components/rnwcore/VirtualView.g.h +8 -3
- package/package.json +21 -21
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
#include "ScrollViewComponentView.h"
|
|
8
8
|
|
|
9
|
-
#include <
|
|
9
|
+
#include <Fabric/ComponentView.h>
|
|
10
10
|
#include <Utils/ValueUtils.h>
|
|
11
11
|
|
|
12
12
|
#pragma warning(push)
|
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
#include <AutoDraw.h>
|
|
21
21
|
#include <Fabric/DWriteHelpers.h>
|
|
22
22
|
#include <unicode.h>
|
|
23
|
+
#include <functional>
|
|
24
|
+
#include "ContentIslandComponentView.h"
|
|
23
25
|
#include "JSValueReader.h"
|
|
24
26
|
#include "RootComponentView.h"
|
|
25
27
|
|
|
@@ -885,6 +887,13 @@ void ScrollViewComponentView::updateContentVisualSize() noexcept {
|
|
|
885
887
|
|
|
886
888
|
void ScrollViewComponentView::prepareForRecycle() noexcept {}
|
|
887
889
|
|
|
890
|
+
void ScrollViewComponentView::updateChildrenClippingPath(
|
|
891
|
+
facebook::react::LayoutMetrics const & /*layoutMetrics*/,
|
|
892
|
+
const facebook::react::ViewProps & /*viewProps*/) noexcept {
|
|
893
|
+
// No-op: ScrollView mounts children into m_scrollVisual (not Visual()),
|
|
894
|
+
// and scroll visuals inherently clip their content.
|
|
895
|
+
}
|
|
896
|
+
|
|
888
897
|
/*
|
|
889
898
|
ScrollViewComponentView::ScrollInteractionTrackerOwner::ScrollInteractionTrackerOwner(
|
|
890
899
|
ScrollViewComponentView *outer)
|
|
@@ -1326,6 +1335,10 @@ winrt::Microsoft::ReactNative::Composition::Experimental::IVisual ScrollViewComp
|
|
|
1326
1335
|
m_allowNextScrollNoMatterWhat = false;
|
|
1327
1336
|
}
|
|
1328
1337
|
}
|
|
1338
|
+
|
|
1339
|
+
// Issue #15557: Notify listeners that scroll position has changed,
|
|
1340
|
+
// so ContentIslandComponentView can update LocalToParentTransformMatrix
|
|
1341
|
+
FireViewChanged();
|
|
1329
1342
|
});
|
|
1330
1343
|
|
|
1331
1344
|
m_scrollBeginDragRevoker = m_scrollVisual.ScrollBeginDrag(
|
|
@@ -1333,6 +1346,9 @@ winrt::Microsoft::ReactNative::Composition::Experimental::IVisual ScrollViewComp
|
|
|
1333
1346
|
[this](
|
|
1334
1347
|
winrt::IInspectable const & /*sender*/,
|
|
1335
1348
|
winrt::Microsoft::ReactNative::Composition::Experimental::IScrollPositionChangedArgs const &args) {
|
|
1349
|
+
// Issue #15557: Notify listeners that scroll position has changed
|
|
1350
|
+
FireViewChanged();
|
|
1351
|
+
|
|
1336
1352
|
m_allowNextScrollNoMatterWhat = true; // Ensure next scroll event is recorded, regardless of throttle
|
|
1337
1353
|
updateStateWithContentOffset();
|
|
1338
1354
|
auto eventEmitter = GetEventEmitter();
|
|
@@ -1479,4 +1495,20 @@ void ScrollViewComponentView::updateShowsVerticalScrollIndicator(bool value) noe
|
|
|
1479
1495
|
void ScrollViewComponentView::updateDecelerationRate(float value) noexcept {
|
|
1480
1496
|
m_scrollVisual.SetDecelerationRate({value, value, value});
|
|
1481
1497
|
}
|
|
1498
|
+
|
|
1499
|
+
// Issue #15557: Notify listeners that scroll position has changed.
|
|
1500
|
+
// ContentIslandComponentView subscribes to this to update LocalToParentTransformMatrix.
|
|
1501
|
+
void ScrollViewComponentView::FireViewChanged() noexcept {
|
|
1502
|
+
m_viewChangedEvent(*this, nullptr);
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1505
|
+
// Issue #15557: Event accessors for ViewChanged
|
|
1506
|
+
winrt::event_token ScrollViewComponentView::ViewChanged(
|
|
1507
|
+
winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable> const &handler) noexcept {
|
|
1508
|
+
return m_viewChangedEvent.add(handler);
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
void ScrollViewComponentView::ViewChanged(winrt::event_token const &token) noexcept {
|
|
1512
|
+
m_viewChangedEvent.remove(token);
|
|
1513
|
+
}
|
|
1482
1514
|
} // namespace winrt::Microsoft::ReactNative::Composition::implementation
|
|
@@ -118,6 +118,18 @@ struct ScrollInteractionTrackerOwner : public winrt::implements<
|
|
|
118
118
|
double getVerticalSize() noexcept;
|
|
119
119
|
double getHorizontalSize() noexcept;
|
|
120
120
|
|
|
121
|
+
// Issue #15557: Event accessors for ViewChanged (used by ContentIslandComponentView for transform update)
|
|
122
|
+
winrt::event_token ViewChanged(
|
|
123
|
+
winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable> const &handler) noexcept;
|
|
124
|
+
void ViewChanged(winrt::event_token const &token) noexcept;
|
|
125
|
+
|
|
126
|
+
protected:
|
|
127
|
+
// ScrollView mounts children into m_scrollVisual (not Visual()), and scroll visuals
|
|
128
|
+
// inherently clip their content, so we skip the children container clipping logic.
|
|
129
|
+
void updateChildrenClippingPath(
|
|
130
|
+
facebook::react::LayoutMetrics const &layoutMetrics,
|
|
131
|
+
const facebook::react::ViewProps &viewProps) noexcept override;
|
|
132
|
+
|
|
121
133
|
private:
|
|
122
134
|
void updateDecelerationRate(float value) noexcept;
|
|
123
135
|
void updateContentVisualSize() noexcept;
|
|
@@ -129,6 +141,8 @@ struct ScrollInteractionTrackerOwner : public winrt::implements<
|
|
|
129
141
|
bool scrollRight(float delta, bool animate) noexcept;
|
|
130
142
|
void updateBackgroundColor(const facebook::react::SharedColor &color) noexcept;
|
|
131
143
|
void updateStateWithContentOffset() noexcept;
|
|
144
|
+
// Issue #15557: Notify listeners that scroll position has changed
|
|
145
|
+
void FireViewChanged() noexcept;
|
|
132
146
|
facebook::react::ScrollViewEventEmitter::Metrics getScrollMetrics(
|
|
133
147
|
facebook::react::SharedViewEventEmitter const &eventEmitter,
|
|
134
148
|
winrt::Microsoft::ReactNative::Composition::Experimental::IScrollPositionChangedArgs const &args) noexcept;
|
|
@@ -160,6 +174,9 @@ struct ScrollInteractionTrackerOwner : public winrt::implements<
|
|
|
160
174
|
bool m_allowNextScrollNoMatterWhat{false};
|
|
161
175
|
std::chrono::steady_clock::time_point m_lastScrollEventTime{};
|
|
162
176
|
std::shared_ptr<facebook::react::ScrollViewShadowNode::ConcreteState const> m_state;
|
|
177
|
+
|
|
178
|
+
// Issue #15557: Event for notifying listeners when scroll position changes
|
|
179
|
+
winrt::event<winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>> m_viewChangedEvent;
|
|
163
180
|
};
|
|
164
181
|
|
|
165
182
|
} // namespace winrt::Microsoft::ReactNative::Composition::implementation
|
package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp
CHANGED
|
@@ -186,6 +186,7 @@ struct CompTextHost : public winrt::implements<CompTextHost, ITextHost> {
|
|
|
186
186
|
|
|
187
187
|
auto pt = m_outer->getClientOffset();
|
|
188
188
|
m_outer->m_caretVisual.Position({x - pt.x, y - pt.y});
|
|
189
|
+
m_outer->m_caretPosition = {x, y};
|
|
189
190
|
return true;
|
|
190
191
|
}
|
|
191
192
|
|
|
@@ -696,17 +697,10 @@ void WindowsTextInputComponentView::OnPointerPressed(
|
|
|
696
697
|
}
|
|
697
698
|
|
|
698
699
|
if (m_textServices && msg) {
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
args.Handled(true);
|
|
704
|
-
} else {
|
|
705
|
-
LRESULT lresult;
|
|
706
|
-
DrawBlock db(*this);
|
|
707
|
-
auto hr = m_textServices->TxSendMessage(msg, static_cast<WPARAM>(wParam), static_cast<LPARAM>(lParam), &lresult);
|
|
708
|
-
args.Handled(hr != S_FALSE);
|
|
709
|
-
}
|
|
700
|
+
LRESULT lresult;
|
|
701
|
+
DrawBlock db(*this);
|
|
702
|
+
auto hr = m_textServices->TxSendMessage(msg, static_cast<WPARAM>(wParam), static_cast<LPARAM>(lParam), &lresult);
|
|
703
|
+
args.Handled(hr != S_FALSE);
|
|
710
704
|
}
|
|
711
705
|
|
|
712
706
|
// Emits the OnPressIn event
|
|
@@ -768,10 +762,18 @@ void WindowsTextInputComponentView::OnPointerReleased(
|
|
|
768
762
|
}
|
|
769
763
|
|
|
770
764
|
if (m_textServices && msg) {
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
765
|
+
// Show context menu on right button release (standard Windows behavior)
|
|
766
|
+
if (msg == WM_RBUTTONUP && !windowsTextInputProps().contextMenuHidden) {
|
|
767
|
+
ShowContextMenu(LocalToScreen(position));
|
|
768
|
+
args.Handled(true);
|
|
769
|
+
} else if (msg == WM_RBUTTONUP) {
|
|
770
|
+
// Context menu is hidden - don't mark as handled, let app add custom behavior
|
|
771
|
+
} else {
|
|
772
|
+
LRESULT lresult;
|
|
773
|
+
DrawBlock db(*this);
|
|
774
|
+
auto hr = m_textServices->TxSendMessage(msg, static_cast<WPARAM>(wParam), static_cast<LPARAM>(lParam), &lresult);
|
|
775
|
+
args.Handled(hr != S_FALSE);
|
|
776
|
+
}
|
|
775
777
|
}
|
|
776
778
|
|
|
777
779
|
// Emits the OnPressOut event
|
|
@@ -1225,8 +1227,11 @@ void WindowsTextInputComponentView::updateState(
|
|
|
1225
1227
|
if (m_mostRecentEventCount == m_state->getData().mostRecentEventCount) {
|
|
1226
1228
|
m_comingFromState = true;
|
|
1227
1229
|
auto &fragments = m_state->getData().attributedStringBox.getValue().getFragments();
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
+
{
|
|
1231
|
+
// DrawBlock defers DrawText() until after UpdateText completes
|
|
1232
|
+
DrawBlock db(*this);
|
|
1233
|
+
UpdateText(fragments.size() ? fragments[0].string : "");
|
|
1234
|
+
}
|
|
1230
1235
|
m_comingFromState = false;
|
|
1231
1236
|
}
|
|
1232
1237
|
}
|
|
@@ -1375,7 +1380,7 @@ void WindowsTextInputComponentView::EmitOnScrollEvent() noexcept {
|
|
|
1375
1380
|
}
|
|
1376
1381
|
|
|
1377
1382
|
void WindowsTextInputComponentView::OnSelectionChanged(LONG start, LONG end) noexcept {
|
|
1378
|
-
if (m_eventEmitter && !m_comingFromState
|
|
1383
|
+
if (m_eventEmitter && !m_comingFromState && !m_comingFromJS) {
|
|
1379
1384
|
auto emitter = std::static_pointer_cast<const facebook::react::WindowsTextInputEventEmitter>(m_eventEmitter);
|
|
1380
1385
|
facebook::react::WindowsTextInputEventEmitter::OnSelectionChange onSelectionChangeArgs;
|
|
1381
1386
|
onSelectionChangeArgs.selection.start = start;
|
|
@@ -1676,7 +1681,8 @@ void WindowsTextInputComponentView::DrawText() noexcept {
|
|
|
1676
1681
|
}
|
|
1677
1682
|
|
|
1678
1683
|
bool isZeroSized =
|
|
1679
|
-
m_layoutMetrics.frame.size.width <= (m_layoutMetrics.contentInsets.left + m_layoutMetrics.contentInsets.right)
|
|
1684
|
+
m_layoutMetrics.frame.size.width <= (m_layoutMetrics.contentInsets.left + m_layoutMetrics.contentInsets.right) ||
|
|
1685
|
+
m_layoutMetrics.frame.size.height <= (m_layoutMetrics.contentInsets.top + m_layoutMetrics.contentInsets.bottom);
|
|
1680
1686
|
if (!m_drawingSurface || isZeroSized)
|
|
1681
1687
|
return;
|
|
1682
1688
|
|
|
@@ -1870,6 +1876,21 @@ void WindowsTextInputComponentView::updateSpellCheck(bool enable) noexcept {
|
|
|
1870
1876
|
m_textServices->TxSendMessage(EM_SETLANGOPTIONS, IMF_SPELLCHECKING, enable ? newLangOptions : 0, &lresult));
|
|
1871
1877
|
}
|
|
1872
1878
|
|
|
1879
|
+
void WindowsTextInputComponentView::OnContextMenuKey(
|
|
1880
|
+
const winrt::Microsoft::ReactNative::Composition::Input::ContextMenuKeyEventArgs &args) noexcept {
|
|
1881
|
+
// Handle context menu key event (SHIFT+F10 or Context Menu key)
|
|
1882
|
+
if (!windowsTextInputProps().contextMenuHidden) {
|
|
1883
|
+
// m_caretPosition is stored from TxSetCaretPos in RichEdit client rect space (physical pixels).
|
|
1884
|
+
// LocalToScreen expects logical (DIP) coordinates, so divide by pointScaleFactor.
|
|
1885
|
+
auto screenPt = LocalToScreen(winrt::Windows::Foundation::Point{
|
|
1886
|
+
static_cast<float>(m_caretPosition.x) / m_layoutMetrics.pointScaleFactor,
|
|
1887
|
+
static_cast<float>(m_caretPosition.y) / m_layoutMetrics.pointScaleFactor});
|
|
1888
|
+
ShowContextMenu(screenPt);
|
|
1889
|
+
args.Handled(true);
|
|
1890
|
+
}
|
|
1891
|
+
// If contextMenuHidden, don't mark as handled - let app handle it
|
|
1892
|
+
}
|
|
1893
|
+
|
|
1873
1894
|
void WindowsTextInputComponentView::ShowContextMenu(const winrt::Windows::Foundation::Point &position) noexcept {
|
|
1874
1895
|
HMENU menu = CreatePopupMenu();
|
|
1875
1896
|
if (!menu)
|
|
@@ -1889,13 +1910,16 @@ void WindowsTextInputComponentView::ShowContextMenu(const winrt::Windows::Founda
|
|
|
1889
1910
|
AppendMenuW(menu, MF_STRING | (canPaste ? 0 : MF_GRAYED), 3, L"Paste");
|
|
1890
1911
|
AppendMenuW(menu, MF_STRING | (!isEmpty && !isReadOnly ? 0 : MF_GRAYED), 4, L"Select All");
|
|
1891
1912
|
|
|
1892
|
-
POINT cursorPos;
|
|
1893
|
-
GetCursorPos(&cursorPos);
|
|
1894
|
-
|
|
1895
1913
|
HWND hwnd = GetActiveWindow();
|
|
1896
1914
|
|
|
1897
1915
|
int cmd = TrackPopupMenu(
|
|
1898
|
-
menu,
|
|
1916
|
+
menu,
|
|
1917
|
+
TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD | TPM_NONOTIFY,
|
|
1918
|
+
static_cast<int>(position.X),
|
|
1919
|
+
static_cast<int>(position.Y),
|
|
1920
|
+
0,
|
|
1921
|
+
hwnd,
|
|
1922
|
+
NULL);
|
|
1899
1923
|
|
|
1900
1924
|
if (cmd == 1) { // Cut
|
|
1901
1925
|
m_textServices->TxSendMessage(WM_CUT, 0, 0, &res);
|
|
@@ -67,6 +67,8 @@ struct WindowsTextInputComponentView
|
|
|
67
67
|
void OnKeyUp(const winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs &args) noexcept override;
|
|
68
68
|
void OnCharacterReceived(const winrt::Microsoft::ReactNative::Composition::Input::CharacterReceivedRoutedEventArgs
|
|
69
69
|
&args) noexcept override;
|
|
70
|
+
void OnContextMenuKey(
|
|
71
|
+
const winrt::Microsoft::ReactNative::Composition::Input::ContextMenuKeyEventArgs &args) noexcept override;
|
|
70
72
|
void onMounted() noexcept override;
|
|
71
73
|
|
|
72
74
|
std::optional<std::string> getAccessiblityValue() noexcept override;
|
|
@@ -146,6 +148,7 @@ struct WindowsTextInputComponentView
|
|
|
146
148
|
DWORD m_propBitsMask{0};
|
|
147
149
|
DWORD m_propBits{0};
|
|
148
150
|
HCURSOR m_hcursor{nullptr};
|
|
151
|
+
POINT m_caretPosition{0, 0};
|
|
149
152
|
std::chrono::steady_clock::time_point m_lastClickTime{};
|
|
150
153
|
std::vector<facebook::react::CompWindowsTextInputSubmitKeyEventsStruct> m_submitKeyEvents;
|
|
151
154
|
};
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
#include <react/featureflags/ReactNativeFeatureFlags.h>
|
|
7
7
|
#include <react/renderer/attributedstring/AttributedStringBox.h>
|
|
8
|
+
#include <react/renderer/attributedstring/PlaceholderAttributedString.h>
|
|
8
9
|
#include <react/renderer/attributedstring/TextAttributes.h>
|
|
9
10
|
#include <react/renderer/components/text/BaseTextShadowNode.h>
|
|
10
11
|
#include <react/renderer/core/LayoutConstraints.h>
|
|
@@ -185,6 +186,7 @@ AttributedString WindowsTextInputShadowNode::getPlaceholderAttributedString(cons
|
|
|
185
186
|
const auto &props = getConcreteProps();
|
|
186
187
|
|
|
187
188
|
AttributedString attributedString;
|
|
189
|
+
attributedString.setBaseTextAttributes(props.textAttributes);
|
|
188
190
|
//[windows
|
|
189
191
|
if (!props.placeholder.empty()) {
|
|
190
192
|
auto textAttributes = TextAttributes::defaultTextAttributes();
|
|
@@ -203,7 +205,7 @@ AttributedString WindowsTextInputShadowNode::getPlaceholderAttributedString(cons
|
|
|
203
205
|
}
|
|
204
206
|
// windows]
|
|
205
207
|
|
|
206
|
-
return attributedString;
|
|
208
|
+
return ensurePlaceholderIfEmpty_DO_NOT_USE(attributedString);
|
|
207
209
|
}
|
|
208
210
|
|
|
209
211
|
#pragma mark - LayoutableShadowNode
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
#ifdef USE_FABRIC
|
|
13
13
|
#include <Fabric/Composition/CompositionContextHelper.h>
|
|
14
14
|
#include <Fabric/Composition/CompositionUIService.h>
|
|
15
|
+
#include <winrt/Microsoft.UI.Windowing.h>
|
|
15
16
|
#include <winrt/Windows.UI.Composition.h>
|
|
16
17
|
#else
|
|
17
18
|
#include <UI.Xaml.Controls.Primitives.h>
|
|
@@ -22,16 +23,14 @@ namespace Microsoft::ReactNative {
|
|
|
22
23
|
|
|
23
24
|
LogBox::~LogBox() {
|
|
24
25
|
#ifdef USE_FABRIC
|
|
25
|
-
if (
|
|
26
|
-
m_context.UIDispatcher().Post([
|
|
27
|
-
|
|
26
|
+
if (m_rnWindow) {
|
|
27
|
+
m_context.UIDispatcher().Post([rnWindow = m_rnWindow]() { rnWindow.Close(); });
|
|
28
|
+
m_rnWindow = nullptr;
|
|
28
29
|
}
|
|
29
30
|
#endif
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
#ifdef USE_FABRIC
|
|
33
|
-
constexpr PCWSTR c_logBoxWindowClassName = L"MS_REACTNATIVE_LOGBOX";
|
|
34
|
-
constexpr auto CompHostProperty = L"CompHost";
|
|
35
34
|
const int LOGBOX_DEFAULT_WIDTH = 700;
|
|
36
35
|
const int LOGBOX_DEFAULT_HEIGHT = 1000;
|
|
37
36
|
#endif // USE_FABRIC
|
|
@@ -55,69 +54,6 @@ void LogBox::Hide() noexcept {
|
|
|
55
54
|
});
|
|
56
55
|
}
|
|
57
56
|
|
|
58
|
-
#ifdef USE_FABRIC
|
|
59
|
-
LRESULT CALLBACK LogBoxWndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) noexcept {
|
|
60
|
-
auto data = reinterpret_cast<::IUnknown *>(GetProp(hwnd, CompHostProperty));
|
|
61
|
-
winrt::com_ptr<winrt::IUnknown> spunk;
|
|
62
|
-
React::CompositionHwndHost host{nullptr};
|
|
63
|
-
|
|
64
|
-
if (data) {
|
|
65
|
-
winrt::check_hresult(data->QueryInterface(winrt::guid_of<React::CompositionHwndHost>(), winrt::put_abi(host)));
|
|
66
|
-
auto result = static_cast<LRESULT>(host.TranslateMessage(message, wparam, lparam));
|
|
67
|
-
if (result)
|
|
68
|
-
return result;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
switch (message) {
|
|
72
|
-
case WM_NCCREATE: {
|
|
73
|
-
auto cs = reinterpret_cast<CREATESTRUCT *>(lparam);
|
|
74
|
-
auto windowData = static_cast<::IUnknown *>(cs->lpCreateParams);
|
|
75
|
-
SetProp(hwnd, CompHostProperty, reinterpret_cast<::IUnknown *>(windowData));
|
|
76
|
-
break;
|
|
77
|
-
}
|
|
78
|
-
case WM_CREATE: {
|
|
79
|
-
host.Initialize((uint64_t)hwnd);
|
|
80
|
-
break;
|
|
81
|
-
}
|
|
82
|
-
case WM_CLOSE: {
|
|
83
|
-
// Just hide the window instead of destroying it
|
|
84
|
-
::ShowWindow(hwnd, SW_HIDE);
|
|
85
|
-
return 0;
|
|
86
|
-
}
|
|
87
|
-
case WM_DESTROY: {
|
|
88
|
-
data->Release();
|
|
89
|
-
SetProp(hwnd, CompHostProperty, nullptr);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return DefWindowProc(hwnd, message, wparam, lparam);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
void LogBox::RegisterWndClass() noexcept {
|
|
97
|
-
static bool registered = false;
|
|
98
|
-
if (registered)
|
|
99
|
-
return;
|
|
100
|
-
|
|
101
|
-
HINSTANCE hInstance = GetModuleHandle(NULL);
|
|
102
|
-
|
|
103
|
-
WNDCLASSEXW wcex = {};
|
|
104
|
-
wcex.cbSize = sizeof(WNDCLASSEX);
|
|
105
|
-
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
|
106
|
-
wcex.lpfnWndProc = &LogBoxWndProc;
|
|
107
|
-
wcex.cbClsExtra = DLGWINDOWEXTRA;
|
|
108
|
-
wcex.cbWndExtra = sizeof(winrt::impl::abi<winrt::Microsoft::ReactNative::ICompositionHwndHost>::type *);
|
|
109
|
-
wcex.hInstance = hInstance;
|
|
110
|
-
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
|
111
|
-
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
|
|
112
|
-
wcex.lpszClassName = c_logBoxWindowClassName;
|
|
113
|
-
ATOM classId = RegisterClassEx(&wcex);
|
|
114
|
-
WINRT_VERIFY(classId);
|
|
115
|
-
winrt::check_win32(!classId);
|
|
116
|
-
|
|
117
|
-
registered = true;
|
|
118
|
-
}
|
|
119
|
-
#endif // USE_FABRIC
|
|
120
|
-
|
|
121
57
|
void LogBox::ShowOnUIThread() noexcept {
|
|
122
58
|
auto host = React::implementation::ReactNativeHost::GetReactNativeHost(m_context.Properties());
|
|
123
59
|
if (!host)
|
|
@@ -173,45 +109,34 @@ void LogBox::ShowOnUIThread() noexcept {
|
|
|
173
109
|
}
|
|
174
110
|
#else
|
|
175
111
|
else {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
112
|
+
if (!m_rnWindow) {
|
|
113
|
+
m_rnWindow = winrt::Microsoft::ReactNative::ReactNativeWindow::CreateFromCompositor(
|
|
114
|
+
winrt::Microsoft::ReactNative::Composition::CompositionUIService::GetCompositor(
|
|
115
|
+
host.InstanceSettings().Properties()));
|
|
179
116
|
auto CompositionHwndHost = React::CompositionHwndHost();
|
|
180
117
|
winrt::Microsoft::ReactNative::ReactViewOptions viewOptions;
|
|
181
118
|
viewOptions.ComponentName(L"LogBox");
|
|
182
|
-
|
|
119
|
+
m_rnWindow.AppWindow().Title(L"LogBox");
|
|
120
|
+
m_rnWindow.AppWindow().Closing([](winrt::Microsoft::UI::Windowing::AppWindow const & /*appWindow*/,
|
|
121
|
+
winrt::Microsoft::UI::Windowing::AppWindowClosingEventArgs const &args) {
|
|
122
|
+
// Prevent default close behavior - as JS will never try to show the logbox again if it isn't hidden through JS
|
|
123
|
+
args.Cancel(true);
|
|
124
|
+
});
|
|
125
|
+
m_rnWindow.ReactNativeIsland().ReactViewHost(
|
|
183
126
|
winrt::Microsoft::ReactNative::ReactCoreInjection::MakeViewHost(host, viewOptions));
|
|
184
|
-
|
|
185
|
-
winrt::impl::abi<winrt::Microsoft::ReactNative::ICompositionHwndHost>::type *pHost{nullptr};
|
|
186
|
-
winrt::com_ptr<::IUnknown> spunk;
|
|
187
|
-
CompositionHwndHost.as(spunk);
|
|
188
|
-
spunk->AddRef(); // Will be stored in windowData
|
|
189
|
-
|
|
190
|
-
m_hwnd = CreateWindow(
|
|
191
|
-
c_logBoxWindowClassName,
|
|
192
|
-
L"React-Native LogBox",
|
|
193
|
-
WS_OVERLAPPEDWINDOW,
|
|
194
|
-
CW_USEDEFAULT,
|
|
195
|
-
CW_USEDEFAULT,
|
|
196
|
-
LOGBOX_DEFAULT_WIDTH,
|
|
197
|
-
LOGBOX_DEFAULT_HEIGHT,
|
|
198
|
-
nullptr,
|
|
199
|
-
nullptr,
|
|
200
|
-
hInstance,
|
|
201
|
-
spunk.get());
|
|
127
|
+
m_rnWindow.AppWindow().ResizeClient({LOGBOX_DEFAULT_WIDTH, LOGBOX_DEFAULT_HEIGHT});
|
|
202
128
|
}
|
|
203
129
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
SetFocus(m_hwnd);
|
|
130
|
+
m_rnWindow.AppWindow().Show(true);
|
|
131
|
+
m_rnWindow.AppWindow().MoveInZOrderAtTop();
|
|
207
132
|
}
|
|
208
133
|
#endif // USE_FABRIC
|
|
209
134
|
}
|
|
210
135
|
|
|
211
136
|
void LogBox::HideOnUIThread() noexcept {
|
|
212
137
|
#ifdef USE_FABRIC
|
|
213
|
-
if (
|
|
214
|
-
|
|
138
|
+
if (m_rnWindow) {
|
|
139
|
+
m_rnWindow.AppWindow().Hide();
|
|
215
140
|
}
|
|
216
141
|
#else // USE_FABRIC
|
|
217
142
|
if (m_popup) {
|
|
@@ -31,7 +31,7 @@ struct LogBox : public std::enable_shared_from_this<LogBox> {
|
|
|
31
31
|
|
|
32
32
|
winrt::Microsoft::ReactNative::ReactContext m_context;
|
|
33
33
|
#ifdef USE_FABRIC
|
|
34
|
-
|
|
34
|
+
winrt::Microsoft::ReactNative::ReactNativeWindow m_rnWindow{nullptr};
|
|
35
35
|
#else
|
|
36
36
|
xaml::Controls::Primitives::Popup m_popup{nullptr};
|
|
37
37
|
winrt::Microsoft::ReactNative::ReactRootView m_logBoxContent{nullptr};
|
|
@@ -20,19 +20,6 @@ ReactNativeAppBuilder::ReactNativeAppBuilder() {
|
|
|
20
20
|
|
|
21
21
|
ReactNativeAppBuilder::~ReactNativeAppBuilder() {}
|
|
22
22
|
|
|
23
|
-
winrt::Microsoft::ReactNative::ReactNativeAppBuilder ReactNativeAppBuilder::SetDispatcherQueueController(
|
|
24
|
-
winrt::Microsoft::UI::Dispatching::DispatcherQueueController const &dispatcherQueueController) {
|
|
25
|
-
m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->DispatcherQueueController(
|
|
26
|
-
dispatcherQueueController);
|
|
27
|
-
return *this;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
winrt::Microsoft::ReactNative::ReactNativeAppBuilder ReactNativeAppBuilder::SetCompositor(
|
|
31
|
-
winrt::Microsoft::UI::Composition::Compositor const &compositor) {
|
|
32
|
-
m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->Compositor(compositor);
|
|
33
|
-
return *this;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
23
|
winrt::Microsoft::ReactNative::ReactNativeAppBuilder ReactNativeAppBuilder::SetAppWindow(
|
|
37
24
|
winrt::Microsoft::UI::Windowing::AppWindow const &appWindow) {
|
|
38
25
|
m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->AppWindow(appWindow);
|
|
@@ -41,34 +28,6 @@ winrt::Microsoft::ReactNative::ReactNativeAppBuilder ReactNativeAppBuilder::SetA
|
|
|
41
28
|
}
|
|
42
29
|
|
|
43
30
|
winrt::Microsoft::ReactNative::ReactNativeWin32App ReactNativeAppBuilder::Build() {
|
|
44
|
-
// Create the DispatcherQueueController if the app developer doesn't provide one
|
|
45
|
-
if (m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->DispatcherQueueController() == nullptr) {
|
|
46
|
-
assert(m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->Compositor() == nullptr);
|
|
47
|
-
|
|
48
|
-
// Create a DispatcherQueue for this thread. This is needed for Composition, Content, and Input APIs.
|
|
49
|
-
auto dispatcherQueueController =
|
|
50
|
-
winrt::Microsoft::UI::Dispatching::DispatcherQueueController::CreateOnCurrentThread();
|
|
51
|
-
|
|
52
|
-
m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->DispatcherQueueController(
|
|
53
|
-
dispatcherQueueController);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Create the Compositor if the app developer doesn't provide one
|
|
57
|
-
if (m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->Compositor() == nullptr) {
|
|
58
|
-
// Create the compositor on behalf of the App Developer.
|
|
59
|
-
auto compositor = winrt::Microsoft::UI::Composition::Compositor();
|
|
60
|
-
m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->Compositor(compositor);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Create the AppWindow if the app developer doesn't provide one
|
|
64
|
-
if (m_reactNativeWin32App.AppWindow() == nullptr) {
|
|
65
|
-
auto appWindow = winrt::Microsoft::UI::Windowing::AppWindow::Create();
|
|
66
|
-
appWindow.Title(L"ReactNativeWin32App");
|
|
67
|
-
appWindow.Resize({1000, 1000});
|
|
68
|
-
|
|
69
|
-
m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->AppWindow(appWindow);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
31
|
return m_reactNativeWin32App;
|
|
73
32
|
}
|
|
74
33
|
|
|
@@ -18,12 +18,6 @@ namespace Microsoft.ReactNative {
|
|
|
18
18
|
|
|
19
19
|
ReactViewOptions ReactViewOptions {get;};
|
|
20
20
|
|
|
21
|
-
// TODO: Hide these APIs for now until we're sure we need to expose them and can do so safely
|
|
22
|
-
// Microsoft.UI.Composition.Compositor Compositor {get;};
|
|
23
|
-
// Microsoft.UI.Content.DesktopChildSiteBridge DesktopChildSiteBridge {get;};
|
|
24
|
-
// Microsoft.UI.Dispatching DispatcherQueueController {get;};
|
|
25
|
-
// ReactNativeIsland ReactNativeIsland {get;};
|
|
26
|
-
|
|
27
21
|
// Methods
|
|
28
22
|
void Start();
|
|
29
23
|
}
|
|
@@ -38,11 +32,6 @@ namespace Microsoft.ReactNative {
|
|
|
38
32
|
|
|
39
33
|
ReactNativeAppBuilder SetAppWindow(Microsoft.UI.Windowing.AppWindow appWindow);
|
|
40
34
|
|
|
41
|
-
// TODO: Hide these APIs for now until we're sure we need to expose them and can do so safely
|
|
42
|
-
// Compositor depends on the DispatcherQueue created by DispatcherQueueController
|
|
43
|
-
// ReactNativeAppBuilder SetCompositor(Microsoft.UI.Composition.Compositor compositor);
|
|
44
|
-
// ReactNativeAppBuilder SetDispatcherQueueController(Microsoft.UI.Dispatching DispatcherQueueController);
|
|
45
|
-
|
|
46
35
|
ReactNativeWin32App Build();
|
|
47
36
|
}
|
|
48
37
|
}
|
|
@@ -80,9 +80,6 @@ namespace Microsoft.ReactNative
|
|
|
80
80
|
DOC_STRING("A windows composition component that hosts React Native UI elements.")
|
|
81
81
|
runtimeclass ReactNativeIsland
|
|
82
82
|
{
|
|
83
|
-
DOC_STRING("Creates a new instance of @ReactNativeIsland. Can be implemented with a ReactViewHost or a ComponentView with reactContext")
|
|
84
|
-
ReactNativeIsland();
|
|
85
|
-
|
|
86
83
|
#ifdef USE_WINUI3
|
|
87
84
|
ReactNativeIsland(Microsoft.UI.Composition.Compositor compositor);
|
|
88
85
|
|
|
@@ -100,6 +97,8 @@ namespace Microsoft.ReactNative
|
|
|
100
97
|
|
|
101
98
|
Windows.Foundation.Size Size { get; };
|
|
102
99
|
|
|
100
|
+
Microsoft.UI.Composition.Compositor Compositor { get; };
|
|
101
|
+
|
|
103
102
|
DOC_STRING("ScaleFactor for this windows (DPI/96)")
|
|
104
103
|
Single ScaleFactor {get; set;};
|
|
105
104
|
|