mirror of
https://github.com/encounter/engine.git
synced 2026-03-30 11:09:55 -07:00
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.
This commit is contained in:
@@ -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'
|
||||
')';
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -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);
|
||||
}
|
||||
|
||||
+32
-1
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user