Unverified Commit 423cf223 authored by Tong Mu's avatar Tong Mu Committed by GitHub

Fix edge cases of PointerEventConverter (#29998)

* Fix: ui.PointerChange.remove might contain position change, but we used to expand it into a Cancel and Remove, neither of which allows position change. A Hover event is added, and a test is updated accordingly.
* Fixed the issue where a PointerMoveEvent and a PointerCancelEvent do not receive the correct pressure.
* Refactor the calculation of delta into deltaTo.
parent 6ba720a4
......@@ -32,6 +32,8 @@ class _PointerState {
Offset lastPosition;
Offset deltaTo(Offset to) => to - lastPosition;
@override
String toString() {
return '_PointerState(pointer: $pointer, down: $down, lastPosition: $lastPosition)';
......@@ -126,14 +128,12 @@ class PointerEventConverter {
tilt: datum.tilt,
);
}
final Offset offset = position - state.lastPosition;
state.lastPosition = position;
yield PointerHoverEvent(
timeStamp: timeStamp,
kind: kind,
device: datum.device,
position: position,
delta: offset,
delta: state.deltaTo(position),
buttons: datum.buttons,
obscured: datum.obscured,
pressureMin: datum.pressureMin,
......@@ -176,14 +176,12 @@ class PointerEventConverter {
// Not all sources of pointer packets respect the invariant that
// they hover the pointer to the down location before sending the
// down event. We restore the invariant here for our clients.
final Offset offset = position - state.lastPosition;
state.lastPosition = position;
yield PointerHoverEvent(
timeStamp: timeStamp,
kind: kind,
device: datum.device,
position: position,
delta: offset,
delta: state.deltaTo(position),
buttons: datum.buttons,
obscured: datum.obscured,
pressureMin: datum.pressureMin,
......@@ -231,15 +229,13 @@ class PointerEventConverter {
assert(_pointers.containsKey(datum.device));
final _PointerState state = _pointers[datum.device];
assert(state.down);
final Offset offset = position - state.lastPosition;
state.lastPosition = position;
yield PointerMoveEvent(
timeStamp: timeStamp,
pointer: state.pointer,
kind: kind,
device: datum.device,
position: position,
delta: offset,
delta: state.deltaTo(position),
buttons: datum.buttons,
obscured: datum.obscured,
pressure: datum.pressure,
......@@ -255,6 +251,7 @@ class PointerEventConverter {
tilt: datum.tilt,
platformData: datum.platformData,
);
state.lastPosition = position;
break;
case ui.PointerChange.up:
case ui.PointerChange.cancel:
......@@ -267,15 +264,13 @@ class PointerEventConverter {
// event. For example, in the iOS simulator, of you drag outside the
// window, you'll get a stream of pointers that violates that
// invariant. We restore the invariant here for our clients.
final Offset offset = position - state.lastPosition;
state.lastPosition = position;
yield PointerMoveEvent(
timeStamp: timeStamp,
pointer: state.pointer,
kind: kind,
device: datum.device,
position: position,
delta: offset,
delta: state.deltaTo(position),
buttons: datum.buttons,
obscured: datum.obscured,
pressure: datum.pressure,
......@@ -326,6 +321,7 @@ class PointerEventConverter {
position: position,
buttons: datum.buttons,
obscured: datum.obscured,
pressure: datum.pressure,
pressureMin: datum.pressureMin,
pressureMax: datum.pressureMax,
distance: datum.distance,
......@@ -349,8 +345,31 @@ class PointerEventConverter {
pointer: state.pointer,
kind: kind,
device: datum.device,
position: state.lastPosition, // Change position in Hover
buttons: datum.buttons,
obscured: datum.obscured,
pressure: datum.pressure,
pressureMin: datum.pressureMin,
pressureMax: datum.pressureMax,
distance: datum.distance,
distanceMax: datum.distanceMax,
size: datum.size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: datum.orientation,
tilt: datum.tilt,
);
}
if (position != state.lastPosition) {
yield PointerHoverEvent(
timeStamp: timeStamp,
kind: kind,
device: datum.device,
position: position,
buttons: datum.buttons,
delta: state.deltaTo(position),
obscured: datum.obscured,
pressureMin: datum.pressureMin,
pressureMax: datum.pressureMax,
......@@ -363,6 +382,7 @@ class PointerEventConverter {
radiusMax: radiusMax,
orientation: datum.orientation,
tilt: datum.tilt,
synthesized: true,
);
}
_pointers.remove(datum.device);
......@@ -390,8 +410,6 @@ class PointerEventConverter {
// before sending the scroll event, if necessary, so that clients
// don't have to worry about native ordering of hover and scroll
// events.
final Offset offset = position - state.lastPosition;
state.lastPosition = position;
if (state.down) {
yield PointerMoveEvent(
timeStamp: timeStamp,
......@@ -399,9 +417,10 @@ class PointerEventConverter {
kind: kind,
device: datum.device,
position: position,
delta: offset,
delta: state.deltaTo(position),
buttons: datum.buttons,
obscured: datum.obscured,
pressure: datum.pressure,
pressureMin: datum.pressureMin,
pressureMax: datum.pressureMax,
distanceMax: datum.distanceMax,
......@@ -420,7 +439,7 @@ class PointerEventConverter {
kind: kind,
device: datum.device,
position: position,
delta: offset,
delta: state.deltaTo(position),
buttons: datum.buttons,
obscured: datum.obscured,
pressureMin: datum.pressureMin,
......@@ -437,6 +456,7 @@ class PointerEventConverter {
synthesized: true,
);
}
state.lastPosition = position;
}
final Offset scrollDelta =
Offset(datum.scrollDeltaX, datum.scrollDeltaY) / devicePixelRatio;
......
......@@ -346,21 +346,21 @@ class PointerAddedEvent extends PointerEvent {
double orientation = 0.0,
double tilt = 0.0,
}) : super(
timeStamp: timeStamp,
kind: kind,
device: device,
position: position,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: distance,
distanceMax: distanceMax,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt
);
timeStamp: timeStamp,
kind: kind,
device: device,
position: position,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: distance,
distanceMax: distanceMax,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
);
}
/// The device is no longer tracking the pointer.
......@@ -383,18 +383,18 @@ class PointerRemovedEvent extends PointerEvent {
double radiusMin = 0.0,
double radiusMax = 0.0,
}) : super(
timeStamp: timeStamp,
kind: kind,
device: device,
position: null,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distanceMax: distanceMax,
radiusMin: radiusMin,
radiusMax: radiusMax,
);
timeStamp: timeStamp,
kind: kind,
device: device,
position: null,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distanceMax: distanceMax,
radiusMin: radiusMin,
radiusMax: radiusMax,
);
}
/// The pointer has moved with respect to the device while the pointer is not
......@@ -433,28 +433,28 @@ class PointerHoverEvent extends PointerEvent {
double tilt = 0.0,
bool synthesized = false,
}) : super(
timeStamp: timeStamp,
kind: kind,
device: device,
position: position,
delta: delta,
buttons: buttons,
down: false,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: distance,
distanceMax: distanceMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
synthesized: synthesized,
);
timeStamp: timeStamp,
kind: kind,
device: device,
position: position,
delta: delta,
buttons: buttons,
down: false,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: distance,
distanceMax: distanceMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
synthesized: synthesized,
);
}
/// The pointer has moved with respect to the device while the pointer is not
......@@ -493,28 +493,28 @@ class PointerEnterEvent extends PointerEvent {
double tilt = 0.0,
bool synthesized = false,
}) : super(
timeStamp: timeStamp,
kind: kind,
device: device,
position: position,
delta: delta,
buttons: buttons,
down: false,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: distance,
distanceMax: distanceMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
synthesized: synthesized,
);
timeStamp: timeStamp,
kind: kind,
device: device,
position: position,
delta: delta,
buttons: buttons,
down: false,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: distance,
distanceMax: distanceMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
synthesized: synthesized,
);
/// Creates an enter event from a [PointerHoverEvent].
///
......@@ -586,28 +586,28 @@ class PointerExitEvent extends PointerEvent {
double tilt = 0.0,
bool synthesized = false,
}) : super(
timeStamp: timeStamp,
kind: kind,
device: device,
position: position,
delta: delta,
buttons: buttons,
down: false,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: distance,
distanceMax: distanceMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
synthesized: synthesized,
);
timeStamp: timeStamp,
kind: kind,
device: device,
position: position,
delta: delta,
buttons: buttons,
down: false,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: distance,
distanceMax: distanceMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
synthesized: synthesized,
);
/// Creates an exit event from a [PointerHoverEvent].
///
......@@ -668,27 +668,27 @@ class PointerDownEvent extends PointerEvent {
double orientation = 0.0,
double tilt = 0.0,
}) : super(
timeStamp: timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
buttons: buttons,
down: true,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: 0.0,
distanceMax: distanceMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt
);
timeStamp: timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
buttons: buttons,
down: true,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: 0.0,
distanceMax: distanceMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
);
}
/// The pointer has moved with respect to the device while the pointer is in
......@@ -725,30 +725,30 @@ class PointerMoveEvent extends PointerEvent {
int platformData = 0,
bool synthesized = false,
}) : super(
timeStamp: timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
delta: delta,
buttons: buttons,
down: true,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: 0.0,
distanceMax: distanceMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
platformData: platformData,
synthesized: synthesized,
);
timeStamp: timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
delta: delta,
buttons: buttons,
down: true,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: 0.0,
distanceMax: distanceMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
platformData: platformData,
synthesized: synthesized,
);
}
/// The pointer has stopped making contact with the device.
......@@ -777,27 +777,27 @@ class PointerUpEvent extends PointerEvent {
double orientation = 0.0,
double tilt = 0.0,
}) : super(
timeStamp: timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
buttons: buttons,
down: false,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: distance,
distanceMax: distanceMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt
);
timeStamp: timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
buttons: buttons,
down: false,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: distance,
distanceMax: distanceMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
);
}
/// An event that corresponds to a discrete pointer signal.
......@@ -815,12 +815,12 @@ abstract class PointerSignalEvent extends PointerEvent {
int device = 0,
Offset position = Offset.zero,
}) : super(
timeStamp: timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
);
timeStamp: timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
);
}
/// The pointer issued a scroll event.
......@@ -843,11 +843,11 @@ class PointerScrollEvent extends PointerSignalEvent {
assert(position != null),
assert(scrollDelta != null),
super(
timeStamp: timeStamp,
kind: kind,
device: device,
position: position,
);
timeStamp: timeStamp,
kind: kind,
device: device,
position: position,
);
/// The amount to scroll, in logical pixels.
final Offset scrollDelta;
......@@ -885,25 +885,25 @@ class PointerCancelEvent extends PointerEvent {
double orientation = 0.0,
double tilt = 0.0,
}) : super(
timeStamp: timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
buttons: buttons,
down: false,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: distance,
distanceMax: distanceMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt
);
timeStamp: timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
buttons: buttons,
down: false,
obscured: obscured,
pressure: pressure,
pressureMin: pressureMin,
pressureMax: pressureMax,
distance: distance,
distanceMax: distanceMax,
size: size,
radiusMajor: radiusMajor,
radiusMinor: radiusMinor,
radiusMin: radiusMin,
radiusMax: radiusMax,
orientation: orientation,
tilt: tilt,
);
}
......@@ -195,13 +195,14 @@ void main() {
final List<PointerEvent> events = PointerEventConverter.expand(
packet.data, ui.window.devicePixelRatio).toList();
expect(events.length, 5);
expect(events.length, 6);
expect(events[0].runtimeType, equals(PointerAddedEvent));
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[3].runtimeType, equals(PointerCancelEvent));
expect(events[4].runtimeType, equals(PointerRemovedEvent));
expect(events[4].runtimeType, equals(PointerHoverEvent));
expect(events[5].runtimeType, equals(PointerRemovedEvent));
});
test('Can expand pointer scroll events', () {
......
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