未验证 提交 dd80fc9f 编写于 作者: S stuartmorgan 提交者: GitHub

Add engine support for scrollwheel events (#7494)

Adds support for pointer signals, in a way that will support both discrete events (e.g., scroll wheels, flutter/flutter#22762) and continuous gestures (e.g., trackpad scroll, flutter/flutter#21953).

Also exposes these new event options to the embedder. Does not include code to send the
new events from the platform shells.
上级 f4951df1
......@@ -213,7 +213,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 = 21;
const int _kPointerDataFieldCount = 24;
PointerDataPacket _unpackPointerDataPacket(ByteData packet) {
const int kStride = Int64List.bytesPerElement;
......@@ -227,6 +227,7 @@ PointerDataPacket _unpackPointerDataPacket(ByteData packet) {
timeStamp: new Duration(microseconds: packet.getInt64(kStride * offset++, _kFakeHostEndian)),
change: PointerChange.values[packet.getInt64(kStride * offset++, _kFakeHostEndian)],
kind: PointerDeviceKind.values[packet.getInt64(kStride * offset++, _kFakeHostEndian)],
signalKind: PointerSignalKind.values[packet.getInt64(kStride * offset++, _kFakeHostEndian)],
device: packet.getInt64(kStride * offset++, _kFakeHostEndian),
physicalX: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
physicalY: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
......@@ -245,6 +246,8 @@ PointerDataPacket _unpackPointerDataPacket(ByteData packet) {
orientation: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
tilt: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
platformData: packet.getInt64(kStride * offset++, _kFakeHostEndian),
scrollDeltaX: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
scrollDeltaY: packet.getFloat64(kStride * offset++, _kFakeHostEndian)
);
assert(offset == (i + 1) * _kPointerDataFieldCount);
}
......
......@@ -54,6 +54,18 @@ enum PointerDeviceKind {
unknown
}
/// The kind of [PointerDeviceKind.signal].
enum PointerSignalKind {
/// The event is not associated with a pointer signal.
none,
/// A pointer-generated scroll (e.g., mouse wheel or trackpad scroll).
scroll,
/// An unknown pointer signal kind.
unknown
}
/// Information about the state of a pointer.
class PointerData {
/// Creates an object that represents the state of a pointer.
......@@ -61,6 +73,7 @@ class PointerData {
this.timeStamp: Duration.zero,
this.change: PointerChange.cancel,
this.kind: PointerDeviceKind.touch,
this.signalKind,
this.device: 0,
this.physicalX: 0.0,
this.physicalY: 0.0,
......@@ -79,6 +92,8 @@ class PointerData {
this.orientation: 0.0,
this.tilt: 0.0,
this.platformData: 0,
this.scrollDeltaX: 0.0,
this.scrollDeltaY: 0.0,
});
/// Time of event dispatch, relative to an arbitrary timeline.
......@@ -90,6 +105,9 @@ class PointerData {
/// The kind of input device for which the event was generated.
final PointerDeviceKind kind;
/// The kind of signal for a pointer signal event.
final PointerSignalKind signalKind;
/// Unique identifier for the pointing device, reused across interactions.
final int device;
......@@ -203,6 +221,16 @@ class PointerData {
/// Opaque platform-specific data associated with the event.
final int platformData;
/// For events with signalKind of PointerSignalKind.scroll:
///
/// The amount to scroll in the x direction, in physical pixels.
final double scrollDeltaX;
/// For events with signalKind of PointerSignalKind.scroll:
///
/// The amount to scroll in the y direction, in physical pixels.
final double scrollDeltaY;
@override
String toString() => '$runtimeType(x: $physicalX, y: $physicalY)';
......@@ -212,6 +240,7 @@ class PointerData {
'timeStamp: $timeStamp, '
'change: $change, '
'kind: $kind, '
'signalKind: $signalKind, '
'device: $device, '
'physicalX: $physicalX, '
'physicalY: $physicalY, '
......@@ -228,7 +257,9 @@ class PointerData {
'radiusMax: $radiusMax, '
'orientation: $orientation, '
'tilt: $tilt, '
'platformData: $platformData'
'platformData: $platformData, '
'scrollDeltaX: $scrollDeltaX, '
'scrollDeltaY: $scrollDeltaY'
')';
}
}
......
......@@ -259,7 +259,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 = 21;
const int _kPointerDataFieldCount = 24;
PointerDataPacket _unpackPointerDataPacket(ByteData packet) {
const int kStride = Int64List.bytesPerElement;
......@@ -273,6 +273,7 @@ PointerDataPacket _unpackPointerDataPacket(ByteData packet) {
timeStamp: new Duration(microseconds: packet.getInt64(kStride * offset++, _kFakeHostEndian)),
change: PointerChange.values[packet.getInt64(kStride * offset++, _kFakeHostEndian)],
kind: PointerDeviceKind.values[packet.getInt64(kStride * offset++, _kFakeHostEndian)],
signalKind: PointerSignalKind.values[packet.getInt64(kStride * offset++, _kFakeHostEndian)],
device: packet.getInt64(kStride * offset++, _kFakeHostEndian),
physicalX: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
physicalY: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
......@@ -291,6 +292,8 @@ PointerDataPacket _unpackPointerDataPacket(ByteData packet) {
orientation: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
tilt: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
platformData: packet.getInt64(kStride * offset++, _kFakeHostEndian),
scrollDeltaX: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
scrollDeltaY: packet.getFloat64(kStride * offset++, _kFakeHostEndian)
);
assert(offset == (i + 1) * _kPointerDataFieldCount);
}
......
......@@ -54,6 +54,18 @@ enum PointerDeviceKind {
unknown
}
/// The kind of [PointerDeviceKind.signal].
enum PointerSignalKind {
/// The event is not associated with a pointer signal.
none,
/// A pointer-generated scroll (e.g., mouse wheel or trackpad scroll).
scroll,
/// An unknown pointer signal kind.
unknown
}
/// Information about the state of a pointer.
class PointerData {
/// Creates an object that represents the state of a pointer.
......@@ -61,6 +73,7 @@ class PointerData {
this.timeStamp: Duration.zero,
this.change: PointerChange.cancel,
this.kind: PointerDeviceKind.touch,
this.signalKind,
this.device: 0,
this.physicalX: 0.0,
this.physicalY: 0.0,
......@@ -79,6 +92,8 @@ class PointerData {
this.orientation: 0.0,
this.tilt: 0.0,
this.platformData: 0,
this.scrollDeltaX: 0.0,
this.scrollDeltaY: 0.0,
});
/// Time of event dispatch, relative to an arbitrary timeline.
......@@ -90,6 +105,9 @@ class PointerData {
/// The kind of input device for which the event was generated.
final PointerDeviceKind kind;
/// The kind of signal for a pointer signal event.
final PointerSignalKind signalKind;
/// Unique identifier for the pointing device, reused across interactions.
final int device;
......@@ -203,6 +221,16 @@ class PointerData {
/// Opaque platform-specific data associated with the event.
final int platformData;
/// For events with signalKind of PointerSignalKind.scroll:
///
/// The amount to scroll in the x direction, in physical pixels.
final double scrollDeltaX;
/// For events with signalKind of PointerSignalKind.scroll:
///
/// The amount to scroll in the y direction, in physical pixels.
final double scrollDeltaY;
@override
String toString() => '$runtimeType(x: $physicalX, y: $physicalY)';
......@@ -212,6 +240,7 @@ class PointerData {
'timeStamp: $timeStamp, '
'change: $change, '
'kind: $kind, '
'signalKind: $signalKind, '
'device: $device, '
'physicalX: $physicalX, '
'physicalY: $physicalY, '
......@@ -228,7 +257,9 @@ class PointerData {
'radiusMax: $radiusMax, '
'orientation: $orientation, '
'tilt: $tilt, '
'platformData: $platformData'
'platformData: $platformData, '
'scrollDeltaX: $scrollDeltaX, '
'scrollDeltaY: $scrollDeltaY'
')';
}
}
......
......@@ -9,7 +9,7 @@
namespace blink {
// If this value changes, update the pointer data unpacking code in hooks.dart.
static constexpr int kPointerDataFieldCount = 21;
static constexpr int kPointerDataFieldCount = 24;
static_assert(sizeof(PointerData) == sizeof(int64_t) * kPointerDataFieldCount,
"PointerData has the wrong size");
......
......@@ -28,11 +28,19 @@ struct alignas(8) PointerData {
kMouse,
kStylus,
kInvertedStylus,
kSignal,
};
// Must match the PointerSignalKind enum in pointer.dart.
enum class SignalKind : int64_t {
kNone,
kScroll,
};
int64_t time_stamp;
Change change;
DeviceKind kind;
SignalKind signal_kind;
int64_t device;
double physical_x;
double physical_y;
......@@ -51,6 +59,8 @@ struct alignas(8) PointerData {
double orientation;
double tilt;
int64_t platformData;
double scroll_delta_x;
double scroll_delta_y;
void Clear();
};
......
......@@ -378,10 +378,16 @@ public class FlutterView extends SurfaceView
private static final int kPointerDeviceKindMouse = 1;
private static final int kPointerDeviceKindStylus = 2;
private static final int kPointerDeviceKindInvertedStylus = 3;
private static final int kPointerDeviceKindUnknown = 4;
private static final int kPointerDeviceKindSignal = 4;
private static final int kPointerDeviceKindUnknown = 5;
// Must match the PointerSignalKind enum in pointer.dart.
private static final int kPointerSignalKindNone = 0;
private static final int kPointerSignalKindScroll = 1;
private static final int kPointerSignalKindUnknown = 2;
// These values must match the unpacking code in hooks.dart.
private static final int kPointerDataFieldCount = 21;
private static final int kPointerDataFieldCount = 24;
private static final int kPointerBytesPerField = 8;
private int getPointerChangeForAction(int maskedAction) {
......@@ -436,11 +442,14 @@ public class FlutterView extends SurfaceView
int pointerKind = getPointerDeviceTypeForToolType(event.getToolType(pointerIndex));
int signalKind = kPointerSignalKindNone;
long timeStamp = event.getEventTime() * 1000; // Convert from milliseconds to microseconds.
packet.putLong(timeStamp); // time_stamp
packet.putLong(pointerChange); // change
packet.putLong(pointerKind); // kind
packet.putLong(signalKind); // signal_kind
packet.putLong(event.getPointerId(pointerIndex)); // device
packet.putDouble(event.getX(pointerIndex)); // physical_x
packet.putDouble(event.getY(pointerIndex)); // physical_y
......@@ -492,6 +501,9 @@ public class FlutterView extends SurfaceView
}
packet.putLong(pointerData); // platformData
packet.putDouble(0.0); // scroll_delta_x
packet.putDouble(0.0); // scroll_delta_y
}
@Override
......
......@@ -677,6 +677,19 @@ inline blink::PointerData::Change ToPointerDataChange(
return blink::PointerData::Change::kCancel;
}
// Returns the blink::PointerData::SignalKind for the given
// FlutterPointerSignaKind.
inline blink::PointerData::SignalKind ToPointerDataSignalKind(
FlutterPointerSignalKind kind) {
switch (kind) {
case kFlutterPointerSignalKindNone:
return blink::PointerData::SignalKind::kNone;
case kFlutterPointerSignalKindScroll:
return blink::PointerData::SignalKind::kScroll;
}
return blink::PointerData::SignalKind::kNone;
}
FlutterEngineResult FlutterEngineSendPointerEvent(
FlutterEngine engine,
const FlutterPointerEvent* pointers,
......@@ -699,6 +712,10 @@ FlutterEngineResult FlutterEngineSendPointerEvent(
pointer_data.physical_x = SAFE_ACCESS(current, x, 0.0);
pointer_data.physical_y = SAFE_ACCESS(current, y, 0.0);
pointer_data.device = SAFE_ACCESS(current, device, 0);
pointer_data.signal_kind = ToPointerDataSignalKind(
SAFE_ACCESS(current, signal_kind, kFlutterPointerSignalKindNone));
pointer_data.scroll_delta_x = SAFE_ACCESS(current, scroll_delta_x, 0.0);
pointer_data.scroll_delta_y = SAFE_ACCESS(current, scroll_delta_y, 0.0);
packet->SetPointerData(i, pointer_data);
current = reinterpret_cast<const FlutterPointerEvent*>(
reinterpret_cast<const uint8_t*>(current) + current->struct_size);
......
......@@ -277,6 +277,7 @@ typedef struct {
double pixel_ratio;
} FlutterWindowMetricsEvent;
// The phase of the pointer event.
typedef enum {
kCancel,
kUp,
......@@ -287,6 +288,12 @@ typedef enum {
kHover,
} FlutterPointerPhase;
// The type of a pointer signal.
typedef enum {
kFlutterPointerSignalKindNone,
kFlutterPointerSignalKindScroll,
} FlutterPointerSignalKind;
typedef struct {
// The size of this struct. Must be sizeof(FlutterPointerEvent).
size_t struct_size;
......@@ -297,6 +304,9 @@ typedef struct {
// An optional device identifier. If this is not specified, it is assumed that
// the embedder has no multitouch capability.
int32_t device;
FlutterPointerSignalKind signal_kind;
double scroll_delta_x;
double scroll_delta_y;
} FlutterPointerEvent;
struct _FlutterPlatformMessageResponseHandle;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册