Skip to content

Commit b5758d0

Browse files
authored
Propagate positions of secondary pointers in UP events on Android (flutter#6716)
1 parent 57c21d4 commit b5758d0

5 files changed

Lines changed: 41 additions & 14 deletions

File tree

lib/ui/hooks.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ void _invoke3<A1, A2, A3>(void callback(A1 a1, A2 a2, A3 a3), Zone zone, A1 arg1
196196
//
197197
// * pointer_data.cc
198198
// * FlutterView.java
199-
const int _kPointerDataFieldCount = 20;
199+
const int _kPointerDataFieldCount = 21;
200200

201201
PointerDataPacket _unpackPointerDataPacket(ByteData packet) {
202202
const int kStride = Int64List.bytesPerElement;
@@ -226,7 +226,8 @@ PointerDataPacket _unpackPointerDataPacket(ByteData packet) {
226226
radiusMin: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
227227
radiusMax: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
228228
orientation: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
229-
tilt: packet.getFloat64(kStride * offset++, _kFakeHostEndian)
229+
tilt: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
230+
platformData: packet.getInt64(kStride * offset++, _kFakeHostEndian),
230231
);
231232
assert(offset == (i + 1) * _kPointerDataFieldCount);
232233
}

lib/ui/pointer.dart

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ class PointerData {
7777
this.radiusMin: 0.0,
7878
this.radiusMax: 0.0,
7979
this.orientation: 0.0,
80-
this.tilt: 0.0
80+
this.tilt: 0.0,
81+
this.platformData: 0,
8182
});
8283

8384
/// Time of event dispatch, relative to an arbitrary timeline.
@@ -199,6 +200,9 @@ class PointerData {
199200
/// the stylus is flat on that surface).
200201
final double tilt;
201202

203+
/// Opaque platform-specific data associated with the event.
204+
final int platformData;
205+
202206
@override
203207
String toString() => '$runtimeType(x: $physicalX, y: $physicalY)';
204208

@@ -223,7 +227,8 @@ class PointerData {
223227
'radiusMin: $radiusMin, '
224228
'radiusMax: $radiusMax, '
225229
'orientation: $orientation, '
226-
'tilt: $tilt'
230+
'tilt: $tilt, '
231+
'platformData: $platformData'
227232
')';
228233
}
229234
}

lib/ui/window/pointer_data.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
namespace blink {
1010

1111
// If this value changes, update the pointer data unpacking code in hooks.dart.
12-
static constexpr int kPointerDataFieldCount = 20;
12+
static constexpr int kPointerDataFieldCount = 21;
1313

1414
static_assert(sizeof(PointerData) == sizeof(int64_t) * kPointerDataFieldCount,
1515
"PointerData has the wrong size");

lib/ui/window/pointer_data.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ struct alignas(8) PointerData {
5050
double radius_max;
5151
double orientation;
5252
double tilt;
53+
int64_t platformData;
5354

5455
void Clear();
5556
};

shell/platform/android/io/flutter/view/FlutterView.java

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -447,8 +447,8 @@ private int getPointerDeviceTypeForToolType(int toolType) {
447447
}
448448
}
449449

450-
private void addPointerForIndex(MotionEvent event, int pointerIndex, ByteBuffer packet) {
451-
int pointerChange = getPointerChangeForAction(event.getActionMasked());
450+
private void addPointerForIndex(MotionEvent event, int pointerIndex, int pointerChange,
451+
int pointerData, ByteBuffer packet) {
452452
if (pointerChange == -1) {
453453
return;
454454
}
@@ -503,6 +503,8 @@ private void addPointerForIndex(MotionEvent event, int pointerIndex, ByteBuffer
503503
} else {
504504
packet.putDouble(0.0); // tilt
505505
}
506+
507+
packet.putLong(pointerData); // platformData
506508
}
507509

508510
@Override
@@ -521,26 +523,44 @@ public boolean onTouchEvent(MotionEvent event) {
521523
}
522524

523525
// These values must match the unpacking code in hooks.dart.
524-
final int kPointerDataFieldCount = 20;
526+
final int kPointerDataFieldCount = 21;
525527
final int kBytePerField = 8;
526528

529+
// This value must match the value in framework's platform_view.dart.
530+
// This flag indicates whether the original Android pointer events were batched together.
531+
final int kPointerDataFlagBatched = 1;
532+
527533
int pointerCount = event.getPointerCount();
528534

529535
ByteBuffer packet = ByteBuffer.allocateDirect(pointerCount * kPointerDataFieldCount * kBytePerField);
530536
packet.order(ByteOrder.LITTLE_ENDIAN);
531537

532538
int maskedAction = event.getActionMasked();
533-
// ACTION_UP, ACTION_POINTER_UP, ACTION_DOWN, and ACTION_POINTER_DOWN
534-
// only apply to a single pointer, other events apply to all pointers.
535-
if (maskedAction == MotionEvent.ACTION_UP || maskedAction == MotionEvent.ACTION_POINTER_UP
536-
|| maskedAction == MotionEvent.ACTION_DOWN || maskedAction == MotionEvent.ACTION_POINTER_DOWN) {
537-
addPointerForIndex(event, event.getActionIndex(), packet);
539+
int pointerChange = getPointerChangeForAction(event.getActionMasked());
540+
if (maskedAction == MotionEvent.ACTION_DOWN || maskedAction == MotionEvent.ACTION_POINTER_DOWN) {
541+
// ACTION_DOWN and ACTION_POINTER_DOWN always apply to a single pointer only.
542+
addPointerForIndex(event, event.getActionIndex(), pointerChange, 0, packet);
543+
} else if (maskedAction == MotionEvent.ACTION_UP || maskedAction == MotionEvent.ACTION_POINTER_UP) {
544+
// ACTION_UP and ACTION_POINTER_UP may contain position updates for other pointers.
545+
// We are converting these updates to move events here in order to preserve this data.
546+
// We also mark these events with a flag in order to help the framework reassemble
547+
// the original Android event later, should it need to forward it to a PlatformView.
548+
for (int p = 0; p < pointerCount; p++) {
549+
if (p != event.getActionIndex()) {
550+
if (event.getToolType(p) == MotionEvent.TOOL_TYPE_FINGER) {
551+
addPointerForIndex(event, p, kPointerChangeMove, kPointerDataFlagBatched, packet);
552+
}
553+
}
554+
}
555+
// It's important that we're sending the UP event last. This allows PlatformView
556+
// to correctly batch everything back into the original Android event if needed.
557+
addPointerForIndex(event, event.getActionIndex(), pointerChange, 0, packet);
538558
} else {
539559
// ACTION_MOVE may not actually mean all pointers have moved
540560
// but it's the responsibility of a later part of the system to
541561
// ignore 0-deltas if desired.
542562
for (int p = 0; p < pointerCount; p++) {
543-
addPointerForIndex(event, p, packet);
563+
addPointerForIndex(event, p, pointerChange, 0, packet);
544564
}
545565
}
546566

0 commit comments

Comments
 (0)