Unverified Commit 6909c544 authored by Callum Moffat's avatar Callum Moffat Committed by GitHub

Don't synthesize primary pointer button unless buttons = 0 (#85808)

Some embeddings might send pointer events with buttons = 0x2 (right-click) for touch or stylus device kinds. If the primary button is synthesized for those events, they won't behave properly. Without this change it's not possible to trigger "secondary tap" events on a TapGestureRecognizer while using a stylus or on an iPad trackpad, since that recognizer will receive buttons = 0x3.
parent ae4758da
......@@ -81,3 +81,4 @@ Marian Triebe <m.triebe@live.de>
Alexis Rouillard <contact@arouillard.fr>
Mirko Mucaria <skogsfrae@gmail.com>
Karol Czeryna <karol.czeryna@gmail.com>
Callum Moffat <callum@moffatman.com>
......@@ -19,7 +19,7 @@ int _synthesiseDownButtons(int buttons, PointerDeviceKind kind) {
case PointerDeviceKind.touch:
case PointerDeviceKind.stylus:
case PointerDeviceKind.invertedStylus:
return buttons | kPrimaryButton;
return buttons == 0 ? kPrimaryButton : buttons;
case PointerDeviceKind.unknown:
// We have no information about the device but we know we never want
// buttons to be 0 when the pointer is down.
......
......@@ -175,7 +175,7 @@ void main() {
expect(events[1], isA<PointerScrollEvent>());
});
test('Should synthesize kPrimaryButton for touch', () {
test('Should synthesize kPrimaryButton for touch when no button is set', () {
final Offset location = const Offset(10.0, 10.0) * ui.window.devicePixelRatio;
const PointerDeviceKind kind = PointerDeviceKind.touch;
final ui.PointerDataPacket packet = ui.PointerDataPacket(
......@@ -203,7 +203,35 @@ void main() {
expect(events[4].buttons, equals(0));
});
test('Should synthesize kPrimaryButton for stylus', () {
test('Should not synthesize kPrimaryButton for touch when a button is set', () {
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, buttons: kSecondaryButton, kind: kind, physicalX: location.dx, physicalY: location.dy),
ui.PointerData(change: ui.PointerChange.move, buttons: kSecondaryButton, 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], isA<PointerAddedEvent>());
expect(events[0].buttons, equals(0));
expect(events[1], isA<PointerHoverEvent>());
expect(events[1].buttons, equals(0));
expect(events[2], isA<PointerDownEvent>());
expect(events[2].buttons, equals(kSecondaryButton));
expect(events[3], isA<PointerMoveEvent>());
expect(events[3].buttons, equals(kSecondaryButton));
expect(events[4], isA<PointerUpEvent>());
expect(events[4].buttons, equals(0));
});
test('Should synthesize kPrimaryButton for stylus when no button is set', () {
final Offset location = const Offset(10.0, 10.0) * ui.window.devicePixelRatio;
for (final PointerDeviceKind kind in <PointerDeviceKind>[
PointerDeviceKind.stylus,
......@@ -230,13 +258,13 @@ void main() {
expect(events[2], isA<PointerDownEvent>());
expect(events[2].buttons, equals(kPrimaryButton));
expect(events[3], isA<PointerMoveEvent>());
expect(events[3].buttons, equals(kPrimaryButton | kSecondaryStylusButton));
expect(events[3].buttons, equals(kSecondaryStylusButton));
expect(events[4], isA<PointerUpEvent>());
expect(events[4].buttons, equals(0));
}
});
test('Should synthesize kPrimaryButton for unknown devices', () {
test('Should synthesize kPrimaryButton for unknown devices when no button is set', () {
final Offset location = const Offset(10.0, 10.0) * ui.window.devicePixelRatio;
const PointerDeviceKind kind = PointerDeviceKind.unknown;
final ui.PointerDataPacket packet = ui.PointerDataPacket(
......@@ -244,7 +272,7 @@ void main() {
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.move, buttons: kSecondaryButton, kind: kind, physicalX: location.dx, physicalY: location.dy),
ui.PointerData(change: ui.PointerChange.up, kind: kind, physicalX: location.dx, physicalY: location.dy),
],
);
......@@ -259,7 +287,7 @@ void main() {
expect(events[2], isA<PointerDownEvent>());
expect(events[2].buttons, equals(kPrimaryButton));
expect(events[3], isA<PointerMoveEvent>());
expect(events[3].buttons, equals(kPrimaryButton));
expect(events[3].buttons, equals(kSecondaryButton));
expect(events[4], isA<PointerUpEvent>());
expect(events[4].buttons, equals(0));
});
......
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