提交 d1bc4c48 编写于 作者: A Adam Barth 提交者: GitHub

Add support for hover pointer events (#3227)

These are implemented on macOS and Fuchsia.
上级 cfe69e4e
......@@ -269,6 +269,25 @@ void RuntimeHolder::OnEvent(mozart::EventPtr event,
pointer_data.physical_x = event->pointer_data->x;
pointer_data.physical_y = event->pointer_data->y;
switch (pointer_data.change) {
case blink::PointerData::Change::kDown:
down_pointers_.insert(pointer_data.pointer);
break;
case blink::PointerData::Change::kCancel:
case blink::PointerData::Change::kUp:
down_pointers_.erase(pointer_data.pointer);
break;
case blink::PointerData::Change::kMove:
if (down_pointers_.count(pointer_data.pointer) == 0)
pointer_data.change = blink::PointerData::Change::kHover;
break;
case blink::PointerData::Change::kAdd:
case blink::PointerData::Change::kRemove:
case blink::PointerData::Change::kHover:
FTL_DCHECK(down_pointers_.count(pointer_data.pointer) == 0);
break;
}
blink::PointerDataPacket packet(1);
packet.SetPointerData(0, pointer_data);
runtime_->DispatchPointerDataPacket(packet);
......
......@@ -7,6 +7,8 @@
#include <mx/channel.h>
#include <unordered_set>
#include "apps/modular/services/application/application_environment.fidl.h"
#include "apps/modular/services/application/service_provider.fidl.h"
#include "apps/mozart/services/input/input_connection.fidl.h"
......@@ -89,6 +91,8 @@ class RuntimeHolder : public blink::RuntimeDelegate,
mozart::ViewPropertiesPtr view_properties_;
uint32_t scene_version_ = mozart::kSceneVersionNone;
unordered_set<int> down_pointers_;
bool pending_invalidation_ = false;
OnInvalidationCallback deferred_invalidation_callback_;
bool is_ready_to_draw_ = false;
......
......@@ -94,14 +94,14 @@ PointerDataPacket _unpackPointerDataPacket(ByteData packet) {
const int kBytesPerPointerData = _kPointerDataFieldCount * kStride;
final int length = packet.lengthInBytes ~/ kBytesPerPointerData;
assert(length * kBytesPerPointerData == packet.lengthInBytes);
List<PointerData> pointers = new List<PointerData>(length);
List<PointerData> data = new List<PointerData>(length);
for (int i = 0; i < length; ++i) {
int offset = i * _kPointerDataFieldCount;
pointers[i] = new PointerData(
data[i] = new PointerData(
timeStamp: new Duration(microseconds: packet.getInt64(kStride * offset++, _kFakeHostEndian)),
pointer: packet.getInt64(kStride * offset++, _kFakeHostEndian),
change: PointerChange.values[packet.getInt64(kStride * offset++, _kFakeHostEndian)],
kind: PointerDeviceKind.values[packet.getInt64(kStride * offset++, _kFakeHostEndian)],
device: packet.getInt64(kStride * offset++, _kFakeHostEndian),
physicalX: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
physicalY: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
buttons: packet.getInt64(kStride * offset++, _kFakeHostEndian),
......@@ -120,5 +120,5 @@ PointerDataPacket _unpackPointerDataPacket(ByteData packet) {
);
assert(offset == (i + 1) * _kPointerDataFieldCount);
}
return new PointerDataPacket(pointers: pointers);
return new PointerDataPacket(data: data);
}
......@@ -21,10 +21,15 @@ enum PointerChange {
/// detection range or might have been disconnected from the system entirely.
remove,
/// The pointer has moved with respect to the device while not in contact with
/// the device.
hover,
/// The pointer has made contact with the device.
down,
/// The pointer has moved with respect to the device.
/// The pointer has moved with respect to the device while in contact with the
/// device.
move,
/// The pointer has stopped making contact with the device.
......@@ -51,9 +56,9 @@ class PointerData {
/// Creates an object that represents the state of a pointer.
const PointerData({
this.timeStamp: Duration.ZERO,
this.pointer: 0,
this.change: PointerChange.cancel,
this.kind: PointerDeviceKind.touch,
this.device: 0,
this.physicalX: 0.0,
this.physicalY: 0.0,
this.buttons: 0,
......@@ -74,14 +79,15 @@ class PointerData {
/// Time of event dispatch, relative to an arbitrary timeline.
final Duration timeStamp;
/// Unique identifier for the pointer, potentially reused.
final int pointer;
/// How the pointer has changed since the last report.
final PointerChange change;
/// The kind of input device for which the event was generated.
final PointerDeviceKind kind;
/// Unique identifier for the pointing device, reused across interactions.
final int device;
/// X coordinate of the position of the pointer, in physical pixels in the
/// global coordinate space.
final double physicalX;
......@@ -188,9 +194,9 @@ class PointerData {
String toStringFull() {
return '$runtimeType('
'timeStamp: $timeStamp, '
'pointer: $pointer, '
'change:: $change, '
'change: $change, '
'kind: $kind, '
'device: $device, '
'physicalX: $physicalX, '
'physicalY: $physicalY, '
'buttons: $buttons, '
......@@ -212,10 +218,10 @@ class PointerData {
/// A sequence of reports about the state of pointers.
class PointerDataPacket {
/// Creates a packet of pointer data reports.
const PointerDataPacket({ this.pointers: const <PointerData>[] });
const PointerDataPacket({ this.data: const <PointerData>[] });
/// Data about the individual pointers in this packet.
///
/// This list might contain multiple pieces of data about the same pointer.
final List<PointerData> pointers;
final List<PointerData> data;
}
......@@ -16,6 +16,7 @@ struct alignas(8) PointerData {
kCancel,
kAdd,
kRemove,
kHover,
kDown,
kMove,
kUp,
......@@ -30,9 +31,9 @@ struct alignas(8) PointerData {
};
int64_t time_stamp;
int64_t pointer;
Change change;
DeviceKind kind;
int64_t device;
double physical_x;
double physical_y;
int64_t buttons;
......
......@@ -329,9 +329,9 @@ public class FlutterView extends SurfaceView
long timeStamp = event.getEventTime() * 1000; // Convert from milliseconds to microseconds.
packet.putLong(timeStamp); // time_stamp
packet.putLong(event.getPointerId(pointerIndex)); // pointer
packet.putLong(pointerChange); // change
packet.putLong(pointerKind); // kind
packet.putLong(event.getPointerId(pointerIndex)); // device
packet.putDouble(event.getX(pointerIndex)); // physical_x
packet.putDouble(event.getY(pointerIndex)); // physical_y
......
......@@ -39,6 +39,7 @@ static inline blink::PointerData::Change PointerChangeFromNSEventPhase(
@implementation SkyWindow {
std::unique_ptr<shell::PlatformViewMac> _platformView;
bool _mouseIsDown;
}
@synthesize renderSurface = _renderSurface;
......@@ -118,6 +119,25 @@ static inline blink::PointerData::Change PointerChangeFromNSEventPhase(
pointer_data.pressure = 1.0;
pointer_data.pressure_max = 1.0;
switch (pointer_data.change) {
case blink::PointerData::Change::kDown:
_mouseIsDown = true;
break;
case blink::PointerData::Change::kCancel:
case blink::PointerData::Change::kUp:
_mouseIsDown = false;
break;
case blink::PointerData::Change::kMove:
if (!_mouseIsDown)
pointer_data.change = blink::PointerData::Change::kHover;
break;
case blink::PointerData::Change::kAdd:
case blink::PointerData::Change::kRemove:
case blink::PointerData::Change::kHover:
FTL_DCHECK(!_mouseIsDown);
break;
}
blink::Threads::UI()->PostTask(
[ engine = _platformView->engine().GetWeakPtr(), pointer_data ] {
if (engine.get()) {
......
......@@ -267,21 +267,21 @@ static inline PointerChangeMapperPhase PointerChangePhaseFromUITouchPhase(
int i = 0;
for (UITouch* touch in touches) {
int touch_identifier = 0;
int device_id = 0;
switch (eventTypePhase.second) {
case Accessed:
touch_identifier = _touchMapper.identifierOf(touch);
device_id = _touchMapper.identifierOf(touch);
break;
case Added:
touch_identifier = _touchMapper.registerTouch(touch);
device_id = _touchMapper.registerTouch(touch);
break;
case Removed:
touch_identifier = _touchMapper.unregisterTouch(touch);
device_id = _touchMapper.unregisterTouch(touch);
break;
}
DCHECK(touch_identifier != 0);
DCHECK(device_id != 0);
CGPoint windowCoordinates = [touch locationInView:nil];
blink::PointerData pointer_data;
......@@ -291,7 +291,7 @@ static inline PointerChangeMapperPhase PointerChangePhaseFromUITouchPhase(
pointer_data.time_stamp = touch.timestamp * kMicrosecondsPerSecond;
pointer_data.change = eventTypePhase.first;
pointer_data.kind = blink::PointerData::DeviceKind::kTouch;
pointer_data.pointer = touch_identifier;
pointer_data.device = device_id;
pointer_data.physical_x = windowCoordinates.x * scale;
pointer_data.physical_y = windowCoordinates.y * scale;
pointer_data.pressure = 1.0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册