Propagate positions of secondary pointers in UP events on Android (flutter/engine#6716)
This commit is contained in:
committed by
GitHub
parent
e5dd70ddb7
commit
dfbd99b3d9
@@ -196,7 +196,7 @@ void _invoke3<A1, A2, A3>(void callback(A1 a1, A2 a2, A3 a3), Zone zone, A1 arg1
|
||||
//
|
||||
// * pointer_data.cc
|
||||
// * FlutterView.java
|
||||
const int _kPointerDataFieldCount = 20;
|
||||
const int _kPointerDataFieldCount = 21;
|
||||
|
||||
PointerDataPacket _unpackPointerDataPacket(ByteData packet) {
|
||||
const int kStride = Int64List.bytesPerElement;
|
||||
@@ -226,7 +226,8 @@ PointerDataPacket _unpackPointerDataPacket(ByteData packet) {
|
||||
radiusMin: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
|
||||
radiusMax: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
|
||||
orientation: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
|
||||
tilt: packet.getFloat64(kStride * offset++, _kFakeHostEndian)
|
||||
tilt: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
|
||||
platformData: packet.getInt64(kStride * offset++, _kFakeHostEndian),
|
||||
);
|
||||
assert(offset == (i + 1) * _kPointerDataFieldCount);
|
||||
}
|
||||
|
||||
@@ -77,7 +77,8 @@ class PointerData {
|
||||
this.radiusMin: 0.0,
|
||||
this.radiusMax: 0.0,
|
||||
this.orientation: 0.0,
|
||||
this.tilt: 0.0
|
||||
this.tilt: 0.0,
|
||||
this.platformData: 0,
|
||||
});
|
||||
|
||||
/// Time of event dispatch, relative to an arbitrary timeline.
|
||||
@@ -199,6 +200,9 @@ class PointerData {
|
||||
/// the stylus is flat on that surface).
|
||||
final double tilt;
|
||||
|
||||
/// Opaque platform-specific data associated with the event.
|
||||
final int platformData;
|
||||
|
||||
@override
|
||||
String toString() => '$runtimeType(x: $physicalX, y: $physicalY)';
|
||||
|
||||
@@ -223,7 +227,8 @@ class PointerData {
|
||||
'radiusMin: $radiusMin, '
|
||||
'radiusMax: $radiusMax, '
|
||||
'orientation: $orientation, '
|
||||
'tilt: $tilt'
|
||||
'tilt: $tilt, '
|
||||
'platformData: $platformData'
|
||||
')';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
namespace blink {
|
||||
|
||||
// If this value changes, update the pointer data unpacking code in hooks.dart.
|
||||
static constexpr int kPointerDataFieldCount = 20;
|
||||
static constexpr int kPointerDataFieldCount = 21;
|
||||
|
||||
static_assert(sizeof(PointerData) == sizeof(int64_t) * kPointerDataFieldCount,
|
||||
"PointerData has the wrong size");
|
||||
|
||||
@@ -50,6 +50,7 @@ struct alignas(8) PointerData {
|
||||
double radius_max;
|
||||
double orientation;
|
||||
double tilt;
|
||||
int64_t platformData;
|
||||
|
||||
void Clear();
|
||||
};
|
||||
|
||||
@@ -447,8 +447,8 @@ public class FlutterView extends SurfaceView
|
||||
}
|
||||
}
|
||||
|
||||
private void addPointerForIndex(MotionEvent event, int pointerIndex, ByteBuffer packet) {
|
||||
int pointerChange = getPointerChangeForAction(event.getActionMasked());
|
||||
private void addPointerForIndex(MotionEvent event, int pointerIndex, int pointerChange,
|
||||
int pointerData, ByteBuffer packet) {
|
||||
if (pointerChange == -1) {
|
||||
return;
|
||||
}
|
||||
@@ -503,6 +503,8 @@ public class FlutterView extends SurfaceView
|
||||
} else {
|
||||
packet.putDouble(0.0); // tilt
|
||||
}
|
||||
|
||||
packet.putLong(pointerData); // platformData
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -521,26 +523,44 @@ public class FlutterView extends SurfaceView
|
||||
}
|
||||
|
||||
// These values must match the unpacking code in hooks.dart.
|
||||
final int kPointerDataFieldCount = 20;
|
||||
final int kPointerDataFieldCount = 21;
|
||||
final int kBytePerField = 8;
|
||||
|
||||
// This value must match the value in framework's platform_view.dart.
|
||||
// This flag indicates whether the original Android pointer events were batched together.
|
||||
final int kPointerDataFlagBatched = 1;
|
||||
|
||||
int pointerCount = event.getPointerCount();
|
||||
|
||||
ByteBuffer packet = ByteBuffer.allocateDirect(pointerCount * kPointerDataFieldCount * kBytePerField);
|
||||
packet.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
int maskedAction = event.getActionMasked();
|
||||
// ACTION_UP, ACTION_POINTER_UP, ACTION_DOWN, and ACTION_POINTER_DOWN
|
||||
// only apply to a single pointer, other events apply to all pointers.
|
||||
if (maskedAction == MotionEvent.ACTION_UP || maskedAction == MotionEvent.ACTION_POINTER_UP
|
||||
|| maskedAction == MotionEvent.ACTION_DOWN || maskedAction == MotionEvent.ACTION_POINTER_DOWN) {
|
||||
addPointerForIndex(event, event.getActionIndex(), packet);
|
||||
int pointerChange = getPointerChangeForAction(event.getActionMasked());
|
||||
if (maskedAction == MotionEvent.ACTION_DOWN || maskedAction == MotionEvent.ACTION_POINTER_DOWN) {
|
||||
// ACTION_DOWN and ACTION_POINTER_DOWN always apply to a single pointer only.
|
||||
addPointerForIndex(event, event.getActionIndex(), pointerChange, 0, packet);
|
||||
} else if (maskedAction == MotionEvent.ACTION_UP || maskedAction == MotionEvent.ACTION_POINTER_UP) {
|
||||
// ACTION_UP and ACTION_POINTER_UP may contain position updates for other pointers.
|
||||
// We are converting these updates to move events here in order to preserve this data.
|
||||
// We also mark these events with a flag in order to help the framework reassemble
|
||||
// the original Android event later, should it need to forward it to a PlatformView.
|
||||
for (int p = 0; p < pointerCount; p++) {
|
||||
if (p != event.getActionIndex()) {
|
||||
if (event.getToolType(p) == MotionEvent.TOOL_TYPE_FINGER) {
|
||||
addPointerForIndex(event, p, kPointerChangeMove, kPointerDataFlagBatched, packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
// It's important that we're sending the UP event last. This allows PlatformView
|
||||
// to correctly batch everything back into the original Android event if needed.
|
||||
addPointerForIndex(event, event.getActionIndex(), pointerChange, 0, packet);
|
||||
} else {
|
||||
// ACTION_MOVE may not actually mean all pointers have moved
|
||||
// but it's the responsibility of a later part of the system to
|
||||
// ignore 0-deltas if desired.
|
||||
for (int p = 0; p < pointerCount; p++) {
|
||||
addPointerForIndex(event, p, packet);
|
||||
addPointerForIndex(event, p, pointerChange, 0, packet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user