Reland "Add new pointer signal for cancelling scroll inertia" (flutter/engine#34537)

This commit is contained in:
Callum Moffat 2022-07-13 23:14:04 -04:00 committed by GitHub
parent 9d17589319
commit 0941daa6de
9 changed files with 120 additions and 101 deletions

View File

@ -129,6 +129,9 @@ enum PointerSignalKind {
/// A pointer-generated scroll (e.g., mouse wheel or trackpad scroll).
scroll,
/// A pointer-generated scroll-inertia cancel.
scrollInertiaCancel,
/// An unknown pointer signal kind.
unknown
}

View File

@ -60,6 +60,7 @@ struct alignas(8) PointerData {
enum class SignalKind : int64_t {
kNone,
kScroll,
kScrollInertiaCancel,
};
int64_t embedder_id;

View File

@ -297,7 +297,8 @@ void PointerDataPacketConverter::ConvertPointerData(
}
} else {
switch (pointer_data.signal_kind) {
case PointerData::SignalKind::kScroll: {
case PointerData::SignalKind::kScroll:
case PointerData::SignalKind::kScrollInertiaCancel: {
// Makes sure we have an existing pointer
auto iter = states_.find(pointer_data.device);
PointerState state;

View File

@ -554,114 +554,117 @@ TEST(PointerDataPacketConverterTest, CanHandleThreeFingerGesture) {
// Third cancel should be dropped
}
TEST(PointerDataPacketConverterTest, CanConvetScroll) {
PointerDataPacketConverter converter;
auto packet = std::make_unique<PointerDataPacket>(6);
PointerData data;
CreateSimulatedMousePointerData(data, PointerData::Change::kAdd,
PointerData::SignalKind::kNone, 0, 0.0, 0.0,
0.0, 0.0, 0);
packet->SetPointerData(0, data);
CreateSimulatedMousePointerData(data, PointerData::Change::kAdd,
PointerData::SignalKind::kNone, 1, 0.0, 0.0,
0.0, 0.0, 0);
packet->SetPointerData(1, data);
CreateSimulatedMousePointerData(data, PointerData::Change::kDown,
PointerData::SignalKind::kNone, 1, 0.0, 0.0,
0.0, 0.0, 1);
packet->SetPointerData(2, data);
CreateSimulatedMousePointerData(data, PointerData::Change::kHover,
PointerData::SignalKind::kScroll, 0, 34.0,
34.0, 30.0, 0.0, 0);
packet->SetPointerData(3, data);
CreateSimulatedMousePointerData(data, PointerData::Change::kHover,
PointerData::SignalKind::kScroll, 1, 49.0,
49.0, 50.0, 0.0, 0);
packet->SetPointerData(4, data);
CreateSimulatedMousePointerData(data, PointerData::Change::kHover,
PointerData::SignalKind::kScroll, 2, 10.0,
20.0, 30.0, 40.0, 0);
packet->SetPointerData(5, data);
auto converted_packet = converter.Convert(std::move(packet));
TEST(PointerDataPacketConverterTest, CanConvertPointerSignals) {
PointerData::SignalKind signal_kinds[] = {
PointerData::SignalKind::kScroll,
PointerData::SignalKind::kScrollInertiaCancel,
};
for (const PointerData::SignalKind& kind : signal_kinds) {
PointerDataPacketConverter converter;
auto packet = std::make_unique<PointerDataPacket>(6);
PointerData data;
CreateSimulatedMousePointerData(data, PointerData::Change::kAdd,
PointerData::SignalKind::kNone, 0, 0.0, 0.0,
0.0, 0.0, 0);
packet->SetPointerData(0, data);
CreateSimulatedMousePointerData(data, PointerData::Change::kAdd,
PointerData::SignalKind::kNone, 1, 0.0, 0.0,
0.0, 0.0, 0);
packet->SetPointerData(1, data);
CreateSimulatedMousePointerData(data, PointerData::Change::kDown,
PointerData::SignalKind::kNone, 1, 0.0, 0.0,
0.0, 0.0, 1);
packet->SetPointerData(2, data);
CreateSimulatedMousePointerData(data, PointerData::Change::kHover, kind, 0,
34.0, 34.0, 30.0, 0.0, 0);
packet->SetPointerData(3, data);
CreateSimulatedMousePointerData(data, PointerData::Change::kHover, kind, 1,
49.0, 49.0, 50.0, 0.0, 0);
packet->SetPointerData(4, data);
CreateSimulatedMousePointerData(data, PointerData::Change::kHover, kind, 2,
10.0, 20.0, 30.0, 40.0, 0);
packet->SetPointerData(5, data);
auto converted_packet = converter.Convert(std::move(packet));
std::vector<PointerData> result;
UnpackPointerPacket(result, std::move(converted_packet));
std::vector<PointerData> result;
UnpackPointerPacket(result, std::move(converted_packet));
ASSERT_EQ(result.size(), (size_t)9);
ASSERT_EQ(result[0].change, PointerData::Change::kAdd);
ASSERT_EQ(result[0].signal_kind, PointerData::SignalKind::kNone);
ASSERT_EQ(result[0].device, 0);
ASSERT_EQ(result[0].physical_x, 0.0);
ASSERT_EQ(result[0].physical_y, 0.0);
ASSERT_EQ(result[0].synthesized, 0);
ASSERT_EQ(result.size(), (size_t)9);
ASSERT_EQ(result[0].change, PointerData::Change::kAdd);
ASSERT_EQ(result[0].signal_kind, PointerData::SignalKind::kNone);
ASSERT_EQ(result[0].device, 0);
ASSERT_EQ(result[0].physical_x, 0.0);
ASSERT_EQ(result[0].physical_y, 0.0);
ASSERT_EQ(result[0].synthesized, 0);
ASSERT_EQ(result[1].change, PointerData::Change::kAdd);
ASSERT_EQ(result[1].signal_kind, PointerData::SignalKind::kNone);
ASSERT_EQ(result[1].device, 1);
ASSERT_EQ(result[1].physical_x, 0.0);
ASSERT_EQ(result[1].physical_y, 0.0);
ASSERT_EQ(result[1].synthesized, 0);
ASSERT_EQ(result[1].change, PointerData::Change::kAdd);
ASSERT_EQ(result[1].signal_kind, PointerData::SignalKind::kNone);
ASSERT_EQ(result[1].device, 1);
ASSERT_EQ(result[1].physical_x, 0.0);
ASSERT_EQ(result[1].physical_y, 0.0);
ASSERT_EQ(result[1].synthesized, 0);
ASSERT_EQ(result[2].change, PointerData::Change::kDown);
ASSERT_EQ(result[2].signal_kind, PointerData::SignalKind::kNone);
ASSERT_EQ(result[2].device, 1);
ASSERT_EQ(result[2].physical_x, 0.0);
ASSERT_EQ(result[2].physical_y, 0.0);
ASSERT_EQ(result[2].synthesized, 0);
ASSERT_EQ(result[2].change, PointerData::Change::kDown);
ASSERT_EQ(result[2].signal_kind, PointerData::SignalKind::kNone);
ASSERT_EQ(result[2].device, 1);
ASSERT_EQ(result[2].physical_x, 0.0);
ASSERT_EQ(result[2].physical_y, 0.0);
ASSERT_EQ(result[2].synthesized, 0);
// Converter will synthesize a hover to position for device 0.
ASSERT_EQ(result[3].change, PointerData::Change::kHover);
ASSERT_EQ(result[3].signal_kind, PointerData::SignalKind::kNone);
ASSERT_EQ(result[3].device, 0);
ASSERT_EQ(result[3].physical_x, 34.0);
ASSERT_EQ(result[3].physical_y, 34.0);
ASSERT_EQ(result[3].physical_delta_x, 34.0);
ASSERT_EQ(result[3].physical_delta_y, 34.0);
ASSERT_EQ(result[3].buttons, 0);
ASSERT_EQ(result[3].synthesized, 1);
// Converter will synthesize a hover to position for device 0.
ASSERT_EQ(result[3].change, PointerData::Change::kHover);
ASSERT_EQ(result[3].signal_kind, PointerData::SignalKind::kNone);
ASSERT_EQ(result[3].device, 0);
ASSERT_EQ(result[3].physical_x, 34.0);
ASSERT_EQ(result[3].physical_y, 34.0);
ASSERT_EQ(result[3].physical_delta_x, 34.0);
ASSERT_EQ(result[3].physical_delta_y, 34.0);
ASSERT_EQ(result[3].buttons, 0);
ASSERT_EQ(result[3].synthesized, 1);
ASSERT_EQ(result[4].change, PointerData::Change::kHover);
ASSERT_EQ(result[4].signal_kind, PointerData::SignalKind::kScroll);
ASSERT_EQ(result[4].device, 0);
ASSERT_EQ(result[4].physical_x, 34.0);
ASSERT_EQ(result[4].physical_y, 34.0);
ASSERT_EQ(result[4].scroll_delta_x, 30.0);
ASSERT_EQ(result[4].scroll_delta_y, 0.0);
ASSERT_EQ(result[4].change, PointerData::Change::kHover);
ASSERT_EQ(result[4].signal_kind, kind);
ASSERT_EQ(result[4].device, 0);
ASSERT_EQ(result[4].physical_x, 34.0);
ASSERT_EQ(result[4].physical_y, 34.0);
ASSERT_EQ(result[4].scroll_delta_x, 30.0);
ASSERT_EQ(result[4].scroll_delta_y, 0.0);
// Converter will synthesize a move to position for device 1.
ASSERT_EQ(result[5].change, PointerData::Change::kMove);
ASSERT_EQ(result[5].signal_kind, PointerData::SignalKind::kNone);
ASSERT_EQ(result[5].device, 1);
ASSERT_EQ(result[5].physical_x, 49.0);
ASSERT_EQ(result[5].physical_y, 49.0);
ASSERT_EQ(result[5].physical_delta_x, 49.0);
ASSERT_EQ(result[5].physical_delta_y, 49.0);
ASSERT_EQ(result[5].buttons, 1);
ASSERT_EQ(result[5].synthesized, 1);
// Converter will synthesize a move to position for device 1.
ASSERT_EQ(result[5].change, PointerData::Change::kMove);
ASSERT_EQ(result[5].signal_kind, PointerData::SignalKind::kNone);
ASSERT_EQ(result[5].device, 1);
ASSERT_EQ(result[5].physical_x, 49.0);
ASSERT_EQ(result[5].physical_y, 49.0);
ASSERT_EQ(result[5].physical_delta_x, 49.0);
ASSERT_EQ(result[5].physical_delta_y, 49.0);
ASSERT_EQ(result[5].buttons, 1);
ASSERT_EQ(result[5].synthesized, 1);
ASSERT_EQ(result[6].change, PointerData::Change::kHover);
ASSERT_EQ(result[6].signal_kind, PointerData::SignalKind::kScroll);
ASSERT_EQ(result[6].device, 1);
ASSERT_EQ(result[6].physical_x, 49.0);
ASSERT_EQ(result[6].physical_y, 49.0);
ASSERT_EQ(result[6].scroll_delta_x, 50.0);
ASSERT_EQ(result[6].scroll_delta_y, 0.0);
ASSERT_EQ(result[6].change, PointerData::Change::kHover);
ASSERT_EQ(result[6].signal_kind, kind);
ASSERT_EQ(result[6].device, 1);
ASSERT_EQ(result[6].physical_x, 49.0);
ASSERT_EQ(result[6].physical_y, 49.0);
ASSERT_EQ(result[6].scroll_delta_x, 50.0);
ASSERT_EQ(result[6].scroll_delta_y, 0.0);
// Converter will synthesize an add for device 2.
ASSERT_EQ(result[7].change, PointerData::Change::kAdd);
ASSERT_EQ(result[7].signal_kind, PointerData::SignalKind::kNone);
ASSERT_EQ(result[7].device, 2);
ASSERT_EQ(result[7].physical_x, 10.0);
ASSERT_EQ(result[7].physical_y, 20.0);
ASSERT_EQ(result[7].synthesized, 1);
// Converter will synthesize an add for device 2.
ASSERT_EQ(result[7].change, PointerData::Change::kAdd);
ASSERT_EQ(result[7].signal_kind, PointerData::SignalKind::kNone);
ASSERT_EQ(result[7].device, 2);
ASSERT_EQ(result[7].physical_x, 10.0);
ASSERT_EQ(result[7].physical_y, 20.0);
ASSERT_EQ(result[7].synthesized, 1);
ASSERT_EQ(result[8].change, PointerData::Change::kHover);
ASSERT_EQ(result[8].signal_kind, PointerData::SignalKind::kScroll);
ASSERT_EQ(result[8].device, 2);
ASSERT_EQ(result[8].physical_x, 10.0);
ASSERT_EQ(result[8].physical_y, 20.0);
ASSERT_EQ(result[8].scroll_delta_x, 30.0);
ASSERT_EQ(result[8].scroll_delta_y, 40.0);
ASSERT_EQ(result[8].change, PointerData::Change::kHover);
ASSERT_EQ(result[8].signal_kind, kind);
ASSERT_EQ(result[8].device, 2);
ASSERT_EQ(result[8].physical_x, 10.0);
ASSERT_EQ(result[8].physical_y, 20.0);
ASSERT_EQ(result[8].scroll_delta_x, 30.0);
ASSERT_EQ(result[8].scroll_delta_y, 40.0);
}
}
TEST(PointerDataPacketConverterTest, CanConvertTrackpadGesture) {

View File

@ -29,6 +29,7 @@ enum PointerDeviceKind {
enum PointerSignalKind {
none,
scroll,
scrollInertiaCancel,
unknown
}

View File

@ -623,6 +623,7 @@ class PointerDataConverter {
} else {
switch (signalKind) {
case ui.PointerSignalKind.scroll:
case ui.PointerSignalKind.scrollInertiaCancel:
final bool alreadyAdded = _pointers.containsKey(device);
_ensureStateForPointer(device, physicalX, physicalY);
if (!alreadyAdded) {

View File

@ -61,11 +61,17 @@ public class AndroidTouchProcessor {
}
// Must match the PointerSignalKind enum in pointer.dart.
@IntDef({PointerSignalKind.NONE, PointerSignalKind.SCROLL, PointerSignalKind.UNKNOWN})
@IntDef({
PointerSignalKind.NONE,
PointerSignalKind.SCROLL,
PointerSignalKind.SCROLL_INERTIA_CANCEL,
PointerSignalKind.UNKNOWN
})
public @interface PointerSignalKind {
int NONE = 0;
int SCROLL = 1;
int UNKNOWN = 2;
int SCROLL_INERTIA_CANCEL = 2;
int UNKNOWN = 3;
}
// Must match the unpacking code in hooks.dart.

View File

@ -1750,6 +1750,8 @@ inline flutter::PointerData::SignalKind ToPointerDataSignalKind(
return flutter::PointerData::SignalKind::kNone;
case kFlutterPointerSignalKindScroll:
return flutter::PointerData::SignalKind::kScroll;
case kFlutterPointerSignalKindScrollInertiaCancel:
return flutter::PointerData::SignalKind::kScrollInertiaCancel;
}
return flutter::PointerData::SignalKind::kNone;
}

View File

@ -773,6 +773,7 @@ typedef enum {
typedef enum {
kFlutterPointerSignalKindNone,
kFlutterPointerSignalKindScroll,
kFlutterPointerSignalKindScrollInertiaCancel,
} FlutterPointerSignalKind;
typedef struct {