react-native-windows 0.84.0-preview.6 → 0.84.0-preview.9
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/Fabric/Composition/CompositionEventHandler.cpp +56 -4
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +6 -1
- package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp +4 -0
- package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h +1 -0
- package/PropertySheets/Generated/PackageVersion.g.props +2 -2
- package/PropertySheets/JSEngine.props +1 -1
- package/package.json +1 -1
|
@@ -1092,12 +1092,26 @@ void CompositionEventHandler::onPointerCaptureLost(
|
|
|
1092
1092
|
if (SurfaceId() == -1)
|
|
1093
1093
|
return;
|
|
1094
1094
|
|
|
1095
|
-
if (m_pointerCapturingComponentTag) {
|
|
1095
|
+
if (m_pointerCapturingComponentTag != -1) {
|
|
1096
1096
|
// copy array to avoid iterator being invalidated during deletion
|
|
1097
1097
|
std::unordered_set<PointerId> capturedPointers = m_capturedPointers;
|
|
1098
1098
|
|
|
1099
1099
|
for (auto pointerId : capturedPointers) {
|
|
1100
1100
|
releasePointerCapture(pointerId, m_pointerCapturingComponentTag);
|
|
1101
|
+
|
|
1102
|
+
// Cancel any active touch for this pointer so React Native is notified that
|
|
1103
|
+
// the touch ended. Without this, m_activeTouches retains a zombie entry and
|
|
1104
|
+
// RN JS is never told the touch is gone — leaving Pressables stuck in a
|
|
1105
|
+
// pressed state after a system-interrupted gesture (e.g. system back swipe,
|
|
1106
|
+
// Alt+Tab, another window coming foreground).
|
|
1107
|
+
auto activeTouch = m_activeTouches.find(pointerId);
|
|
1108
|
+
if (activeTouch != m_activeTouches.end()) {
|
|
1109
|
+
ActiveTouch cancelledTouchCopy = std::move(activeTouch->second);
|
|
1110
|
+
m_activeTouches.erase(activeTouch);
|
|
1111
|
+
if (cancelledTouchCopy.eventEmitter) {
|
|
1112
|
+
DispatchSynthesizedTouchCancelForActiveTouch(cancelledTouchCopy, pointerPoint, keyModifiers);
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1101
1115
|
}
|
|
1102
1116
|
|
|
1103
1117
|
m_pointerCapturingComponentTag = -1;
|
|
@@ -1214,6 +1228,37 @@ void CompositionEventHandler::onPointerExited(
|
|
|
1214
1228
|
}
|
|
1215
1229
|
}
|
|
1216
1230
|
|
|
1231
|
+
// Windows touch pointer IDs can be arbitrarily large (e.g. 2233). React Native's JS
|
|
1232
|
+
// touch handler uses identifiers as array indices and warns/misbehaves for values > 20.
|
|
1233
|
+
// This function maps each live Windows pointer to a small identifier in [0, 19] by
|
|
1234
|
+
// scanning m_activeTouches for in-use slots and cycling from the last assigned index.
|
|
1235
|
+
// Identifier MOUSE_POINTER_ID (1) is permanently reserved for mouse and never returned here.
|
|
1236
|
+
int CompositionEventHandler::AllocateTouchIdentifier() noexcept {
|
|
1237
|
+
constexpr int kMaxTouchIdentifier = 20;
|
|
1238
|
+
for (int i = 0; i < kMaxTouchIdentifier; i++) {
|
|
1239
|
+
int candidate = (m_touchId + i) % kMaxTouchIdentifier;
|
|
1240
|
+
if (candidate == static_cast<int>(MOUSE_POINTER_ID)) {
|
|
1241
|
+
continue; // reserved for mouse
|
|
1242
|
+
}
|
|
1243
|
+
bool inUse = std::any_of(m_activeTouches.begin(), m_activeTouches.end(), [candidate](const auto &pair) {
|
|
1244
|
+
return pair.second.touch.identifier == candidate;
|
|
1245
|
+
});
|
|
1246
|
+
if (!inUse) {
|
|
1247
|
+
m_touchId = (candidate + 1) % kMaxTouchIdentifier;
|
|
1248
|
+
return candidate;
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
// All non-mouse slots occupied (> 19 simultaneous touch/pen points) — wrap anyway,
|
|
1252
|
+
// skipping the mouse-reserved slot.
|
|
1253
|
+
int fallback = m_touchId;
|
|
1254
|
+
m_touchId = (m_touchId + 1) % kMaxTouchIdentifier;
|
|
1255
|
+
if (fallback == static_cast<int>(MOUSE_POINTER_ID)) {
|
|
1256
|
+
fallback = m_touchId;
|
|
1257
|
+
m_touchId = (m_touchId + 1) % kMaxTouchIdentifier;
|
|
1258
|
+
}
|
|
1259
|
+
return fallback;
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1217
1262
|
void CompositionEventHandler::onPointerPressed(
|
|
1218
1263
|
const winrt::Microsoft::ReactNative::Composition::Input::PointerPoint &pointerPoint,
|
|
1219
1264
|
winrt::Windows::System::VirtualKeyModifiers keyModifiers) noexcept {
|
|
@@ -1322,11 +1367,18 @@ void CompositionEventHandler::onPointerPressed(
|
|
|
1322
1367
|
UpdateActiveTouch(activeTouch, ptScaled, ptLocal);
|
|
1323
1368
|
|
|
1324
1369
|
activeTouch.isPrimary = pointerId == 1;
|
|
1325
|
-
|
|
1370
|
+
// Map the Windows pointer ID to a small identifier (0–19) safe for use as a JS array index.
|
|
1371
|
+
// Windows touch IDs can be arbitrarily large (e.g. 2233), which causes React Native to warn
|
|
1372
|
+
// and corrupts touch state, leaving Pressables stuck after a scroll.
|
|
1373
|
+
// Mouse pointer ID is always 1 (MOUSE_POINTER_ID), which is already within the safe range —
|
|
1374
|
+
// use it directly to preserve stable, predictable identifier assignment for mouse input.
|
|
1375
|
+
activeTouch.touch.identifier = (pointerPoint.PointerDeviceType() == Composition::Input::PointerDeviceType::Mouse)
|
|
1376
|
+
? static_cast<int>(MOUSE_POINTER_ID)
|
|
1377
|
+
: AllocateTouchIdentifier();
|
|
1326
1378
|
|
|
1327
1379
|
// If the pointer has not been marked as hovering over views before the touch started, we register
|
|
1328
1380
|
// that the activeTouch should not maintain its hovered state once the pointer has been lifted.
|
|
1329
|
-
auto currentlyHoveredTags = m_currentlyHoveredViewsPerPointer.find(
|
|
1381
|
+
auto currentlyHoveredTags = m_currentlyHoveredViewsPerPointer.find(pointerId);
|
|
1330
1382
|
if (currentlyHoveredTags == m_currentlyHoveredViewsPerPointer.end() || currentlyHoveredTags->second.empty()) {
|
|
1331
1383
|
activeTouch.shouldLeaveWhenReleased = true;
|
|
1332
1384
|
}
|
|
@@ -1641,7 +1693,7 @@ void CompositionEventHandler::DispatchTouchEvent(
|
|
|
1641
1693
|
continue;
|
|
1642
1694
|
}
|
|
1643
1695
|
|
|
1644
|
-
if (
|
|
1696
|
+
if (pair.first == pointerId) {
|
|
1645
1697
|
event.changedTouches.insert(activeTouch.touch);
|
|
1646
1698
|
}
|
|
1647
1699
|
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
|
-
|
|
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;
|
|
@@ -130,6 +130,7 @@ void ImageComponentView::didReceiveImage(const std::shared_ptr<ImageResponseImag
|
|
|
130
130
|
#endif
|
|
131
131
|
|
|
132
132
|
m_imageResponseImage = imageResponseImage;
|
|
133
|
+
m_requiresImageRedraw = true;
|
|
133
134
|
ensureDrawingSurface();
|
|
134
135
|
}
|
|
135
136
|
|
|
@@ -310,6 +311,9 @@ void ImageComponentView::ensureDrawingSurface() noexcept {
|
|
|
310
311
|
} else if (m_imageResponseImage->m_brushFactory) {
|
|
311
312
|
Visual().as<Experimental::ISpriteVisual>().Brush(
|
|
312
313
|
m_imageResponseImage->m_brushFactory(m_reactContext.Handle(), m_compContext));
|
|
314
|
+
} else if (m_requiresImageRedraw) {
|
|
315
|
+
m_requiresImageRedraw = false;
|
|
316
|
+
DrawImage();
|
|
313
317
|
}
|
|
314
318
|
}
|
|
315
319
|
|
|
@@ -96,6 +96,7 @@ struct ImageComponentView : ImageComponentViewT<ImageComponentView, ViewComponen
|
|
|
96
96
|
winrt::Microsoft::ReactNative::Composition::Experimental::IDrawingSurfaceBrush m_drawingSurface;
|
|
97
97
|
std::shared_ptr<ImageResponseImage> m_imageResponseImage;
|
|
98
98
|
std::shared_ptr<WindowsImageResponseObserver> m_imageResponseObserver;
|
|
99
|
+
bool m_requiresImageRedraw{true};
|
|
99
100
|
facebook::react::ImageShadowNode::ConcreteState::Shared m_state;
|
|
100
101
|
};
|
|
101
102
|
|
|
@@ -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.
|
|
13
|
+
<ReactNativeWindowsVersion>0.84.0-preview.9</ReactNativeWindowsVersion>
|
|
14
14
|
<ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
|
|
15
15
|
<ReactNativeWindowsMinor>84</ReactNativeWindowsMinor>
|
|
16
16
|
<ReactNativeWindowsPatch>0</ReactNativeWindowsPatch>
|
|
17
17
|
<ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
|
|
18
|
-
<ReactNativeWindowsCommitId>
|
|
18
|
+
<ReactNativeWindowsCommitId>724a8ddbf9f6996e42bbab42ae4e642efaffe27f</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-
|
|
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>
|