From 1306ea59ec26f43c43d5d3b4dabc22d006f7f571 Mon Sep 17 00:00:00 2001 From: Niklas Schulze Date: Thu, 18 Nov 2021 22:03:03 +0100 Subject: [PATCH] winuwp: Add multi-touch support (flutter/engine#28067) --- .../platform/windows/flutter_window_winuwp.cc | 42 +++++++++++++------ .../platform/windows/flutter_window_winuwp.h | 10 +++++ .../platform/windows/flutter_windows_view.h | 2 +- 3 files changed, 40 insertions(+), 14 deletions(-) diff --git a/engine/src/flutter/shell/platform/windows/flutter_window_winuwp.cc b/engine/src/flutter/shell/platform/windows/flutter_window_winuwp.cc index d8f7b55fb6..7274e1af1d 100644 --- a/engine/src/flutter/shell/platform/windows/flutter_window_winuwp.cc +++ b/engine/src/flutter/shell/platform/windows/flutter_window_winuwp.cc @@ -11,10 +11,11 @@ namespace flutter { // Multipler used to map controller velocity to an appropriate scroll input. static constexpr double kControllerScrollMultiplier = 3; -// TODO(clarkezone): Determine pointer ID in -// OnPointerPressed/OnPointerReleased/OnPointerMoved in order to support multi -// touch. See https://github.com/flutter/flutter/issues/70201 -static constexpr int32_t kDefaultPointerDeviceId = 0; +// Minimum pointer ID that gets emitted by the pointer ID generator. +static constexpr uint32_t kMinPointerId = 0; + +// Maximum pointer ID that gets emitted by the pointer ID generator. +static constexpr uint32_t kMaxPointerId = 128; // Maps a Flutter cursor name to a CoreCursor. // @@ -69,8 +70,8 @@ winrt::Windows::UI::Core::CoreCursor GetCursorByName( } // namespace FlutterWindowWinUWP::FlutterWindowWinUWP( - ABI::Windows::ApplicationModel::Core::CoreApplicationView* - applicationview) { + ABI::Windows::ApplicationModel::Core::CoreApplicationView* applicationview) + : pointer_id_generator_(kMinPointerId, kMaxPointerId) { winrt::Windows::ApplicationModel::Core::CoreApplicationView cav{nullptr}; winrt::copy_from_abi(cav, applicationview); @@ -211,9 +212,10 @@ void FlutterWindowWinUWP::OnPointerPressed( double y = GetPosY(args); FlutterPointerDeviceKind device_kind = GetPointerDeviceKind(args); FlutterPointerMouseButtons mouse_button = GetPointerMouseButton(args); + auto pointer_id = GetPointerId(args); - binding_handler_delegate_->OnPointerDown( - x, y, device_kind, kDefaultPointerDeviceId, mouse_button); + binding_handler_delegate_->OnPointerDown(x, y, device_kind, pointer_id, + mouse_button); } void FlutterWindowWinUWP::OnPointerReleased( @@ -223,9 +225,11 @@ void FlutterWindowWinUWP::OnPointerReleased( double y = GetPosY(args); FlutterPointerDeviceKind device_kind = GetPointerDeviceKind(args); FlutterPointerMouseButtons mouse_button = GetPointerMouseButton(args); + auto pointer_id = GetPointerId(args); - binding_handler_delegate_->OnPointerUp(x, y, device_kind, - kDefaultPointerDeviceId, mouse_button); + binding_handler_delegate_->OnPointerUp(x, y, device_kind, pointer_id, + mouse_button); + ReleasePointer(args); } void FlutterWindowWinUWP::OnPointerMoved( @@ -234,9 +238,9 @@ void FlutterWindowWinUWP::OnPointerMoved( double x = GetPosX(args); double y = GetPosY(args); FlutterPointerDeviceKind device_kind = GetPointerDeviceKind(args); + auto pointer_id = GetPointerId(args); - binding_handler_delegate_->OnPointerMove(x, y, device_kind, - kDefaultPointerDeviceId); + binding_handler_delegate_->OnPointerMove(x, y, device_kind, pointer_id); } void FlutterWindowWinUWP::OnPointerWheelChanged( @@ -245,9 +249,10 @@ void FlutterWindowWinUWP::OnPointerWheelChanged( double x = GetPosX(args); double y = GetPosY(args); FlutterPointerDeviceKind device_kind = GetPointerDeviceKind(args); + auto pointer_id = GetPointerId(args); int delta = args.CurrentPoint().Properties().MouseWheelDelta(); binding_handler_delegate_->OnScroll(x, y, 0, -delta, 1, device_kind, - kDefaultPointerDeviceId); + pointer_id); } double FlutterWindowWinUWP::GetPosX( @@ -304,6 +309,17 @@ FlutterPointerMouseButtons FlutterWindowWinUWP::GetPointerMouseButton( return kFlutterPointerButtonMousePrimary; } +void FlutterWindowWinUWP::ReleasePointer( + winrt::Windows::UI::Core::PointerEventArgs const& args) { + pointer_id_generator_.ReleaseNumber(args.CurrentPoint().PointerId()); +} + +uint32_t FlutterWindowWinUWP::GetPointerId( + winrt::Windows::UI::Core::PointerEventArgs const& args) { + // Generate a mapped ID in the interval [kMinPointerId, kMaxPointerId]. + return pointer_id_generator_.GetGeneratedId(args.CurrentPoint().PointerId()); +} + void FlutterWindowWinUWP::OnBoundsChanged( winrt::Windows::UI::ViewManagement::ApplicationView const& app_view, winrt::Windows::Foundation::IInspectable const&) { diff --git a/engine/src/flutter/shell/platform/windows/flutter_window_winuwp.h b/engine/src/flutter/shell/platform/windows/flutter_window_winuwp.h index 39a3eaa29f..065841fc2a 100644 --- a/engine/src/flutter/shell/platform/windows/flutter_window_winuwp.h +++ b/engine/src/flutter/shell/platform/windows/flutter_window_winuwp.h @@ -17,6 +17,7 @@ #include "flutter/shell/platform/windows/display_helper_winuwp.h" #include "flutter/shell/platform/windows/flutter_windows_view.h" #include "flutter/shell/platform/windows/game_pad_cursor_winuwp.h" +#include "flutter/shell/platform/windows/sequential_id_generator.h" namespace flutter { @@ -132,6 +133,12 @@ class FlutterWindowWinUWP : public WindowBindingHandler { FlutterPointerDeviceKind GetPointerDeviceKind( winrt::Windows::UI::Core::PointerEventArgs const& args); + // Gets the pointer ID. + uint32_t GetPointerId(winrt::Windows::UI::Core::PointerEventArgs const& args); + + // Releases the pointer from the ID generator. + void ReleasePointer(winrt::Windows::UI::Core::PointerEventArgs const& args); + // Gets the mouse button. FlutterPointerMouseButtons GetPointerMouseButton( winrt::Windows::UI::Core::PointerEventArgs const& args); @@ -170,6 +177,9 @@ class FlutterWindowWinUWP : public WindowBindingHandler { // DisplayHelper object used to determine window bounds, DPI etc. std::unique_ptr display_helper_ = {nullptr}; + + // Generates pointer IDs for pointer events. + SequentialIdGenerator pointer_id_generator_; }; } // namespace flutter diff --git a/engine/src/flutter/shell/platform/windows/flutter_windows_view.h b/engine/src/flutter/shell/platform/windows/flutter_windows_view.h index 95ccbbfd1a..c18032e709 100644 --- a/engine/src/flutter/shell/platform/windows/flutter_windows_view.h +++ b/engine/src/flutter/shell/platform/windows/flutter_windows_view.h @@ -316,7 +316,7 @@ class FlutterWindowsView : public WindowBindingHandlerDelegate, std::unique_ptr engine_; // Keeps track of pointer states in relation to the window. - std::map> pointer_states_; + std::unordered_map> pointer_states_; // The plugin registrar managing internal plugins. std::unique_ptr internal_plugin_registrar_;