diff --git a/engine/src/flutter/lib/ui/window/pointer_data.h b/engine/src/flutter/lib/ui/window/pointer_data.h index 05d91fada3..05adf06821 100644 --- a/engine/src/flutter/lib/ui/window/pointer_data.h +++ b/engine/src/flutter/lib/ui/window/pointer_data.h @@ -9,6 +9,25 @@ namespace flutter { +// Must match the button constants in events.dart. +enum PointerButtonMouse : int64_t { + kPointerButtonMousePrimary = 1 << 0, + kPointerButtonMouseSecondary = 1 << 1, + kPointerButtonMouseMiddle = 1 << 2, + kPointerButtonMouseBack = 1 << 3, + kPointerButtonMouseForward = 1 << 4, +}; + +enum PointerButtonTouch : int64_t { + kPointerButtonTouchContact = 1 << 0, +}; + +enum PointerButtonStylus : int64_t { + kPointerButtonStylusContact = 1 << 0, + kPointerButtonStylusPrimary = 1 << 1, + kPointerButtonStylusSecondary = 1 << 2, +}; + // This structure is unpacked by hooks.dart. struct alignas(8) PointerData { // Must match the PointerChange enum in pointer.dart. diff --git a/engine/src/flutter/shell/platform/embedder/embedder.cc b/engine/src/flutter/shell/platform/embedder/embedder.cc index e9b50852bb..390e938836 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder.cc +++ b/engine/src/flutter/shell/platform/embedder/embedder.cc @@ -712,6 +712,35 @@ inline flutter::PointerData::SignalKind ToPointerDataSignalKind( return flutter::PointerData::SignalKind::kNone; } +// Returns the buttons for PointerData for the given buttons and change from a +// FlutterPointerEvent. +inline int64_t ToPointerDataButtons(int64_t buttons, + flutter::PointerData::Change change) { + switch (change) { + case flutter::PointerData::Change::kDown: + case flutter::PointerData::Change::kMove: + // These kinds of change must have a non-zero `buttons`, otherwise gesture + // recognizers will ignore these events. To avoid breaking legacy + // embedders, it synthesizes a primary button when seeing `button = 0` and + // logs a warning to inform them to update. + if (buttons == 0) { + // TODO: Log a warning to inform the embedder to send the + // correct buttons. See + // https://github.com/flutter/flutter/issues/32052#issuecomment-489278965 + return flutter::kPointerButtonMousePrimary; + } + return buttons; + + case flutter::PointerData::Change::kCancel: + case flutter::PointerData::Change::kAdd: + case flutter::PointerData::Change::kRemove: + case flutter::PointerData::Change::kHover: + case flutter::PointerData::Change::kUp: + return buttons; + } + return buttons; +} + FlutterEngineResult FlutterEngineSendPointerEvent( FlutterEngine engine, const FlutterPointerEvent* pointers, @@ -738,6 +767,10 @@ FlutterEngineResult FlutterEngineSendPointerEvent( SAFE_ACCESS(current, signal_kind, kFlutterPointerSignalKindNone)); pointer_data.scroll_delta_x = SAFE_ACCESS(current, scroll_delta_x, 0.0); pointer_data.scroll_delta_y = SAFE_ACCESS(current, scroll_delta_y, 0.0); + // TODO: Change 0 to a SAFE_ACCESS to current.buttons once this + // field is added. See + // https://github.com/flutter/flutter/issues/32052#issuecomment-489278965 + pointer_data.buttons = ToPointerDataButtons(0, pointer_data.change); packet->SetPointerData(i, pointer_data); current = reinterpret_cast( reinterpret_cast(current) + current->struct_size);