-
Notifications
You must be signed in to change notification settings - Fork 1.2k
[fix] touch issues #16009
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 0.82-stable
Are you sure you want to change the base?
[fix] touch issues #16009
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "type": "patch", | ||
| "comment": "Fixed: Touch screen events not properly captured for pressable and text inputs", | ||
| "packageName": "react-native-windows", | ||
| "email": "gordomacmaster@gmail.com", | ||
| "dependentChangeType": "patch" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -358,6 +358,7 @@ CompositionEventHandler::~CompositionEventHandler() { | |
| pointerSource.PointerMoved(m_pointerMovedToken); | ||
| pointerSource.PointerCaptureLost(m_pointerCaptureLostToken); | ||
| pointerSource.PointerWheelChanged(m_pointerWheelChangedToken); | ||
| pointerSource.PointerExited(m_pointerExitedToken); | ||
| auto keyboardSource = winrt::Microsoft::UI::Input::InputKeyboardSource::GetForIsland(island); | ||
| keyboardSource.KeyDown(m_keyDownToken); | ||
| keyboardSource.KeyUp(m_keyUpToken); | ||
|
|
@@ -1185,9 +1186,12 @@ void CompositionEventHandler::onPointerPressed( | |
| }); | ||
|
|
||
| if (staleTouch != m_activeTouches.end()) { | ||
| // A pointer with this ID already exists - Should we fire a button cancel or something? | ||
| // assert(false); | ||
| return; | ||
| // A previous pointer with this ID was never properly released (e.g., app lost focus, | ||
| // pointer left window). Cancel the stale touch and clean it up so the new press can proceed. | ||
| if (staleTouch->second.eventEmitter) { | ||
| DispatchSynthesizedTouchCancelForActiveTouch(staleTouch->second, pointerPoint, keyModifiers); | ||
| } | ||
| m_activeTouches.erase(staleTouch); | ||
| } | ||
|
|
||
| const auto eventType = TouchEventType::Start; | ||
|
|
@@ -1246,6 +1250,12 @@ void CompositionEventHandler::onPointerPressed( | |
| targetComponentView = targetComponentView.Parent(); | ||
| } | ||
|
|
||
| // Don't register the touch if no eventEmitter was found — inserting a null-emitter entry | ||
| // into m_activeTouches would block future presses with the same pointer ID. | ||
| if (!activeTouch.eventEmitter) { | ||
| return; | ||
| } | ||
|
|
||
| UpdateActiveTouch(activeTouch, ptScaled, ptLocal); | ||
|
|
||
| // activeTouch.touch.isPrimary = true; | ||
|
|
@@ -1283,8 +1293,13 @@ void CompositionEventHandler::onPointerReleased( | |
| facebook::react::Point ptLocal, ptScaled; | ||
| getTargetPointerArgs(fabricuiManager, pointerPoint, tag, ptScaled, ptLocal); | ||
|
|
||
| if (tag == -1) | ||
| if (tag == -1) { | ||
| if (activeTouch->second.eventEmitter) { | ||
| DispatchSynthesizedTouchCancelForActiveTouch(activeTouch->second, pointerPoint, keyModifiers); | ||
| } | ||
| m_activeTouches.erase(pointerId); | ||
| return; | ||
| } | ||
|
|
||
| auto targetComponentView = fabricuiManager->GetViewRegistry().componentViewDescriptorWithTag(tag).view; | ||
| auto args = winrt::make<winrt::Microsoft::ReactNative::Composition::Input::implementation::PointerRoutedEventArgs>( | ||
|
|
@@ -1456,6 +1471,47 @@ facebook::react::PointerEvent CompositionEventHandler::CreatePointerEventFromAct | |
| return event; | ||
| } | ||
|
|
||
| void CompositionEventHandler::DispatchSynthesizedTouchCancelForActiveTouch( | ||
| const ActiveTouch &cancelledTouch, | ||
| const winrt::Microsoft::ReactNative::Composition::Input::PointerPoint &pointerPoint, | ||
| winrt::Windows::System::VirtualKeyModifiers keyModifiers) { | ||
| if (!cancelledTouch.eventEmitter) { | ||
| return; | ||
| } | ||
|
|
||
| facebook::react::PointerEvent pointerEvent = | ||
| CreatePointerEventFromActiveTouch(cancelledTouch, TouchEventType::Cancel); | ||
| winrt::Microsoft::ReactNative::ComponentView targetView{nullptr}; | ||
| facebook::react::SharedTouchEventEmitter emitter = cancelledTouch.eventEmitter; | ||
| auto pointerHandler = [emitter, pointerEvent](std::vector<winrt::Microsoft::ReactNative::ComponentView> &) { | ||
| emitter->onPointerCancel(pointerEvent); | ||
| }; | ||
| HandleIncomingPointerEvent(pointerEvent, targetView, pointerPoint, keyModifiers, pointerHandler); | ||
|
|
||
| facebook::react::TouchEvent touchEvent; | ||
| touchEvent.changedTouches.insert(cancelledTouch.touch); | ||
|
|
||
| for (const auto &pair : m_activeTouches) { | ||
| if (!pair.second.eventEmitter || pair.second.eventEmitter != cancelledTouch.eventEmitter) { | ||
| continue; | ||
| } | ||
|
|
||
| if (touchEvent.changedTouches.find(pair.second.touch) != touchEvent.changedTouches.end()) { | ||
| continue; | ||
| } | ||
|
|
||
| touchEvent.touches.insert(pair.second.touch); | ||
| } | ||
|
|
||
| for (const auto &pair : m_activeTouches) { | ||
| if (pair.second.eventEmitter == cancelledTouch.eventEmitter) { | ||
| touchEvent.targetTouches.insert(pair.second.touch); | ||
| } | ||
| } | ||
|
Comment on lines
+1487
to
+1506
|
||
|
|
||
| cancelledTouch.eventEmitter->onTouchCancel(touchEvent); | ||
| } | ||
|
|
||
| // If we have events that include multiple pointer updates, we should change arg from pointerId to vector<pointerId> | ||
| void CompositionEventHandler::DispatchTouchEvent( | ||
| TouchEventType eventType, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -697,10 +697,14 @@ void WindowsTextInputComponentView::OnPointerPressed( | |
| wParam |= (XBUTTON2 << 16); | ||
| break; | ||
| } | ||
| wParam = PointerRoutedEventArgsToMouseWParam(args); | ||
| wParam |= PointerRoutedEventArgsToMouseWParam(args); | ||
| } else { | ||
| msg = WM_POINTERDOWN; | ||
| wParam = PointerPointToPointerWParam(pp); | ||
| if (IsDoubleClick()) { | ||
| msg = WM_LBUTTONDBLCLK; | ||
| } else { | ||
| msg = WM_LBUTTONDOWN; | ||
| } | ||
| wParam = PointerRoutedEventArgsToMouseWParam(args); | ||
| } | ||
|
|
||
| if (m_textServices && msg) { | ||
|
|
@@ -762,10 +766,10 @@ void WindowsTextInputComponentView::OnPointerReleased( | |
| wParam |= (XBUTTON2 << 16); | ||
| break; | ||
| } | ||
| wParam = PointerRoutedEventArgsToMouseWParam(args); | ||
| wParam |= PointerRoutedEventArgsToMouseWParam(args); | ||
| } else { | ||
| msg = WM_POINTERUP; | ||
| wParam = PointerPointToPointerWParam(pp); | ||
| msg = WM_LBUTTONUP; | ||
| wParam = PointerRoutedEventArgsToMouseWParam(args); | ||
| } | ||
|
|
||
| if (m_textServices && msg) { | ||
|
|
@@ -819,19 +823,19 @@ void WindowsTextInputComponentView::OnPointerMoved( | |
| msg = WM_MOUSEMOVE; | ||
| wParam = PointerRoutedEventArgsToMouseWParam(args); | ||
| } else { | ||
| msg = WM_POINTERUPDATE; | ||
| wParam = PointerPointToPointerWParam(pp); | ||
| msg = WM_MOUSEMOVE; | ||
| wParam = PointerRoutedEventArgsToMouseWParam(args); | ||
| } | ||
|
Comment on lines
822
to
828
|
||
|
|
||
| if (m_textServices) { | ||
| LRESULT lresult; | ||
| DrawBlock db(*this); | ||
| auto hr = m_textServices->TxSendMessage(msg, static_cast<WPARAM>(wParam), static_cast<LPARAM>(lParam), &lresult); | ||
| args.Handled(hr != S_FALSE); | ||
| } | ||
|
|
||
| m_textServices->OnTxSetCursor( | ||
| DVASPECT_CONTENT, -1, nullptr, nullptr, nullptr, nullptr, nullptr, ptContainer.x, ptContainer.y); | ||
| m_textServices->OnTxSetCursor( | ||
| DVASPECT_CONTENT, -1, nullptr, nullptr, nullptr, nullptr, nullptr, ptContainer.x, ptContainer.y); | ||
| } | ||
| } | ||
|
|
||
| void WindowsTextInputComponentView::OnPointerWheelChanged( | ||
|
|
@@ -933,7 +937,7 @@ bool WindowsTextInputComponentView::ShouldSubmit( | |
| bool ctrlDown = (args.KeyboardSource().GetKeyState(winrt::Windows::System::VirtualKey::Control) & | ||
| winrt::Microsoft::UI::Input::VirtualKeyStates::Down) == | ||
| winrt::Microsoft::UI::Input::VirtualKeyStates::Down; | ||
| bool altDown = (args.KeyboardSource().GetKeyState(winrt::Windows::System::VirtualKey::Control) & | ||
| bool altDown = (args.KeyboardSource().GetKeyState(winrt::Windows::System::VirtualKey::Menu) & | ||
| winrt::Microsoft::UI::Input::VirtualKeyStates::Down) == | ||
| winrt::Microsoft::UI::Input::VirtualKeyStates::Down; | ||
| bool metaDown = (args.KeyboardSource().GetKeyState(winrt::Windows::System::VirtualKey::LeftWindows) & | ||
|
|
@@ -944,7 +948,7 @@ bool WindowsTextInputComponentView::ShouldSubmit( | |
| winrt::Microsoft::UI::Input::VirtualKeyStates::Down; | ||
| return (submitKeyEvent.shiftKey && shiftDown) || (submitKeyEvent.ctrlKey && ctrlDown) || | ||
| (submitKeyEvent.altKey && altDown) || (submitKeyEvent.metaKey && metaDown) || | ||
| (!submitKeyEvent.shiftKey && !submitKeyEvent.altKey && !submitKeyEvent.metaKey && !submitKeyEvent.altKey && | ||
| (!submitKeyEvent.shiftKey && !submitKeyEvent.ctrlKey && !submitKeyEvent.altKey && !submitKeyEvent.metaKey && | ||
| !shiftDown && !ctrlDown && !altDown && !metaDown); | ||
| } else { | ||
| shouldSubmit = false; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.