react-native-windows 0.74.20 → 0.74.22

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.
Files changed (94) hide show
  1. package/Microsoft.ReactNative/ComponentView.idl +44 -32
  2. package/Microsoft.ReactNative/Composition.Input.idl +3 -0
  3. package/Microsoft.ReactNative/CompositionComponentView.idl +43 -24
  4. package/Microsoft.ReactNative/CompositionSwitcher.idl +3 -0
  5. package/Microsoft.ReactNative/Fabric/AbiEventEmitter.cpp +21 -0
  6. package/Microsoft.ReactNative/Fabric/AbiEventEmitter.h +23 -0
  7. package/Microsoft.ReactNative/Fabric/AbiShadowNode.cpp +7 -0
  8. package/Microsoft.ReactNative/Fabric/AbiShadowNode.h +3 -0
  9. package/Microsoft.ReactNative/Fabric/ComponentView.cpp +334 -65
  10. package/Microsoft.ReactNative/Fabric/ComponentView.h +162 -38
  11. package/Microsoft.ReactNative/Fabric/Composition/ActivityIndicatorComponentView.cpp +2 -2
  12. package/Microsoft.ReactNative/Fabric/Composition/ComponentViewRegistry.cpp +3 -0
  13. package/Microsoft.ReactNative/Fabric/Composition/Composition.Input.cpp +29 -7
  14. package/Microsoft.ReactNative/Fabric/Composition/Composition.Input.h +23 -4
  15. package/Microsoft.ReactNative/Fabric/Composition/CompositionContextHelper.cpp +44 -13
  16. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +118 -0
  17. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +12 -1
  18. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +147 -119
  19. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +4 -8
  20. package/Microsoft.ReactNative/Fabric/Composition/CompositionHwndHost.cpp +1 -0
  21. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +129 -106
  22. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +31 -54
  23. package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp +133 -0
  24. package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.h +61 -0
  25. package/Microsoft.ReactNative/Fabric/Composition/DebuggingOverlayComponentView.cpp +9 -8
  26. package/Microsoft.ReactNative/Fabric/Composition/DebuggingOverlayComponentView.h +1 -2
  27. package/Microsoft.ReactNative/Fabric/Composition/FocusManager.cpp +20 -6
  28. package/Microsoft.ReactNative/Fabric/Composition/FocusManager.h +13 -6
  29. package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp +1 -4
  30. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +3 -5
  31. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.h +1 -2
  32. package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +1 -6
  33. package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.h +0 -1
  34. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.cpp +108 -18
  35. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.h +33 -5
  36. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +137 -56
  37. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +21 -4
  38. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +45 -10
  39. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +9 -2
  40. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +209 -189
  41. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h +2 -5
  42. package/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.cpp +22 -10
  43. package/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.h +4 -5
  44. package/Microsoft.ReactNative/Fabric/Composition/TextDrawing.cpp +1 -2
  45. package/Microsoft.ReactNative/Fabric/Composition/TextDrawing.h +1 -1
  46. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +115 -168
  47. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +11 -14
  48. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.cpp +14 -11
  49. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.h +4 -4
  50. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.cpp +0 -13
  51. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.h +0 -3
  52. package/Microsoft.ReactNative/Fabric/Composition/Theme.cpp +12 -4
  53. package/Microsoft.ReactNative/Fabric/Composition/TooltipService.cpp +338 -0
  54. package/Microsoft.ReactNative/Fabric/Composition/TooltipService.h +66 -0
  55. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +56 -4
  56. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +7 -0
  57. package/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.cpp +2 -4
  58. package/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.h +1 -2
  59. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +40 -9
  60. package/Microsoft.ReactNative/Fabric/ReactTaggedView.h +4 -0
  61. package/Microsoft.ReactNative/Fabric/WindowsComponentDescriptorRegistry.cpp +1 -3
  62. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.cpp +25 -1
  63. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.h +4 -1
  64. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewTraitsInitializer.h +1 -1
  65. package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.cpp +9 -2
  66. package/Microsoft.ReactNative/IReactCompositionViewComponentBuilder.idl +13 -3
  67. package/Microsoft.ReactNative/IReactViewComponentBuilder.idl +64 -4
  68. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +1 -1
  69. package/Microsoft.ReactNative/Modules/LogBoxModule.cpp +9 -0
  70. package/Microsoft.ReactNative/Modules/LogBoxModule.h +2 -0
  71. package/Microsoft.ReactNative/Modules/SampleTurboModule.cpp +104 -0
  72. package/Microsoft.ReactNative/Modules/SampleTurboModule.h +78 -0
  73. package/Microsoft.ReactNative/ReactCoreInjection.h +0 -1
  74. package/Microsoft.ReactNative/ReactHost/MsoReactContext.cpp +0 -7
  75. package/Microsoft.ReactNative/ReactHost/MsoReactContext.h +0 -5
  76. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +17 -1
  77. package/Microsoft.ReactNative/ReactInstanceSettingsBuilder.cpp +59 -0
  78. package/Microsoft.ReactNative/ReactInstanceSettingsBuilder.h +23 -0
  79. package/Microsoft.ReactNative/ReactNativeAppBuilder.cpp +179 -0
  80. package/Microsoft.ReactNative/ReactNativeAppBuilder.h +35 -0
  81. package/Microsoft.ReactNative/ReactNativeAppBuilder.idl +69 -0
  82. package/Microsoft.ReactNative/ReactNativeIsland.idl +5 -0
  83. package/Microsoft.ReactNative/ReactNativeWin32App.cpp +82 -0
  84. package/Microsoft.ReactNative/ReactNativeWin32App.h +38 -0
  85. package/Microsoft.ReactNative/Timer.idl +1 -1
  86. package/Microsoft.ReactNative/packages.lock.json +0 -10
  87. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  88. package/PropertySheets/WinUI.props +1 -1
  89. package/Shared/Shared.vcxitems +43 -0
  90. package/Shared/Shared.vcxitems.filters +3 -0
  91. package/Shared/TurboModuleManager.cpp +0 -3
  92. package/just-task.js +1 -1
  93. package/package.json +3 -3
  94. package/templates/cpp-app/windows/MyApp/MyApp.cpp +1 -0
