Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lib/ui/hooks.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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),
Expand All @@ -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);
}
Expand Down
34 changes: 33 additions & 1 deletion lib/ui/pointer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,31 @@ enum PointerDeviceKind {
/// A pointer device with a stylus that has been inverted.
invertedStylus,

/// A pointer that is generating signals at its location. Examples include
/// a mouse scroll wheel, or trackpad gestures such as scroll and pinch.
signal,

/// An unknown pointer device.
unknown
}

/// The kind of [PointerDeviceKind.signal].
enum PointerSignalKind {
/// 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.
const 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,
Expand All @@ -79,6 +93,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.
Expand All @@ -90,6 +106,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;

Expand Down Expand Up @@ -203,6 +222,16 @@ class PointerData {
/// Opaque platform-specific data associated with the event.
final int platformData;

/// For PointerDeviceKind.signal with PointerSignalKind.scroll:
///
/// The amount to scroll in the x direction, in physical pixels.
final double scrollDeltaX;

/// For PointerDeviceKind.signal with PointerSignalKind.scroll:
///
/// The amount to scroll in the y direction, in physical pixels.
final double scrollDeltaY;

@override
String toString() => '$runtimeType(x: $physicalX, y: $physicalY)';

Expand All @@ -212,6 +241,7 @@ class PointerData {
'timeStamp: $timeStamp, '
'change: $change, '
'kind: $kind, '
'signalKind: $signalKind, '
'device: $device, '
'physicalX: $physicalX, '
'physicalY: $physicalY, '
Expand All @@ -228,7 +258,9 @@ class PointerData {
'radiusMax: $radiusMax, '
'orientation: $orientation, '
'tilt: $tilt, '
'platformData: $platformData'
'platformData: $platformData, '
'scrollDeltaX: $scrollDeltaX, '
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is physicalX set to when scrollDeltaX is non null / nonzero?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm, i see, that's where the point is.

Will any future signals involve more than two linear dimensions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect swipe to use these fields; pinch zoom and rotate would need different fields.

'scrollDeltaY: $scrollDeltaY'
')';
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/window/pointer_data.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
9 changes: 9 additions & 0 deletions lib/ui/window/pointer_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,18 @@ struct alignas(8) PointerData {
kMouse,
kStylus,
kInvertedStylus,
kSignal,
};

// Must match the PointerSignalKind enum in pointer.dart.
enum class SignalKind : int64_t {
kScroll,
};

int64_t time_stamp;
Change change;
DeviceKind kind;
SignalKind signal_kind;
int64_t device;
double physical_x;
double physical_y;
Expand All @@ -51,6 +58,8 @@ struct alignas(8) PointerData {
double orientation;
double tilt;
int64_t platformData;
double scroll_delta_x;
double scroll_delta_y;

void Clear();
};
Expand Down
16 changes: 14 additions & 2 deletions shell/platform/android/io/flutter/view/FlutterView.java
Original file line number Diff line number Diff line change
Expand Up @@ -395,10 +395,15 @@ public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
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 kPointerSignalKindScroll = 0;
private static final int kPointerSignalKindUnknown = 1;

// 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) {
Expand Down Expand Up @@ -453,11 +458,15 @@ private void addPointerForIndex(MotionEvent event, int pointerIndex, int pointer

int pointerKind = getPointerDeviceTypeForToolType(event.getToolType(pointerIndex));

// This is ignored for non-signal device kinds.
int signalKind = kPointerSignalKindScroll;

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
Expand Down Expand Up @@ -502,6 +511,9 @@ private void addPointerForIndex(MotionEvent event, int pointerIndex, int pointer
}

packet.putLong(pointerData); // platformData

packet.putDouble(0.0); // scroll_delta_x
packet.putDouble(0.0); // scroll_delta_y
}

@Override
Expand Down
37 changes: 37 additions & 0 deletions shell/platform/embedder/embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,20 @@ FlutterEngineResult FlutterEngineSendWindowMetricsEvent(
: kInvalidArguments;
}

// Returns the blink::PointerData::DeviceKind for the given
// FlutterPointerDeviceKind.
inline blink::PointerData::DeviceKind ToPointerDataDeviceKind(
FlutterPointerDeviceKind kind) {
switch (kind) {
case kMouse:
return blink::PointerData::DeviceKind::kMouse;
case kSignal:
return blink::PointerData::DeviceKind::kSignal;
}
return blink::PointerData::DeviceKind::kMouse;
}

// Returns the blink::PointerData::Change for the given FlutterPointerPhase.
inline blink::PointerData::Change ToPointerDataChange(
FlutterPointerPhase phase) {
switch (phase) {
Expand All @@ -551,10 +565,27 @@ inline blink::PointerData::Change ToPointerDataChange(
return blink::PointerData::Change::kDown;
case kMove:
return blink::PointerData::Change::kMove;
case kAdd:
return blink::PointerData::Change::kAdd;
case kRemove:
return blink::PointerData::Change::kRemove;
case kHover:
return blink::PointerData::Change::kHover;
}
return blink::PointerData::Change::kCancel;
}

// Returns the blink::PointerData::SignalKind for the given
// FlutterPointerSignaKind.
inline blink::PointerData::SignalKind ToPointerDataSignalKind(
FlutterPointerSignalKind kind) {
switch (kind) {
case kScroll:
return blink::PointerData::SignalKind::kScroll;
}
return blink::PointerData::SignalKind::kScroll;
}

FlutterEngineResult FlutterEngineSendPointerEvent(
FlutterEngine engine,
const FlutterPointerEvent* pointers,
Expand All @@ -576,6 +607,12 @@ FlutterEngineResult FlutterEngineSendPointerEvent(
pointer_data.kind = blink::PointerData::DeviceKind::kMouse;
pointer_data.physical_x = SAFE_ACCESS(current, x, 0.0);
pointer_data.physical_y = SAFE_ACCESS(current, y, 0.0);
pointer_data.kind = ToPointerDataDeviceKind(
SAFE_ACCESS(current, kind, FlutterPointerDeviceKind::kMouse));
pointer_data.signal_kind = ToPointerDataSignalKind(
SAFE_ACCESS(current, signal_kind, FlutterPointerSignalKind::kScroll));
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);
Expand Down
19 changes: 19 additions & 0 deletions shell/platform/embedder/embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,20 +143,39 @@ typedef struct {
double pixel_ratio;
} FlutterWindowMetricsEvent;

// The kind of device generating a pointer event.
typedef enum {
kMouse,
kSignal,
} FlutterPointerDeviceKind;

// The phase of the pointer event.
typedef enum {
kCancel,
kUp,
kDown,
kMove,
kAdd,
kRemove,
kHover,
} FlutterPointerPhase;

// The type of a pointer signal.
typedef enum {
kScroll,
} FlutterPointerSignalKind;

typedef struct {
// The size of this struct. Must be sizeof(FlutterPointerEvent).
size_t struct_size;
FlutterPointerPhase phase;
size_t timestamp; // in microseconds.
double x;
double y;
FlutterPointerDeviceKind kind;
FlutterPointerSignalKind signal_kind; // ignored unless kind is kSignal.
double scroll_delta_x;
double scroll_delta_y;
} FlutterPointerEvent;

struct _FlutterPlatformMessageResponseHandle;
Expand Down