react-native-windows 0.84.0-preview.6 → 0.84.0-preview.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1214,6 +1214,37 @@ void CompositionEventHandler::onPointerExited(
1214
1214
  }
1215
1215
  }
1216
1216
 
1217
+ // Windows touch pointer IDs can be arbitrarily large (e.g. 2233). React Native's JS
1218
+ // touch handler uses identifiers as array indices and warns/misbehaves for values > 20.
1219
+ // This function maps each live Windows pointer to a small identifier in [0, 19] by
1220
+ // scanning m_activeTouches for in-use slots and cycling from the last assigned index.
1221
+ // Identifier MOUSE_POINTER_ID (1) is permanently reserved for mouse and never returned here.
1222
+ int CompositionEventHandler::AllocateTouchIdentifier() noexcept {
1223
+ constexpr int kMaxTouchIdentifier = 20;
1224
+ for (int i = 0; i < kMaxTouchIdentifier; i++) {
1225
+ int candidate = (m_touchId + i) % kMaxTouchIdentifier;
1226
+ if (candidate == static_cast<int>(MOUSE_POINTER_ID)) {
1227
+ continue; // reserved for mouse
1228
+ }
1229
+ bool inUse = std::any_of(m_activeTouches.begin(), m_activeTouches.end(), [candidate](const auto &pair) {
1230
+ return pair.second.touch.identifier == candidate;
1231
+ });
1232
+ if (!inUse) {
1233
+ m_touchId = (candidate + 1) % kMaxTouchIdentifier;
1234
+ return candidate;
1235
+ }
1236
+ }
1237
+ // All non-mouse slots occupied (> 19 simultaneous touch/pen points) — wrap anyway,
1238
+ // skipping the mouse-reserved slot.
1239
+ int fallback = m_touchId;
1240
+ m_touchId = (m_touchId + 1) % kMaxTouchIdentifier;
1241
+ if (fallback == static_cast<int>(MOUSE_POINTER_ID)) {
1242
+ fallback = m_touchId;
1243
+ m_touchId = (m_touchId + 1) % kMaxTouchIdentifier;
1244
+ }
1245
+ return fallback;
1246
+ }
1247
+
1217
1248
  void CompositionEventHandler::onPointerPressed(
1218
1249
  const winrt::Microsoft::ReactNative::Composition::Input::PointerPoint &pointerPoint,
1219
1250
  winrt::Windows::System::VirtualKeyModifiers keyModifiers) noexcept {
@@ -1322,11 +1353,18 @@ void CompositionEventHandler::onPointerPressed(
1322
1353
  UpdateActiveTouch(activeTouch, ptScaled, ptLocal);
1323
1354
 
1324
1355
  activeTouch.isPrimary = pointerId == 1;
1325
- activeTouch.touch.identifier = pointerId;
1356
+ // Map the Windows pointer ID to a small identifier (0–19) safe for use as a JS array index.
1357
+ // Windows touch IDs can be arbitrarily large (e.g. 2233), which causes React Native to warn
1358
+ // and corrupts touch state, leaving Pressables stuck after a scroll.
1359
+ // Mouse pointer ID is always 1 (MOUSE_POINTER_ID), which is already within the safe range —
1360
+ // use it directly to preserve stable, predictable identifier assignment for mouse input.
1361
+ activeTouch.touch.identifier = (pointerPoint.PointerDeviceType() == Composition::Input::PointerDeviceType::Mouse)
1362
+ ? static_cast<int>(MOUSE_POINTER_ID)
1363
+ : AllocateTouchIdentifier();
1326
1364
 
1327
1365
  // If the pointer has not been marked as hovering over views before the touch started, we register
1328
1366
  // that the activeTouch should not maintain its hovered state once the pointer has been lifted.
1329
- auto currentlyHoveredTags = m_currentlyHoveredViewsPerPointer.find(activeTouch.touch.identifier);
1367
+ auto currentlyHoveredTags = m_currentlyHoveredViewsPerPointer.find(pointerId);
1330
1368
  if (currentlyHoveredTags == m_currentlyHoveredViewsPerPointer.end() || currentlyHoveredTags->second.empty()) {
1331
1369
  activeTouch.shouldLeaveWhenReleased = true;
1332
1370
  }
@@ -1641,7 +1679,7 @@ void CompositionEventHandler::DispatchTouchEvent(
1641
1679
  continue;
1642
1680
  }
1643
1681
 
1644
- if (activeTouch.touch.identifier == pointerId) {
1682
+ if (pair.first == pointerId) {
1645
1683
  event.changedTouches.insert(activeTouch.touch);
1646
1684
  }
1647
1685
  uniqueEventEmitters.insert(activeTouch.eventEmitter);
@@ -162,8 +162,13 @@ class CompositionEventHandler : public std::enable_shared_from_this<CompositionE
162
162
  void UpdateCursor() noexcept;
163
163
  void SetCursor(facebook::react::Cursor cursor, HCURSOR hcur) noexcept;
164
164
 
165
+ // Allocates a small touch identifier (0–19) that is safe to use as a JS array index.
166
+ // Windows pointer IDs can be arbitrarily large, which causes React Native to warn and
167
+ // back-fill huge arrays, corrupting touch state after scrolling.
168
+ int AllocateTouchIdentifier() noexcept;
169
+
165
170
  std::map<PointerId, ActiveTouch> m_activeTouches; // iOS is map of touch event args to ActiveTouch..?
166
- PointerId m_touchId = 0;
171
+ int m_touchId = 0; // cycling base used by AllocateTouchIdentifier
167
172
 
168
173
  std::map<PointerId, std::vector<ReactTaggedView>> m_currentlyHoveredViewsPerPointer;
169
174
  winrt::weak_ref<winrt::Microsoft::ReactNative::ReactNativeIsland> m_wkRootView;
@@ -10,11 +10,11 @@
10
10
  -->
11
11
  <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
12
12
  <PropertyGroup>
13
- <ReactNativeWindowsVersion>0.84.0-preview.6</ReactNativeWindowsVersion>
13
+ <ReactNativeWindowsVersion>0.84.0-preview.7</ReactNativeWindowsVersion>
14
14
  <ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
15
15
  <ReactNativeWindowsMinor>84</ReactNativeWindowsMinor>
16
16
  <ReactNativeWindowsPatch>0</ReactNativeWindowsPatch>
17
17
  <ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
18
- <ReactNativeWindowsCommitId>91ceaa8418a39db986927aaaff0cdd07dbf9ba2e</ReactNativeWindowsCommitId>
18
+ <ReactNativeWindowsCommitId>4c8074d47d675aee1d2110c5b92e9e349bfa1abb</ReactNativeWindowsCommitId>
19
19
  </PropertyGroup>
20
20
  </Project>
@@ -6,7 +6,7 @@
6
6
  <!-- Enabling this will (1) Include hermes glues in the Microsoft.ReactNative binaries AND (2) Make hermes the default engine -->
7
7
  <UseHermes Condition="'$(UseHermes)' == ''">true</UseHermes>
8
8
  <!-- This will be true if (1) the client want to use hermes by setting UseHermes to true OR (2) We are building for UWP where dynamic switching is enabled -->
9
- <HermesVersion Condition="'$(HermesVersion)' == ''">0.0.0-2512.22001-bc3d0ed7</HermesVersion>
9
+ <HermesVersion Condition="'$(HermesVersion)' == ''">0.0.0-2604.21001-94aa5e1d</HermesVersion>
10
10
  <HermesPackageName Condition="'$(HermesPackageName)' == ''">Microsoft.JavaScript.Hermes</HermesPackageName>
11
11
  <HermesPackage Condition="'$(HermesPackage)' == '' And Exists('$(PkgMicrosoft_JavaScript_Hermes)')">$(PkgMicrosoft_JavaScript_Hermes)</HermesPackage>
12
12
  <HermesPackage Condition="'$(HermesPackage)' == ''">$(NuGetPackageRoot)\$(HermesPackageName)\$(HermesVersion)</HermesPackage>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-windows",
3
- "version": "0.84.0-preview.6",
3
+ "version": "0.84.0-preview.7",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",