@@ -1189,7 +1189,7 @@ void CompositionEventHandler::onPointerPressed(
11891189 // A previous pointer with this ID was never properly released (e.g., app lost focus,
11901190 // pointer left window). Cancel the stale touch and clean it up so the new press can proceed.
11911191 if (staleTouch->second .eventEmitter ) {
1192- DispatchTouchEvent (TouchEventType::Cancel, pointerId , pointerPoint, keyModifiers);
1192+ DispatchSynthesizedTouchCancelForActiveTouch (staleTouch-> second , pointerPoint, keyModifiers);
11931193 }
11941194 m_activeTouches.erase (staleTouch);
11951195 }
@@ -1295,7 +1295,7 @@ void CompositionEventHandler::onPointerReleased(
12951295
12961296 if (tag == -1 ) {
12971297 if (activeTouch->second .eventEmitter ) {
1298- DispatchTouchEvent (TouchEventType::Cancel, pointerId , pointerPoint, keyModifiers);
1298+ DispatchSynthesizedTouchCancelForActiveTouch (activeTouch-> second , pointerPoint, keyModifiers);
12991299 }
13001300 m_activeTouches.erase (pointerId);
13011301 return ;
@@ -1471,6 +1471,47 @@ facebook::react::PointerEvent CompositionEventHandler::CreatePointerEventFromAct
14711471 return event;
14721472}
14731473
1474+ void CompositionEventHandler::DispatchSynthesizedTouchCancelForActiveTouch (
1475+ const ActiveTouch &cancelledTouch,
1476+ const winrt::Microsoft::ReactNative::Composition::Input::PointerPoint &pointerPoint,
1477+ winrt::Windows::System::VirtualKeyModifiers keyModifiers) {
1478+ if (!cancelledTouch.eventEmitter ) {
1479+ return ;
1480+ }
1481+
1482+ facebook::react::PointerEvent pointerEvent =
1483+ CreatePointerEventFromActiveTouch (cancelledTouch, TouchEventType::Cancel);
1484+ winrt::Microsoft::ReactNative::ComponentView targetView{nullptr };
1485+ facebook::react::SharedTouchEventEmitter emitter = cancelledTouch.eventEmitter ;
1486+ auto pointerHandler = [emitter, pointerEvent](std::vector<winrt::Microsoft::ReactNative::ComponentView> &) {
1487+ emitter->onPointerCancel (pointerEvent);
1488+ };
1489+ HandleIncomingPointerEvent (pointerEvent, targetView, pointerPoint, keyModifiers, pointerHandler);
1490+
1491+ facebook::react::TouchEvent touchEvent;
1492+ touchEvent.changedTouches .insert (cancelledTouch.touch );
1493+
1494+ for (const auto &pair : m_activeTouches) {
1495+ if (!pair.second .eventEmitter || pair.second .eventEmitter != cancelledTouch.eventEmitter ) {
1496+ continue ;
1497+ }
1498+
1499+ if (touchEvent.changedTouches .find (pair.second .touch ) != touchEvent.changedTouches .end ()) {
1500+ continue ;
1501+ }
1502+
1503+ touchEvent.touches .insert (pair.second .touch );
1504+ }
1505+
1506+ for (const auto &pair : m_activeTouches) {
1507+ if (pair.second .eventEmitter == cancelledTouch.eventEmitter ) {
1508+ touchEvent.targetTouches .insert (pair.second .touch );
1509+ }
1510+ }
1511+
1512+ cancelledTouch.eventEmitter ->onTouchCancel (touchEvent);
1513+ }
1514+
14741515// If we have events that include multiple pointer updates, we should change arg from pointerId to vector<pointerId>
14751516void CompositionEventHandler::DispatchTouchEvent (
14761517 TouchEventType eventType,
0 commit comments