Unverified Commit 1ae32fac authored by Tong Mu's avatar Tong Mu Committed by GitHub

Correctly synthesise event buttons (#30535)

* Correctly synthesise buttons, and add tests
parent 8e3906a2
......@@ -40,6 +40,22 @@ class _PointerState {
}
}
// Add `kPrimaryButton` to [buttons] when a pointer of certain devices is down.
//
// TODO(tongmu): This patch is supposed to be done by embedders. Patching it
// in framework is a workaround before [PointerEventConverter] is moved to embedders.
// https://github.com/flutter/flutter/issues/30454
int _synthesiseDownButtons(int buttons, PointerDeviceKind kind) {
switch (kind) {
case PointerDeviceKind.touch:
case PointerDeviceKind.stylus:
case PointerDeviceKind.invertedStylus:
return buttons | kPrimaryButton;
default:
return buttons;
}
}
/// Converts from engine pointer data to framework pointer events.
///
/// This takes [PointerDataPacket] objects, as received from the engine via
......@@ -207,8 +223,7 @@ class PointerEventConverter {
kind: kind,
device: datum.device,
position: position,
// TODO(tongmu): Move button patching to embedder, https://github.com/flutter/flutter/issues/30454
buttons: datum.buttons | kPrimaryButton,
buttons: _synthesiseDownButtons(datum.buttons, kind),
obscured: datum.obscured,
pressure: datum.pressure,
pressureMin: datum.pressureMin,
......@@ -237,8 +252,7 @@ class PointerEventConverter {
device: datum.device,
position: position,
delta: state.deltaTo(position),
// TODO(tongmu): Move button patching to embedder, https://github.com/flutter/flutter/issues/30454
buttons: datum.buttons | kPrimaryButton,
buttons: _synthesiseDownButtons(datum.buttons, kind),
obscured: datum.obscured,
pressure: datum.pressure,
pressureMin: datum.pressureMin,
......@@ -273,8 +287,7 @@ class PointerEventConverter {
device: datum.device,
position: position,
delta: state.deltaTo(position),
// TODO(tongmu): Move button patching to embedder, https://github.com/flutter/flutter/issues/30454
buttons: datum.buttons | kPrimaryButton,
buttons: _synthesiseDownButtons(datum.buttons, kind),
obscured: datum.obscured,
pressure: datum.pressure,
pressureMin: datum.pressureMin,
......@@ -421,8 +434,7 @@ class PointerEventConverter {
device: datum.device,
position: position,
delta: state.deltaTo(position),
// TODO(tongmu): Move button patching to embedder, https://github.com/flutter/flutter/issues/30454
buttons: datum.buttons | kPrimaryButton,
buttons: _synthesiseDownButtons(datum.buttons, kind),
obscured: datum.obscured,
pressure: datum.pressure,
pressureMin: datum.pressureMin,
......
......@@ -47,7 +47,6 @@ void main() {
ui.window.onPointerDataPacket(packet);
expect(events.length, 2);
expect(events[0].runtimeType, equals(PointerDownEvent));
expect(events[0].buttons, equals(1));
expect(events[1].runtimeType, equals(PointerUpEvent));
});
......@@ -66,9 +65,7 @@ void main() {
ui.window.onPointerDataPacket(packet);
expect(events.length, 3);
expect(events[0].runtimeType, equals(PointerDownEvent));
expect(events[0].buttons, equals(1));
expect(events[1].runtimeType, equals(PointerMoveEvent));
expect(events[1].buttons, equals(1));
expect(events[2].runtimeType, equals(PointerUpEvent));
});
......@@ -122,9 +119,7 @@ void main() {
ui.window.onPointerDataPacket(packet);
expect(events.length, 3);
expect(events[0].runtimeType, equals(PointerDownEvent));
expect(events[0].buttons, equals(1));
expect(events[1].runtimeType, equals(PointerMoveEvent));
expect(events[1].buttons, equals(1));
expect(events[1].delta, equals(const Offset(9.0, 12.0)));
expect(events[2].runtimeType, equals(PointerUpEvent));
});
......@@ -143,7 +138,6 @@ void main() {
ui.window.onPointerDataPacket(packet);
expect(events.length, 2);
expect(events[0].runtimeType, equals(PointerDownEvent));
expect(events[0].buttons, equals(1));
expect(events[1].runtimeType, equals(PointerCancelEvent));
});
......@@ -165,7 +159,6 @@ void main() {
ui.window.onPointerDataPacket(packet);
expect(events.length, 2);
expect(events[0].runtimeType, equals(PointerDownEvent));
expect(events[0].buttons, equals(1));
expect(events[1].runtimeType, equals(PointerCancelEvent));
});
......@@ -207,7 +200,6 @@ void main() {
expect(events[1].runtimeType, equals(PointerHoverEvent));
expect(events[1].delta, equals(const Offset(5.0, 7.0)));
expect(events[2].runtimeType, equals(PointerDownEvent));
expect(events[2].buttons, equals(1));
expect(events[3].runtimeType, equals(PointerCancelEvent));
expect(events[4].runtimeType, equals(PointerHoverEvent));
expect(events[5].runtimeType, equals(PointerRemovedEvent));
......@@ -254,10 +246,109 @@ void main() {
expect(events[2].runtimeType, equals(PointerScrollEvent));
expect(events[3].runtimeType, equals(PointerHoverEvent));
expect(events[4].runtimeType, equals(PointerDownEvent));
expect(events[4].buttons, equals(1));
expect(events[5].runtimeType, equals(PointerMoveEvent));
expect(events[5].buttons, equals(1));
expect(events[5].delta, equals(unexpectedOffset));
expect(events[6].runtimeType, equals(PointerScrollEvent));
});
test('Should synthesise kPrimaryButton for touch', () {
final Offset location = const Offset(10.0, 10.0) * ui.window.devicePixelRatio;
const PointerDeviceKind kind = PointerDeviceKind.touch;
final ui.PointerDataPacket packet = ui.PointerDataPacket(
data: <ui.PointerData>[
ui.PointerData(change: ui.PointerChange.add, kind: kind, physicalX: location.dx, physicalY: location.dy),
ui.PointerData(change: ui.PointerChange.hover, kind: kind, physicalX: location.dx, physicalY: location.dy),
ui.PointerData(change: ui.PointerChange.down, kind: kind, physicalX: location.dx, physicalY: location.dy),
ui.PointerData(change: ui.PointerChange.move, kind: kind, physicalX: location.dx, physicalY: location.dy),
ui.PointerData(change: ui.PointerChange.up, kind: kind, physicalX: location.dx, physicalY: location.dy),
]
);
final List<PointerEvent> events = PointerEventConverter.expand(
packet.data, ui.window.devicePixelRatio).toList();
expect(events.length, 5);
expect(events[0].runtimeType, equals(PointerAddedEvent));
expect(events[0].buttons, equals(0));
expect(events[1].runtimeType, equals(PointerHoverEvent));
expect(events[1].buttons, equals(0));
expect(events[2].runtimeType, equals(PointerDownEvent));
expect(events[2].buttons, equals(kPrimaryButton));
expect(events[3].runtimeType, equals(PointerMoveEvent));
expect(events[3].buttons, equals(kPrimaryButton));
expect(events[4].runtimeType, equals(PointerUpEvent));
expect(events[4].buttons, equals(0));
PointerEventConverter.clearPointers();
});
test('Should synthesise kPrimaryButton for stylus', () {
final Offset location = const Offset(10.0, 10.0) * ui.window.devicePixelRatio;
for (PointerDeviceKind kind in <PointerDeviceKind>[
PointerDeviceKind.stylus,
PointerDeviceKind.invertedStylus,
]) {
final ui.PointerDataPacket packet = ui.PointerDataPacket(
data: <ui.PointerData>[
ui.PointerData(change: ui.PointerChange.add, kind: kind, physicalX: location.dx, physicalY: location.dy),
ui.PointerData(change: ui.PointerChange.hover, kind: kind, physicalX: location.dx, physicalY: location.dy),
ui.PointerData(change: ui.PointerChange.down, kind: kind, physicalX: location.dx, physicalY: location.dy),
ui.PointerData(change: ui.PointerChange.move, buttons: kSecondaryStylusButton, kind: kind, physicalX: location.dx, physicalY: location.dy),
ui.PointerData(change: ui.PointerChange.up, kind: kind, physicalX: location.dx, physicalY: location.dy),
]
);
final List<PointerEvent> events = PointerEventConverter.expand(
packet.data, ui.window.devicePixelRatio).toList();
expect(events.length, 5);
expect(events[0].runtimeType, equals(PointerAddedEvent));
expect(events[0].buttons, equals(0));
expect(events[1].runtimeType, equals(PointerHoverEvent));
expect(events[1].buttons, equals(0));
expect(events[2].runtimeType, equals(PointerDownEvent));
expect(events[2].buttons, equals(kPrimaryButton));
expect(events[3].runtimeType, equals(PointerMoveEvent));
expect(events[3].buttons, equals(kPrimaryButton | kSecondaryStylusButton));
expect(events[4].runtimeType, equals(PointerUpEvent));
expect(events[4].buttons, equals(0));
PointerEventConverter.clearPointers();
}
});
test('Should not synthesise kPrimaryButton for certain devices', () {
final Offset location = const Offset(10.0, 10.0) * ui.window.devicePixelRatio;
for (PointerDeviceKind kind in <PointerDeviceKind>[
PointerDeviceKind.mouse,
]) {
final ui.PointerDataPacket packet = ui.PointerDataPacket(
data: <ui.PointerData>[
ui.PointerData(change: ui.PointerChange.add, kind: kind, physicalX: location.dx, physicalY: location.dy),
ui.PointerData(change: ui.PointerChange.hover, kind: kind, physicalX: location.dx, physicalY: location.dy),
ui.PointerData(change: ui.PointerChange.down, kind: kind, buttons: kMiddleMouseButton, physicalX: location.dx, physicalY: location.dy),
ui.PointerData(change: ui.PointerChange.move, kind: kind, buttons: kMiddleMouseButton | kSecondaryMouseButton, physicalX: location.dx, physicalY: location.dy),
ui.PointerData(change: ui.PointerChange.up, kind: kind, physicalX: location.dx, physicalY: location.dy),
]
);
final List<PointerEvent> events = PointerEventConverter.expand(
packet.data, ui.window.devicePixelRatio).toList();
expect(events.length, 5);
expect(events[0].runtimeType, equals(PointerAddedEvent));
expect(events[0].buttons, equals(0));
expect(events[1].runtimeType, equals(PointerHoverEvent));
expect(events[1].buttons, equals(0));
expect(events[2].runtimeType, equals(PointerDownEvent));
expect(events[2].buttons, equals(kMiddleMouseButton));
expect(events[3].runtimeType, equals(PointerMoveEvent));
expect(events[3].buttons, equals(kMiddleMouseButton | kSecondaryMouseButton));
expect(events[4].runtimeType, equals(PointerUpEvent));
expect(events[4].buttons, equals(0));
PointerEventConverter.clearPointers();
}
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment