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> ...@@ -81,3 +81,4 @@ Marian Triebe <m.triebe@live.de>
Alexis Rouillard <contact@arouillard.fr> Alexis Rouillard <contact@arouillard.fr>
Mirko Mucaria <skogsfrae@gmail.com> Mirko Mucaria <skogsfrae@gmail.com>
Karol Czeryna <karol.czeryna@gmail.com> Karol Czeryna <karol.czeryna@gmail.com>
Callum Moffat <callum@moffatman.com>
...@@ -19,7 +19,7 @@ int _synthesiseDownButtons(int buttons, PointerDeviceKind kind) { ...@@ -19,7 +19,7 @@ int _synthesiseDownButtons(int buttons, PointerDeviceKind kind) {
case PointerDeviceKind.touch: case PointerDeviceKind.touch:
case PointerDeviceKind.stylus: case PointerDeviceKind.stylus:
case PointerDeviceKind.invertedStylus: case PointerDeviceKind.invertedStylus:
return buttons | kPrimaryButton; return buttons == 0 ? kPrimaryButton : buttons;
case PointerDeviceKind.unknown: case PointerDeviceKind.unknown:
// We have no information about the device but we know we never want // We have no information about the device but we know we never want
// buttons to be 0 when the pointer is down. // buttons to be 0 when the pointer is down.
......
...@@ -175,7 +175,7 @@ void main() { ...@@ -175,7 +175,7 @@ void main() {
expect(events[1], isA<PointerScrollEvent>()); 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; final Offset location = const Offset(10.0, 10.0) * ui.window.devicePixelRatio;
const PointerDeviceKind kind = PointerDeviceKind.touch; const PointerDeviceKind kind = PointerDeviceKind.touch;
final ui.PointerDataPacket packet = ui.PointerDataPacket( final ui.PointerDataPacket packet = ui.PointerDataPacket(
...@@ -203,7 +203,35 @@ void main() { ...@@ -203,7 +203,35 @@ void main() {
expect(events[4].buttons, equals(0)); 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; final Offset location = const Offset(10.0, 10.0) * ui.window.devicePixelRatio;
for (final PointerDeviceKind kind in <PointerDeviceKind>[ for (final PointerDeviceKind kind in <PointerDeviceKind>[
PointerDeviceKind.stylus, PointerDeviceKind.stylus,
...@@ -230,13 +258,13 @@ void main() { ...@@ -230,13 +258,13 @@ void main() {
expect(events[2], isA<PointerDownEvent>()); expect(events[2], isA<PointerDownEvent>());
expect(events[2].buttons, equals(kPrimaryButton)); expect(events[2].buttons, equals(kPrimaryButton));
expect(events[3], isA<PointerMoveEvent>()); 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], isA<PointerUpEvent>());
expect(events[4].buttons, equals(0)); 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; final Offset location = const Offset(10.0, 10.0) * ui.window.devicePixelRatio;
const PointerDeviceKind kind = PointerDeviceKind.unknown; const PointerDeviceKind kind = PointerDeviceKind.unknown;
final ui.PointerDataPacket packet = ui.PointerDataPacket( final ui.PointerDataPacket packet = ui.PointerDataPacket(
...@@ -244,7 +272,7 @@ void main() { ...@@ -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.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.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.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), ui.PointerData(change: ui.PointerChange.up, kind: kind, physicalX: location.dx, physicalY: location.dy),
], ],
); );
...@@ -259,7 +287,7 @@ void main() { ...@@ -259,7 +287,7 @@ void main() {
expect(events[2], isA<PointerDownEvent>()); expect(events[2], isA<PointerDownEvent>());
expect(events[2].buttons, equals(kPrimaryButton)); expect(events[2].buttons, equals(kPrimaryButton));
expect(events[3], isA<PointerMoveEvent>()); 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], isA<PointerUpEvent>());
expect(events[4].buttons, equals(0)); 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