@@ -14,7 +14,7 @@
14
14
  namespace winrt::Microsoft::ReactNative::Composition {
15
15
 
16
16
  void RenderText(
17
- ID2D1DeviceContext &deviceContext,
17
+ ID2D1RenderTarget &deviceContext,
18
18
  ::IDWriteTextLayout &textLayout,
19
19
  const facebook::react::AttributedString &attributedString,
20
20
  const facebook::react::TextAttributes &textAttributes,
@@ -176,9 +176,8 @@ struct CompTextHost : public winrt::implements<CompTextHost, ITextHost> {
176
176
  return false;
177
177
  }
178
178
 
179
- m_outer->m_caretVisual.Position(
180
- {x - (m_outer->m_layoutMetrics.frame.origin.x * m_outer->m_layoutMetrics.pointScaleFactor),
181
- y - (m_outer->m_layoutMetrics.frame.origin.y * m_outer->m_layoutMetrics.pointScaleFactor)});
179
+ auto pt = m_outer->getClientOffset();
180
+ m_outer->m_caretVisual.Position({x - pt.x, y - pt.y});
182
181
  return true;
183
182
  }
184
183
 
@@ -225,7 +224,8 @@ struct CompTextHost : public winrt::implements<CompTextHost, ITextHost> {
225
224
  winrt::Microsoft::ReactNative::ComponentView view{nullptr};
226
225
  winrt::check_hresult(
227
226
  m_outer->QueryInterface(winrt::guid_of<winrt::Microsoft::ReactNative::ComponentView>(), winrt::put_abi(view)));
228
- m_outer->rootComponentView()->TrySetFocusedComponent(view);
227
+ m_outer->rootComponentView()->TrySetFocusedComponent(
228
+ view, winrt::Microsoft::ReactNative::FocusNavigationDirection::None);
229
229
  // assert(false);
230
230
  // TODO focus
231
231
  }
@@ -261,7 +261,7 @@ struct CompTextHost : public winrt::implements<CompTextHost, ITextHost> {
261
261
 
262
262
  //@cmember Retrieves the coordinates of a window's client area
263
263
  HRESULT TxGetClientRect(LPRECT prc) override {
264
- *prc = m_outer->m_rcClient;
264
+ *prc = m_outer->getClientRect();
265
265
  return S_OK;
266
266
  }
267
267
 
@@ -454,6 +454,7 @@ facebook::react::AttributedString WindowsTextInputComponentView::getAttributedSt
454
454
  // Use BaseTextShadowNode to get attributed string from children
455
455
 
456
456
  auto childTextAttributes = facebook::react::TextAttributes::defaultTextAttributes();
457
+ childTextAttributes.fontSizeMultiplier = m_fontSizeMultiplier;
457
458
 
458
459
  childTextAttributes.apply(windowsTextInputProps().textAttributes);
459
460
 
@@ -463,9 +464,9 @@ facebook::react::AttributedString WindowsTextInputComponentView::getAttributedSt
463
464
  // BaseTextShadowNode only gets children. We must detect and prepend text
464
465
  // value attributes manually.
465
466
  auto text = GetTextFromRichEdit();
466
- // if (!m_props->text.empty()) {
467
467
  if (!text.empty()) {
468
468
  auto textAttributes = facebook::react::TextAttributes::defaultTextAttributes();
469
+ textAttributes.fontSizeMultiplier = m_fontSizeMultiplier;
469
470
  textAttributes.apply(windowsTextInputProps().textAttributes);
470
471
  auto fragment = facebook::react::AttributedString::Fragment{};
471
472
  fragment.string = text;
@@ -491,67 +492,41 @@ WindowsTextInputComponentView::WindowsTextInputComponentView(
491
492
  compContext,
492
493
  tag,
493
494
  reactContext,
494
- ComponentViewFeatures::Default & ~ComponentViewFeatures::Background,
495
- false) {
496
- /*
497
- m_textChangedRevoker =
498
- m_element.TextChanged(winrt::auto_revoke, [this](auto sender, xaml::Controls::TextChangedEventArgs args) {
499
- auto data = m_state->getData();
500
- data.attributedString = getAttributedString();
501
- data.mostRecentEventCount = m_nativeEventCount;
502
- m_state->updateState(std::move(data));
503
-
504
- if (m_eventEmitter && !m_comingFromJS) {
505
- auto emitter = std::static_pointer_cast<const facebook::react::WindowsTextInputEventEmitter>(m_eventEmitter);
506
- facebook::react::WindowsTextInputEventEmitter::OnChange onChangeArgs;
507
- onChangeArgs.text = winrt::to_string(m_element.Text());
508
- onChangeArgs.eventCount = ++m_nativeEventCount;
509
- emitter->onChange(onChangeArgs);
510
- }
511
- });
512
-
513
- m_SelectionChangedRevoker = m_element.SelectionChanged(winrt::auto_revoke, [this](auto sender, auto args) {
514
- if (m_eventEmitter) {
515
- auto emitter = std::static_pointer_cast<const facebook::react::WindowsTextInputEventEmitter>(m_eventEmitter);
516
- facebook::react::WindowsTextInputEventEmitter::OnSelectionChange onSelectionChangeArgs;
517
- onSelectionChangeArgs.selection.start = m_element.SelectionStart();
518
- onSelectionChangeArgs.selection.end = m_element.SelectionStart() + m_element.SelectionLength();
519
- emitter->onSelectionChange(onSelectionChangeArgs);
520
- }
521
- });
522
- */
523
- }
495
+ ComponentViewFeatures::Default & ~ComponentViewFeatures::Background) {}
524
496
 
525
497
  void WindowsTextInputComponentView::HandleCommand(
526
- winrt::hstring commandName,
527
- const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept {
498
+ const winrt::Microsoft::ReactNative::HandleCommandArgs &args) noexcept {
499
+ Super::HandleCommand(args);
500
+ if (args.Handled())
501
+ return;
502
+
503
+ auto commandName = args.CommandName();
528
504
  if (commandName == L"setTextAndSelection") {
529
505
  int eventCount, begin, end;
530
- winrt::hstring text;
506
+ std::optional<winrt::hstring> text;
531
507
 
532
- winrt::Microsoft::ReactNative::ReadArgs(args, eventCount, text, begin, end);
508
+ winrt::Microsoft::ReactNative::ReadArgs(args.CommandArgs(), eventCount, text, begin, end);
533
509
  if (eventCount >= m_nativeEventCount) {
534
510
  m_comingFromJS = true;
535
- UpdateText(winrt::to_string(text));
536
-
537
- SELCHANGE sc;
538
- memset(&sc, 0, sizeof(sc));
539
- sc.chrg.cpMin = static_cast<LONG>(begin);
540
- sc.chrg.cpMax = static_cast<LONG>(end);
541
- sc.seltyp = (begin == end) ? SEL_EMPTY : SEL_TEXT;
542
-
543
- LRESULT res;
544
- /*
545
- winrt::check_hresult(m_textServices->TxSendMessage(
546
- EM_SELCHANGE, 0 , reinterpret_cast<WPARAM>(&sc), &res));
547
- */
548
- winrt::check_hresult(
549
- m_textServices->TxSendMessage(EM_SETSEL, static_cast<WPARAM>(begin), static_cast<LPARAM>(end), &res));
511
+ {
512
+ if (text.has_value()) {
513
+ DrawBlock db(*this);
514
+ UpdateText(winrt::to_string(text.value()));
515
+ }
516
+
517
+ SELCHANGE sc;
518
+ memset(&sc, 0, sizeof(sc));
519
+ sc.chrg.cpMin = static_cast<LONG>(begin);
520
+ sc.chrg.cpMax = static_cast<LONG>(end);
521
+ sc.seltyp = (begin == end) ? SEL_EMPTY : SEL_TEXT;
522
+
523
+ LRESULT res;
524
+ winrt::check_hresult(
525
+ m_textServices->TxSendMessage(EM_SETSEL, static_cast<WPARAM>(begin), static_cast<LPARAM>(end), &res));
526
+ }
550
527
 
551
528
  m_comingFromJS = false;
552
529
  }
553
- } else {
554
- Super::HandleCommand(commandName, args);
555
530
  }
556
531
  }
557
532
 
@@ -750,12 +725,11 @@ void WindowsTextInputComponentView::OnPointerMoved(
750
725
  }
751
726
 
752
727
  void WindowsTextInputComponentView::OnKeyDown(
753
- const winrt::Microsoft::ReactNative::Composition::Input::KeyboardSource &source,
754
728
  const winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs &args) noexcept {
755
729
  // Do not forward tab keys into the TextInput, since we want that to do the tab loop instead. This aligns with WinUI
756
730
  // behavior We do forward Ctrl+Tab to the textinput.
757
731
  if (args.Key() != winrt::Windows::System::VirtualKey::Tab ||
758
- (source.GetKeyState(winrt::Windows::System::VirtualKey::Control) &
732
+ (args.KeyboardSource().GetKeyState(winrt::Windows::System::VirtualKey::Control) &
759
733
  winrt::Microsoft::UI::Input::VirtualKeyStates::Down) == winrt::Microsoft::UI::Input::VirtualKeyStates::Down) {
760
734
  WPARAM wParam = static_cast<WPARAM>(args.Key());
761
735
  LPARAM lParam = 0;
@@ -776,16 +750,15 @@ void WindowsTextInputComponentView::OnKeyDown(
776
750
  }
777
751
  }
778
752
 
779
- Super::OnKeyDown(source, args);
753
+ Super::OnKeyDown(args);
780
754
  }
781
755
 
782
756
  void WindowsTextInputComponentView::OnKeyUp(
783
- const winrt::Microsoft::ReactNative::Composition::Input::KeyboardSource &source,
784
757
  const winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs &args) noexcept {
785
758
  // Do not forward tab keys into the TextInput, since we want that to do the tab loop instead. This aligns with WinUI
786
759
  // behavior We do forward Ctrl+Tab to the textinput.
787
760
  if (args.Key() != winrt::Windows::System::VirtualKey::Tab ||
788
- (source.GetKeyState(winrt::Windows::System::VirtualKey::Control) &
761
+ (args.KeyboardSource().GetKeyState(winrt::Windows::System::VirtualKey::Control) &
789
762
  winrt::Microsoft::UI::Input::VirtualKeyStates::Down) == winrt::Microsoft::UI::Input::VirtualKeyStates::Down) {
790
763
  WPARAM wParam = static_cast<WPARAM>(args.Key());
791
764
  LPARAM lParam = 1;
@@ -807,11 +780,10 @@ void WindowsTextInputComponentView::OnKeyUp(
807
780
  }
808
781
  }
809
782
 
810
- Super::OnKeyUp(source, args);
783
+ Super::OnKeyUp(args);
811
784
  }
812
785
 
813
786
  bool WindowsTextInputComponentView::ShouldSubmit(
814
- const winrt::Microsoft::ReactNative::Composition::Input::KeyboardSource &source,
815
787
  const winrt::Microsoft::ReactNative::Composition::Input::CharacterReceivedRoutedEventArgs &args) noexcept {
816
788
  bool shouldSubmit = true;
817
789
 
@@ -824,19 +796,19 @@ bool WindowsTextInputComponentView::ShouldSubmit(
824
796
  // If 'submitKeyEvents' are supplied, use them to determine whether to emit onSubmitEditing' for either
825
797
  // single-line or multi-line TextInput
826
798
  if (args.KeyCode() == '\r') {
827
- bool shiftDown = (source.GetKeyState(winrt::Windows::System::VirtualKey::Shift) &
799
+ bool shiftDown = (args.KeyboardSource().GetKeyState(winrt::Windows::System::VirtualKey::Shift) &
828
800
  winrt::Microsoft::UI::Input::VirtualKeyStates::Down) ==
829
801
  winrt::Microsoft::UI::Input::VirtualKeyStates::Down;
830
- bool ctrlDown = (source.GetKeyState(winrt::Windows::System::VirtualKey::Control) &
802
+ bool ctrlDown = (args.KeyboardSource().GetKeyState(winrt::Windows::System::VirtualKey::Control) &
831
803
  winrt::Microsoft::UI::Input::VirtualKeyStates::Down) ==
832
804
  winrt::Microsoft::UI::Input::VirtualKeyStates::Down;
833
- bool altDown = (source.GetKeyState(winrt::Windows::System::VirtualKey::Control) &
805
+ bool altDown = (args.KeyboardSource().GetKeyState(winrt::Windows::System::VirtualKey::Control) &
834
806
  winrt::Microsoft::UI::Input::VirtualKeyStates::Down) ==
835
807
  winrt::Microsoft::UI::Input::VirtualKeyStates::Down;
836
- bool metaDown = (source.GetKeyState(winrt::Windows::System::VirtualKey::LeftWindows) &
808
+ bool metaDown = (args.KeyboardSource().GetKeyState(winrt::Windows::System::VirtualKey::LeftWindows) &
837
809
  winrt::Microsoft::UI::Input::VirtualKeyStates::Down) ==
838
810
  winrt::Microsoft::UI::Input::VirtualKeyStates::Down ||
839
- (source.GetKeyState(winrt::Windows::System::VirtualKey::RightWindows) &
811
+ (args.KeyboardSource().GetKeyState(winrt::Windows::System::VirtualKey::RightWindows) &
840
812
  winrt::Microsoft::UI::Input::VirtualKeyStates::Down) ==
841
813
  winrt::Microsoft::UI::Input::VirtualKeyStates::Down;
842
814
  return (submitKeyEvent.shiftKey && shiftDown) || (submitKeyEvent.ctrlKey && ctrlDown) ||
@@ -854,18 +826,17 @@ bool WindowsTextInputComponentView::ShouldSubmit(
854
826
  }
855
827
 
856
828
  void WindowsTextInputComponentView::OnCharacterReceived(
857
- const winrt::Microsoft::ReactNative::Composition::Input::KeyboardSource &source,
858
829
  const winrt::Microsoft::ReactNative::Composition::Input::CharacterReceivedRoutedEventArgs &args) noexcept {
859
830
  // Do not forward tab keys into the TextInput, since we want that to do the tab loop instead. This aligns with WinUI
860
831
  // behavior We do forward Ctrl+Tab to the textinput.
861
832
  if ((args.KeyCode() == '\t') &&
862
- ((source.GetKeyState(winrt::Windows::System::VirtualKey::Control) &
833
+ ((args.KeyboardSource().GetKeyState(winrt::Windows::System::VirtualKey::Control) &
863
834
  winrt::Microsoft::UI::Input::VirtualKeyStates::Down) != winrt::Microsoft::UI::Input::VirtualKeyStates::Down)) {
864
835
  return;
865
836
  }
866
837
 
867
838
  // Logic for submit events
868
- if (ShouldSubmit(source, args)) {
839
+ if (ShouldSubmit(args)) {
869
840
  // call onSubmitEditing event
870
841
  if (m_eventEmitter && !m_comingFromJS) {
871
842
  auto emitter = std::static_pointer_cast<const facebook::react::WindowsTextInputEventEmitter>(m_eventEmitter);
@@ -953,6 +924,10 @@ void WindowsTextInputComponentView::onGotFocus(
953
924
  LRESULT lresult;
954
925
  DrawBlock db(*this);
955
926
  m_textServices->TxSendMessage(WM_SETFOCUS, 0, 0, &lresult);
927
+
928
+ if (windowsTextInputProps().clearTextOnFocus) {
929
+ m_textServices->TxSetText(L"");
930
+ }
956
931
  }
957
932
  }
958
933
 
@@ -987,37 +962,35 @@ void WindowsTextInputComponentView::updateProps(
987
962
  *std::static_pointer_cast<const facebook::react::WindowsTextInputProps>(oldProps ? oldProps : viewProps());
988
963
  const auto &newTextInputProps = *std::static_pointer_cast<const facebook::react::WindowsTextInputProps>(props);
989
964
 
990
- DWORD propBitsMask = 0;
991
- DWORD propBits = 0;
992
-
993
965
  Super::updateProps(props, oldProps);
994
966
 
995
967
  if (!facebook::react::floatEquality(
996
968
  oldTextInputProps.textAttributes.fontSize, newTextInputProps.textAttributes.fontSize) ||
969
+ (oldTextInputProps.textAttributes.allowFontScaling != newTextInputProps.textAttributes.allowFontScaling) ||
997
970
  oldTextInputProps.textAttributes.fontWeight != newTextInputProps.textAttributes.fontWeight) {
998
- propBitsMask |= TXTBIT_CHARFORMATCHANGE;
999
- propBits |= TXTBIT_CHARFORMATCHANGE;
971
+ m_propBitsMask |= TXTBIT_CHARFORMATCHANGE;
972
+ m_propBits |= TXTBIT_CHARFORMATCHANGE;
1000
973
  }
1001
974
 
1002
975
  if (oldTextInputProps.secureTextEntry != newTextInputProps.secureTextEntry) {
1003
- propBitsMask |= TXTBIT_USEPASSWORD;
976
+ m_propBitsMask |= TXTBIT_USEPASSWORD;
1004
977
  if (newTextInputProps.secureTextEntry) {
1005
- propBits |= TXTBIT_USEPASSWORD;
978
+ m_propBits |= TXTBIT_USEPASSWORD;
1006
979
  }
1007
980
  }
1008
981
 
1009
982
  if (oldTextInputProps.multiline != newTextInputProps.multiline) {
1010
983
  m_multiline = newTextInputProps.multiline;
1011
- propBitsMask |= TXTBIT_MULTILINE | TXTBIT_WORDWRAP;
984
+ m_propBitsMask |= TXTBIT_MULTILINE | TXTBIT_WORDWRAP;
1012
985
  if (newTextInputProps.multiline) {
1013
- propBits |= TXTBIT_MULTILINE | TXTBIT_WORDWRAP;
986
+ m_propBits |= TXTBIT_MULTILINE | TXTBIT_WORDWRAP;
1014
987
  }
1015
988
  }
1016
989
 
1017
990
  if (oldTextInputProps.editable != newTextInputProps.editable) {
1018
- propBitsMask |= TXTBIT_READONLY;
991
+ m_propBitsMask |= TXTBIT_READONLY;
1019
992
  if (!newTextInputProps.editable) {
1020
- propBits |= TXTBIT_READONLY;
993
+ m_propBits |= TXTBIT_READONLY;
1021
994
  }
1022
995
  }
1023
996
 
@@ -1049,62 +1022,7 @@ void WindowsTextInputComponentView::updateProps(
1049
1022
  m_submitKeyEvents.clear();
1050
1023
  }
1051
1024
 
1052
- /*
1053
- if (oldTextInputProps.textAttributes.foregroundColor != newTextInputProps.textAttributes.foregroundColor) {
1054
- if (newTextInputProps.textAttributes.foregroundColor)
1055
- m_element.Foreground(newTextInputProps.textAttributes.foregroundColor.AsWindowsBrush());
1056
- else
1057
- m_element.ClearValue(::xaml::Controls::TextBlock::ForegroundProperty());
1058
- }
1059
-
1060
- if (oldTextInputProps.textAttributes.fontStyle != newTextInputProps.textAttributes.fontStyle) {
1061
- switch (newTextInputProps.textAttributes.fontStyle.value_or(facebook::react::FontStyle::Normal)) {
1062
- case facebook::react::FontStyle::Italic:
1063
- m_element.FontStyle(winrt::Windows::UI::Text::FontStyle::Italic);
1064
- break;
1065
- case facebook::react::FontStyle::Normal:
1066
- m_element.FontStyle(winrt::Windows::UI::Text::FontStyle::Normal);
1067
- break;
1068
- case facebook::react::FontStyle::Oblique:
1069
- m_element.FontStyle(winrt::Windows::UI::Text::FontStyle::Oblique);
1070
- break;
1071
- default:
1072
- assert(false);
1073
- }
1074
- }
1075
-
1076
- if (oldTextInputProps.textAttributes.fontFamily != newTextInputProps.textAttributes.fontFamily) {
1077
- if (newTextInputProps.textAttributes.fontFamily.empty())
1078
- m_element.FontFamily(xaml::Media::FontFamily(L"Segoe UI"));
1079
- else
1080
- m_element.FontFamily(xaml::Media::FontFamily(
1081
- Microsoft::Common::Unicode::Utf8ToUtf16(newTextInputProps.textAttributes.fontFamily)));
1082
- }
1083
-
1084
- if (oldTextInputProps.allowFontScaling != newTextInputProps.allowFontScaling) {
1085
- m_element.IsTextScaleFactorEnabled(newTextInputProps.allowFontScaling);
1086
- }
1087
-
1088
- if (oldTextInputProps.selection.start != newTextInputProps.selection.start ||
1089
- oldTextInputProps.selection.end != newTextInputProps.selection.end) {
1090
- m_element.Select(
1091
- newTextInputProps.selection.start, newTextInputProps.selection.end - newTextInputProps.selection.start);
1092
- }
1093
-
1094
- if (oldTextInputProps.autoCapitalize != newTextInputProps.autoCapitalize) {
1095
- if (newTextInputProps.autoCapitalize == "characters") {
1096
- m_element.CharacterCasing(xaml::Controls::CharacterCasing::Upper);
1097
- } else { // anything else turns off autoCap (should be "None" but
1098
- // we don't support "words"/"sentences" yet)
1099
- m_element.CharacterCasing(xaml::Controls::CharacterCasing::Normal);
1100
- }
1101
- }
1102
- */
1103
-
1104
- if (propBitsMask != 0) {
1105
- DrawBlock db(*this);
1106
- winrt::check_hresult(m_textServices->OnTxPropertyBitsChange(propBitsMask, propBits));
1107
- }
1025
+ UpdatePropertyBits();
1108
1026
  }
1109
1027
 
1110
1028
  void WindowsTextInputComponentView::updateState(
@@ -1114,32 +1032,26 @@ void WindowsTextInputComponentView::updateState(
1114
1032
 
1115
1033
  if (!m_state) {
1116
1034
  assert(false && "State is `null` for <TextInput> component.");
1117
- // m_element.Text(L"");
1118
1035
  return;
1119
1036
  }
1120
1037
 
1121
- auto data = m_state->getData();
1122
-
1123
1038
  if (!oldState) {
1124
1039
  m_mostRecentEventCount = m_state->getData().mostRecentEventCount;
1125
1040
  }
1126
1041
 
1042
+ if (auto root = rootComponentView()) {
1043
+ auto fontSizeMultiplier = root->FontSizeMultiplier();
1044
+ if (fontSizeMultiplier != m_fontSizeMultiplier) {
1045
+ fontSizeMultiplier = m_fontSizeMultiplier;
1046
+ m_propBitsMask |= TXTBIT_CHARFORMATCHANGE;
1047
+ m_propBits |= TXTBIT_CHARFORMATCHANGE;
1048
+ }
1049
+ }
1050
+
1127
1051
  if (m_mostRecentEventCount == m_state->getData().mostRecentEventCount) {
1128
1052
  m_comingFromState = true;
1129
- // Only handle single/empty fragments right now -- ignore the other fragments
1130
-
1131
- LRESULT res;
1132
- CHARRANGE cr;
1133
- cr.cpMin = cr.cpMax = 0;
1134
- winrt::check_hresult(m_textServices->TxSendMessage(EM_EXGETSEL, 0, reinterpret_cast<LPARAM>(&cr), &res));
1135
-
1136
- UpdateText(
1137
- m_state->getData().attributedString.getFragments().size()
1138
- ? m_state->getData().attributedString.getFragments()[0].string
1139
- : "");
1140
-
1141
- winrt::check_hresult(
1142
- m_textServices->TxSendMessage(EM_SETSEL, static_cast<WPARAM>(cr.cpMin), static_cast<LPARAM>(cr.cpMax), &res));
1053
+ auto &fragments = m_state->getData().attributedString.getFragments();
1054
+ UpdateText(fragments.size() ? fragments[0].string : "");
1143
1055
 
1144
1056
  m_comingFromState = false;
1145
1057
  }
@@ -1159,7 +1071,8 @@ void WindowsTextInputComponentView::UpdateText(const std::string &str) noexcept
1159
1071
  winrt::check_hresult(m_textServices->TxSendMessage(
1160
1072
  EM_SETTEXTEX, reinterpret_cast<WPARAM>(&stt), reinterpret_cast<LPARAM>(str.c_str()), &res));
1161
1073
 
1162
- winrt::check_hresult(m_textServices->TxSendMessage(EM_EXGETSEL, 0, reinterpret_cast<LPARAM>(&cr), &res));
1074
+ winrt::check_hresult(
1075
+ m_textServices->TxSendMessage(EM_SETSEL, static_cast<WPARAM>(cr.cpMin), static_cast<LPARAM>(cr.cpMax), &res));
1163
1076
 
1164
1077
  // enable colored emojis
1165
1078
  winrt::check_hresult(
@@ -1222,7 +1135,7 @@ void WindowsTextInputComponentView::OnTextUpdated() noexcept {
1222
1135
  }
1223
1136
 
1224
1137
  void WindowsTextInputComponentView::OnSelectionChanged(LONG start, LONG end) noexcept {
1225
- if (m_eventEmitter /* && !m_comingFromJS ?? */) {
1138
+ if (m_eventEmitter && !m_comingFromState /* && !m_comingFromJS ?? */) {
1226
1139
  auto emitter = std::static_pointer_cast<const facebook::react::WindowsTextInputEventEmitter>(m_eventEmitter);
1227
1140
  facebook::react::WindowsTextInputEventEmitter::OnSelectionChange onSelectionChangeArgs;
1228
1141
  onSelectionChangeArgs.selection.start = start;
@@ -1253,10 +1166,39 @@ std::string WindowsTextInputComponentView::GetTextFromRichEdit() const noexcept
1253
1166
  void WindowsTextInputComponentView::FinalizeUpdates(
1254
1167
  winrt::Microsoft::ReactNative::ComponentViewUpdateMask updateMask) noexcept {
1255
1168
  Super::FinalizeUpdates(updateMask);
1256
- ensureDrawingSurface();
1257
- if (m_needsRedraw) {
1258
- DrawText();
1169
+ InternalFinalize();
1170
+ }
1171
+
1172
+ void WindowsTextInputComponentView::UpdatePropertyBits() noexcept {
1173
+ if (m_propBitsMask != 0) {
1174
+ DrawBlock db(*this);
1175
+ winrt::check_hresult(m_textServices->OnTxPropertyBitsChange(m_propBitsMask, m_propBits));
1176
+ m_propBitsMask = 0;
1177
+ m_propBits = 0;
1178
+ }
1179
+ }
1180
+
1181
+ void WindowsTextInputComponentView::InternalFinalize() noexcept {
1182
+ if (m_mounted) {
1183
+ UpdatePropertyBits();
1184
+
1185
+ ensureDrawingSurface();
1186
+ if (m_needsRedraw) {
1187
+ DrawText();
1188
+ }
1189
+ }
1190
+ }
1191
+
1192
+ void WindowsTextInputComponentView::onMounted() noexcept {
1193
+ Super::onMounted();
1194
+
1195
+ auto fontSizeMultiplier = rootComponentView()->FontSizeMultiplier();
1196
+ if (m_fontSizeMultiplier != fontSizeMultiplier) {
1197
+ m_fontSizeMultiplier = fontSizeMultiplier;
1198
+ m_propBitsMask |= TXTBIT_CHARFORMATCHANGE;
1199
+ m_propBits |= TXTBIT_CHARFORMATCHANGE;
1259
1200
  }
1201
+ InternalFinalize();
1260
1202
  }
1261
1203
 
1262
1204
  std::optional<std::string> WindowsTextInputComponentView::getAcccessiblityValue() noexcept {
@@ -1301,9 +1243,9 @@ void WindowsTextInputComponentView::UpdateCharFormat() noexcept {
1301
1243
 
1302
1244
  // set font size -- 15 to convert twips to pt
1303
1245
  const auto &props = windowsTextInputProps();
1304
- float fontSize = props.textAttributes.fontSize;
1305
- if (std::isnan(fontSize))
1306
- fontSize = facebook::react::TextAttributes::defaultTextAttributes().fontSize;
1246
+ float fontSize = m_fontSizeMultiplier *
1247
+ (std::isnan(props.textAttributes.fontSize) ? facebook::react::TextAttributes::defaultTextAttributes().fontSize
1248
+ : props.textAttributes.fontSize);
1307
1249
  // TODO get fontSize from props.textAttributes, or defaultTextAttributes, or fragment?
1308
1250
  cfNew.dwMask |= CFM_SIZE;
1309
1251
  cfNew.yHeight = static_cast<LONG>(fontSize * 15);
@@ -1370,8 +1312,8 @@ void WindowsTextInputComponentView::ensureDrawingSurface() noexcept {
1370
1312
  winrt::Windows::Graphics::DirectX::DirectXPixelFormat::B8G8R8A8UIntNormalized,
1371
1313
  winrt::Windows::Graphics::DirectX::DirectXAlphaMode::Premultiplied);
1372
1314
 
1373
- m_rcClient = getClientRect();
1374
- winrt::check_hresult(m_textServices->OnTxInPlaceActivate(&m_rcClient));
1315
+ auto rc = getClientRect();
1316
+ winrt::check_hresult(m_textServices->OnTxInPlaceActivate(&rc));
1375
1317
 
1376
1318
  LRESULT lresult;
1377
1319
  winrt::check_hresult(
@@ -1401,6 +1343,7 @@ winrt::com_ptr<::IDWriteTextLayout> WindowsTextInputComponentView::CreatePlaceho
1401
1343
  if (std::isnan(props.textAttributes.fontSize)) {
1402
1344
  textAttributes.fontSize = 12.0f;
1403
1345
  }
1346
+ textAttributes.fontSizeMultiplier = m_fontSizeMultiplier;
1404
1347
  fragment1.string = props.placeholder;
1405
1348
  fragment1.textAttributes = textAttributes;
1406
1349
  attributedString.appendFragment(fragment1);
@@ -1450,7 +1393,11 @@ void WindowsTextInputComponentView::DrawText() noexcept {
1450
1393
  static_cast<LONG>(offset.x) + static_cast<LONG>(m_imgWidth),
1451
1394
  static_cast<LONG>(offset.y) + static_cast<LONG>(m_imgHeight)};
1452
1395
 
1453
- winrt::check_hresult(m_textServices->OnTxInPlaceActivate(&rcClient));
1396
+ {
1397
+ m_cDrawBlock++; // Dont use AutoDrawBlock as we are already in draw, and dont need to draw again.
1398
+ winrt::check_hresult(m_textServices->OnTxInPlaceActivate(&rcClient));
1399
+ m_cDrawBlock--;
1400
+ }
1454
1401
 
1455
1402
  const auto &props = windowsTextInputProps();
1456
1403
  if (facebook::react::isColorMeaningful(props.backgroundColor)) {
@@ -1529,4 +1476,4 @@ winrt::Microsoft::ReactNative::ComponentView WindowsTextInputComponentView::Crea
1529
1476
  return winrt::make<WindowsTextInputComponentView>(compContext, tag, reactContext);
1530
1477
  }
1531
1478
 
1532
- } // namespace winrt::Microsoft::ReactNative::Composition::implementation
1479
+ } // namespace winrt::Microsoft::ReactNative::Composition::implementation
@@ -46,8 +46,7 @@ struct WindowsTextInputComponentView
46
46
  void FinalizeUpdates(winrt::Microsoft::ReactNative::ComponentViewUpdateMask updateMask) noexcept override;
47
47
  static facebook::react::SharedViewProps defaultProps() noexcept;
48
48
  const facebook::react::WindowsTextInputProps &windowsTextInputProps() const noexcept;
49
- void HandleCommand(winrt::hstring commandName, const winrt::Microsoft::ReactNative::IJSValueReader &args) noexcept
50
- override;
49
+ void HandleCommand(const winrt::Microsoft::ReactNative::HandleCommandArgs &args) noexcept override;
51
50
  void OnRenderingDeviceLost() noexcept override;
52
51
  void onLostFocus(const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept override;
53
52
  void onGotFocus(const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept override;
@@ -62,16 +61,11 @@ struct WindowsTextInputComponentView
62
61
  void OnPointerMoved(
63
62
  const winrt::Microsoft::ReactNative::Composition::Input::PointerRoutedEventArgs &args) noexcept override;
64
63
 
65
- void OnKeyDown(
66
- const winrt::Microsoft::ReactNative::Composition::Input::KeyboardSource &source,
67
- const winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs &args) noexcept override;
68
- void OnKeyUp(
69
- const winrt::Microsoft::ReactNative::Composition::Input::KeyboardSource &source,
70
- const winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs &args) noexcept override;
71
- void OnCharacterReceived(
72
- const winrt::Microsoft::ReactNative::Composition::Input::KeyboardSource &source,
73
- const winrt::Microsoft::ReactNative::Composition::Input::CharacterReceivedRoutedEventArgs &args) noexcept
74
- override;
64
+ void OnKeyDown(const winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs &args) noexcept override;
65
+ void OnKeyUp(const winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs &args) noexcept override;
66
+ void OnCharacterReceived(const winrt::Microsoft::ReactNative::Composition::Input::CharacterReceivedRoutedEventArgs
67
+ &args) noexcept override;
68
+ void onMounted() noexcept override;
75
69
 
76
70
  std::optional<std::string> getAcccessiblityValue() noexcept override;
77
71
  void setAcccessiblityValue(std::string &&value) noexcept override;
@@ -106,8 +100,9 @@ struct WindowsTextInputComponentView
106
100
  const facebook::react::SharedColor &cursorColor,
107
101
  const facebook::react::SharedColor &foregroundColor) noexcept;
108
102
  bool ShouldSubmit(
109
- const winrt::Microsoft::ReactNative::Composition::Input::KeyboardSource &source,
110
103
  const winrt::Microsoft::ReactNative::Composition::Input::CharacterReceivedRoutedEventArgs &args) noexcept;
104
+ void InternalFinalize() noexcept;
105
+ void UpdatePropertyBits() noexcept;
111
106
 
112
107
  winrt::Windows::UI::Composition::CompositionSurfaceBrush m_brush{nullptr};
113
108
  winrt::Microsoft::ReactNative::Composition::Experimental::ICaretVisual m_caretVisual{nullptr};
@@ -121,7 +116,7 @@ struct WindowsTextInputComponentView
121
116
  winrt::com_ptr<ITextServices2> m_textServices;
122
117
  unsigned int m_imgWidth{0}, m_imgHeight{0};
123
118
  std::shared_ptr<facebook::react::WindowsTextInputShadowNode::ConcreteState const> m_state;
124
- RECT m_rcClient;
119
+ float m_fontSizeMultiplier{1.0};
125
120
  int64_t m_mostRecentEventCount{0};
126
121
  int m_nativeEventCount{0};
127
122
  bool m_comingFromJS{false};
@@ -131,6 +126,8 @@ struct WindowsTextInputComponentView
131
126
  bool m_drawing{false};
132
127
  bool m_clearTextOnSubmit{false};
133
128
  bool m_multiline{false};
129
+ DWORD m_propBitsMask{0};
130
+ DWORD m_propBits{0};
134
131
  std::vector<facebook::react::CompWindowsTextInputSubmitKeyEventsStruct> m_submitKeyEvents;
135
132
  };
136
133