Commit cbe60510 authored by Mike Wasserman's avatar Mike Wasserman Committed by Commit Bot

mus: Support scroll event transport and dispatch

Add ScrollData and EventMomentumPhase mojo struct, enum, and traits.
Remove lossy ScrollEvent conversion code from PlatformDisplayDefault.
Generalize some EventDispatcher code to support non-pointer events.
Add a basic StructTraitsTest.ScrollEvent unit test.

Bug: 602859, b/73663094
Test: onemilescroll.com, Arc++ scrolls/flings with --enable-features=Mus
Change-Id: Ib6ba95fdd79aa67d5ad1b6b7c4ff9f4b38b3e45b
Reviewed-on: https://chromium-review.googlesource.com/940607Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Commit-Queue: Michael Wasserman <msw@chromium.org>
Cr-Commit-Position: refs/heads/master@{#540367}
parent 6a272677
...@@ -41,13 +41,21 @@ bool IsOnlyOneMouseButtonDown(int flags) { ...@@ -41,13 +41,21 @@ bool IsOnlyOneMouseButtonDown(int flags) {
// This is meant to mirror when implicit capture stops. Specifically non-mouse // This is meant to mirror when implicit capture stops. Specifically non-mouse
// pointer up, or mouse and no more buttons down. // pointer up, or mouse and no more buttons down.
bool IsPointerGoingUp(const PointerEvent& event) { bool IsPointerGoingUp(const Event& event) {
return (event.type() == ui::ET_POINTER_UP || return event.IsPointerEvent() &&
(event.type() == ui::ET_POINTER_UP ||
event.type() == ui::ET_POINTER_CANCELLED) && event.type() == ui::ET_POINTER_CANCELLED) &&
(!event.IsMousePointerEvent() || (!event.IsMousePointerEvent() ||
IsOnlyOneMouseButtonDown(event.flags())); IsOnlyOneMouseButtonDown(event.flags()));
} }
// Get the pointer id from an event, only supports PointerEvents for now.
int32_t GetPointerId(const Event& event) {
if (event.IsPointerEvent())
return event.AsPointerEvent()->pointer_details().id;
return PointerDetails::kUnknownPointerId;
}
} // namespace } // namespace
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
...@@ -311,21 +319,21 @@ void EventDispatcher::ProcessEvent(const ui::Event& event, ...@@ -311,21 +319,21 @@ void EventDispatcher::ProcessEvent(const ui::Event& event,
return; return;
} }
DCHECK(event.IsPointerEvent()); DCHECK(event.IsPointerEvent() || event.IsScrollEvent());
DCHECK(event_location.location == event.AsLocatedEvent()->root_location_f());
DCHECK(event_location.location == event.AsLocatedEvent()->location_f());
DCHECK(!waiting_on_event_targeter_); DCHECK(!waiting_on_event_targeter_);
const EventSource event_source = if (ShouldUseEventTargeter(event)) {
event.IsMousePointerEvent() ? EventSource::MOUSE : EventSource::TOUCH;
DCHECK(event_location.location == event.AsPointerEvent()->root_location_f());
DCHECK(event_location.location == event.AsPointerEvent()->location_f());
if (ShouldUseEventTargeter(*event.AsPointerEvent())) {
waiting_on_event_targeter_ = true; waiting_on_event_targeter_ = true;
const EventSource event_source =
event.IsMousePointerEvent() ? EventSource::MOUSE : EventSource::TOUCH;
event_targeter_->FindTargetForLocation( event_targeter_->FindTargetForLocation(
event_source, event_location, event_source, event_location,
base::BindOnce(&EventDispatcher::ProcessPointerEventOnFoundTarget, base::BindOnce(&EventDispatcher::ProcessEventOnFoundTarget,
base::Unretained(this), *event.AsPointerEvent())); base::Unretained(this), ui::Event::Clone(event)));
} else { } else {
ProcessPointerEventOnFoundTargetImpl(*event.AsPointerEvent(), ProcessEventOnFoundTargetImpl(ui::Event::Clone(event), event_location,
event_location, nullptr); nullptr);
} }
} }
...@@ -438,15 +446,14 @@ void EventDispatcher::HideCursorOnMatchedKeyEvent(const ui::KeyEvent& event) { ...@@ -438,15 +446,14 @@ void EventDispatcher::HideCursorOnMatchedKeyEvent(const ui::KeyEvent& event) {
delegate_->OnEventChangesCursorVisibility(event, false); delegate_->OnEventChangesCursorVisibility(event, false);
} }
bool EventDispatcher::ShouldUseEventTargeter(const PointerEvent& event) const { bool EventDispatcher::ShouldUseEventTargeter(const Event& event) const {
const int32_t pointer_id = event.pointer_details().id;
if (drag_controller_) if (drag_controller_)
return true; return true;
if (capture_window_) if (capture_window_)
return false; return false;
auto iter = pointer_targets_.find(pointer_id); auto iter = pointer_targets_.find(GetPointerId(event));
if (iter == pointer_targets_.end() || !iter->second.is_pointer_down) if (iter == pointer_targets_.end() || !iter->second.is_pointer_down)
return true; return true;
...@@ -454,40 +461,39 @@ bool EventDispatcher::ShouldUseEventTargeter(const PointerEvent& event) const { ...@@ -454,40 +461,39 @@ bool EventDispatcher::ShouldUseEventTargeter(const PointerEvent& event) const {
event.type() == ET_POINTER_DOWN; event.type() == ET_POINTER_DOWN;
} }
void EventDispatcher::ProcessPointerEventOnFoundTarget( void EventDispatcher::ProcessEventOnFoundTarget(
const ui::PointerEvent& event, std::unique_ptr<ui::Event> event,
const EventLocation& event_location, const EventLocation& event_location,
const DeepestWindow& target) { const DeepestWindow& target) {
DCHECK(waiting_on_event_targeter_); DCHECK(waiting_on_event_targeter_);
waiting_on_event_targeter_ = false; waiting_on_event_targeter_ = false;
ProcessPointerEventOnFoundTargetImpl(event, event_location, &target); ProcessEventOnFoundTargetImpl(std::move(event), event_location, &target);
} }
void EventDispatcher::ProcessPointerEventOnFoundTargetImpl( void EventDispatcher::ProcessEventOnFoundTargetImpl(
const ui::PointerEvent& event, std::unique_ptr<ui::Event> event,
const EventLocation& event_location, const EventLocation& event_location,
const DeepestWindow* found_target) { const DeepestWindow* found_target) {
DCHECK(!waiting_on_event_targeter_);
// WARNING: |found_target| may be null! // WARNING: |found_target| may be null!
std::unique_ptr<ui::Event> cloned_event = ui::Event::Clone(event); DCHECK(!waiting_on_event_targeter_);
UpdateCursorRelatedProperties(event, event_location); UpdateCursorRelatedProperties(*event, event_location);
const bool is_mouse_event = event.IsMousePointerEvent(); const bool is_mouse_event = event->IsMousePointerEvent();
const bool is_pointer_going_up = IsPointerGoingUp(event); const bool is_pointer_going_up = IsPointerGoingUp(*event);
// Update mouse down state upon events which change it. // Update mouse down state upon events which change it.
if (is_mouse_event) { if (is_mouse_event) {
if (event.type() == ui::ET_POINTER_DOWN) if (event->type() == ui::ET_POINTER_DOWN)
mouse_button_down_ = true; mouse_button_down_ = true;
else if (is_pointer_going_up) else if (is_pointer_going_up)
mouse_button_down_ = false; mouse_button_down_ = false;
} }
if (drag_controller_) { if (drag_controller_ && event->IsPointerEvent()) {
DCHECK(found_target); DCHECK(found_target);
if (drag_controller_->DispatchPointerEvent( if (drag_controller_->DispatchPointerEvent(
*cloned_event->AsPointerEvent(), *event->AsPointerEvent(),
AdjustTargetForModal(*found_target).window)) { AdjustTargetForModal(*found_target).window)) {
return; return;
} }
...@@ -496,7 +502,7 @@ void EventDispatcher::ProcessPointerEventOnFoundTargetImpl( ...@@ -496,7 +502,7 @@ void EventDispatcher::ProcessPointerEventOnFoundTargetImpl(
if (capture_window_) { if (capture_window_) {
SetMouseCursorSourceWindow(capture_window_); SetMouseCursorSourceWindow(capture_window_);
DispatchToClient(capture_window_, capture_window_client_id_, DispatchToClient(capture_window_, capture_window_client_id_,
*cloned_event->AsPointerEvent(), event_location); *event->AsLocatedEvent(), event_location);
return; return;
} }
...@@ -509,17 +515,16 @@ void EventDispatcher::ProcessPointerEventOnFoundTargetImpl( ...@@ -509,17 +515,16 @@ void EventDispatcher::ProcessPointerEventOnFoundTargetImpl(
result->pointer_target.in_nonclient_area = result->pointer_target.in_nonclient_area =
result->deepest_window.in_non_client_area; result->deepest_window.in_non_client_area;
result->pointer_target.is_pointer_down = result->pointer_target.is_pointer_down =
event.type() == ui::ET_POINTER_DOWN; event->type() == ui::ET_POINTER_DOWN;
result->pointer_target.display_id = event_location.display_id; result->pointer_target.display_id = event_location.display_id;
} }
const int32_t pointer_id = event.pointer_details().id; const int32_t pointer_id = GetPointerId(*event);
if (!IsTrackingPointer(pointer_id) || if (!IsTrackingPointer(pointer_id) ||
!pointer_targets_[pointer_id].is_pointer_down) { !pointer_targets_[pointer_id].is_pointer_down) {
DCHECK(result); DCHECK(result);
const bool any_pointers_down = AreAnyPointersDown(); const bool any_pointers_down = AreAnyPointersDown();
UpdateTargetForPointer(pointer_id, *cloned_event->AsPointerEvent(), UpdateTargetForPointer(pointer_id, *event->AsLocatedEvent(),
result->pointer_target, event_location); result->pointer_target, event_location);
if (is_mouse_event) if (is_mouse_event)
SetMouseCursorSourceWindow(pointer_targets_[pointer_id].window); SetMouseCursorSourceWindow(pointer_targets_[pointer_id].window);
...@@ -550,7 +555,7 @@ void EventDispatcher::ProcessPointerEventOnFoundTargetImpl( ...@@ -550,7 +555,7 @@ void EventDispatcher::ProcessPointerEventOnFoundTargetImpl(
} }
DispatchToPointerTarget(pointer_targets_[pointer_id], DispatchToPointerTarget(pointer_targets_[pointer_id],
*cloned_event->AsPointerEvent(), event_location); *event->AsLocatedEvent(), event_location);
if (is_pointer_going_up) { if (is_pointer_going_up) {
if (is_mouse_event) if (is_mouse_event)
...@@ -561,7 +566,7 @@ void EventDispatcher::ProcessPointerEventOnFoundTargetImpl( ...@@ -561,7 +566,7 @@ void EventDispatcher::ProcessPointerEventOnFoundTargetImpl(
delegate_->ReleaseNativeCapture(); delegate_->ReleaseNativeCapture();
} }
if (event.type() == ET_POINTER_DOWN) { if (event->type() == ET_POINTER_DOWN) {
// Use |found_target| as |result| has already been adjusted for the // Use |found_target| as |result| has already been adjusted for the
// modal window. // modal window.
DCHECK(found_target); DCHECK(found_target);
...@@ -571,7 +576,7 @@ void EventDispatcher::ProcessPointerEventOnFoundTargetImpl( ...@@ -571,7 +576,7 @@ void EventDispatcher::ProcessPointerEventOnFoundTargetImpl(
} }
void EventDispatcher::UpdateCursorRelatedProperties( void EventDispatcher::UpdateCursorRelatedProperties(
const ui::PointerEvent& event, const ui::Event& event,
const EventLocation& event_location) { const EventLocation& event_location) {
if (event.IsMousePointerEvent()) { if (event.IsMousePointerEvent()) {
// This corresponds to the code in CompoundEventFilter which updates // This corresponds to the code in CompoundEventFilter which updates
...@@ -585,7 +590,7 @@ void EventDispatcher::UpdateCursorRelatedProperties( ...@@ -585,7 +590,7 @@ void EventDispatcher::UpdateCursorRelatedProperties(
event_location.display_id); event_location.display_id);
delegate_->OnMouseCursorLocationChanged(event_location.raw_location, delegate_->OnMouseCursorLocationChanged(event_location.raw_location,
event_location.display_id); event_location.display_id);
} else { } else if (event.IsPointerEvent()) {
// When we have a non-touch event that wasn't synthesized, hide the mouse // When we have a non-touch event that wasn't synthesized, hide the mouse
// cursor until the next non-synthesized mouse event. // cursor until the next non-synthesized mouse event.
delegate_->OnEventChangesCursorTouchVisibility(event, false); delegate_->OnEventChangesCursorTouchVisibility(event, false);
...@@ -663,7 +668,7 @@ void EventDispatcher::StopTrackingPointer(int32_t pointer_id) { ...@@ -663,7 +668,7 @@ void EventDispatcher::StopTrackingPointer(int32_t pointer_id) {
void EventDispatcher::UpdateTargetForPointer( void EventDispatcher::UpdateTargetForPointer(
int32_t pointer_id, int32_t pointer_id,
const ui::PointerEvent& event, const ui::LocatedEvent& event,
const PointerTarget& pointer_target, const PointerTarget& pointer_target,
const EventLocation& event_location) { const EventLocation& event_location) {
if (!IsTrackingPointer(pointer_id)) { if (!IsTrackingPointer(pointer_id)) {
......
...@@ -33,7 +33,6 @@ namespace ui { ...@@ -33,7 +33,6 @@ namespace ui {
class Event; class Event;
class KeyEvent; class KeyEvent;
class LocatedEvent; class LocatedEvent;
class PointerEvent;
namespace ws { namespace ws {
...@@ -241,16 +240,16 @@ class EventDispatcher : public ServerWindowDrawnTrackerObserver, ...@@ -241,16 +240,16 @@ class EventDispatcher : public ServerWindowDrawnTrackerObserver,
return pointer_targets_.count(pointer_id) > 0; return pointer_targets_.count(pointer_id) > 0;
} }
// Returns true if EventTargeter needs to queried for the specified event. // Returns true if EventTargeter needs to be queried for the specified event.
bool ShouldUseEventTargeter(const PointerEvent& event) const; bool ShouldUseEventTargeter(const Event& event) const;
// Callback from EventTargeter once the target has been found. Calls // Callback from EventTargeter once the target has been found. Calls
// ProcessPointerEventOnFoundTargetImpl(). // ProcessEventOnFoundTargetImpl().
void ProcessPointerEventOnFoundTarget(const ui::PointerEvent& event, void ProcessEventOnFoundTarget(std::unique_ptr<ui::Event> event,
const EventLocation& event_location, const EventLocation& event_location,
const DeepestWindow& target); const DeepestWindow& target);
// EventDispatcher provides the following logic for pointer events: // EventDispatcher provides the following logic for events:
// . wheel events go to the current target of the associated pointer. If // . wheel events go to the current target of the associated pointer. If
// there is no target, they go to the deepest window. // there is no target, they go to the deepest window.
// . move (not drag) events go to the deepest window. // . move (not drag) events go to the deepest window.
...@@ -264,13 +263,12 @@ class EventDispatcher : public ServerWindowDrawnTrackerObserver, ...@@ -264,13 +263,12 @@ class EventDispatcher : public ServerWindowDrawnTrackerObserver,
// If ShouldUseEventTargeter() returned false it means this function should // If ShouldUseEventTargeter() returned false it means this function should
// not need |found_target| and has enough information to process the event // not need |found_target| and has enough information to process the event
// without a DeepestWindow. // without a DeepestWindow.
void ProcessPointerEventOnFoundTargetImpl(const ui::PointerEvent& event, void ProcessEventOnFoundTargetImpl(std::unique_ptr<ui::Event> event,
const EventLocation& event_location, const EventLocation& event_location,
const DeepestWindow* found_target); const DeepestWindow* found_target);
// Called when processing a pointer event to updated cursor related // Called when processing a event to updated cursor related properties.
// properties. void UpdateCursorRelatedProperties(const ui::Event& event,
void UpdateCursorRelatedProperties(const ui::PointerEvent& event,
const EventLocation& event_location); const EventLocation& event_location);
void UpdateNonClientAreaForCurrentWindowOnFoundWindow( void UpdateNonClientAreaForCurrentWindowOnFoundWindow(
...@@ -301,7 +299,7 @@ class EventDispatcher : public ServerWindowDrawnTrackerObserver, ...@@ -301,7 +299,7 @@ class EventDispatcher : public ServerWindowDrawnTrackerObserver,
// pointer sends the appropriate event to the delegate and updates the // pointer sends the appropriate event to the delegate and updates the
// currently tracked PointerTarget appropriately. // currently tracked PointerTarget appropriately.
void UpdateTargetForPointer(int32_t pointer_id, void UpdateTargetForPointer(int32_t pointer_id,
const ui::PointerEvent& event, const ui::LocatedEvent& event,
const PointerTarget& pointer_target, const PointerTarget& pointer_target,
const EventLocation& event_location); const EventLocation& event_location);
......
...@@ -203,16 +203,8 @@ void PlatformDisplayDefault::OnDamageRect(const gfx::Rect& damaged_region) { ...@@ -203,16 +203,8 @@ void PlatformDisplayDefault::OnDamageRect(const gfx::Rect& damaged_region) {
} }
void PlatformDisplayDefault::DispatchEvent(ui::Event* event) { void PlatformDisplayDefault::DispatchEvent(ui::Event* event) {
// Event location and event root location are the same, and both in pixels // Mojo requires conversion of mouse and touch events to pointer events.
// and display coordinates. if (event->IsMouseEvent()) {
if (event->IsScrollEvent()) {
// TODO(moshayedi): crbug.com/602859. Dispatch scroll events as
// they are once we have proper support for scroll events.
ui::PointerEvent pointer_event(
ui::MouseWheelEvent(*event->AsScrollEvent()));
SendEventToSink(&pointer_event);
} else if (event->IsMouseEvent()) {
ui::PointerEvent pointer_event(*event->AsMouseEvent()); ui::PointerEvent pointer_event(*event->AsMouseEvent());
SendEventToSink(&pointer_event); SendEventToSink(&pointer_event);
} else if (event->IsTouchEvent()) { } else if (event->IsTouchEvent()) {
......
...@@ -122,6 +122,24 @@ struct GestureData { ...@@ -122,6 +122,24 @@ struct GestureData {
LocationData location; LocationData location;
}; };
// Data to support scroll events.
struct ScrollData {
LocationData location;
// Potential accelerated offsets.
float x_offset;
float y_offset;
// Unaccelerated offsets.
float x_offset_ordinal;
float y_offset_ordinal;
// Number of fingers on the pad.
int32 finger_count;
// For non-fling events, provides momentum information (e.g. for the case
// where the device provides continuous event updates during a fling).
EventMomentumPhase momentum_phase;
};
struct Event { struct Event {
// TODO(sky): rename to type. // TODO(sky): rename to type.
EventType action; EventType action;
...@@ -138,4 +156,5 @@ struct Event { ...@@ -138,4 +156,5 @@ struct Event {
KeyData? key_data; KeyData? key_data;
PointerData? pointer_data; PointerData? pointer_data;
GestureData? gesture_data; GestureData? gesture_data;
ScrollData? scroll_data;
}; };
...@@ -21,4 +21,7 @@ sources = [ ...@@ -21,4 +21,7 @@ sources = [
] ]
# TODO(moshayedi): crbug.com/617167. Map mojom.Event directly to ui::Event. # TODO(moshayedi): crbug.com/617167. Map mojom.Event directly to ui::Event.
type_mappings = [ "ui.mojom.Event=std::unique_ptr<ui::Event>[move_only]" ] type_mappings = [
"ui.mojom.Event=std::unique_ptr<ui::Event>[move_only]",
"ui.mojom.EventMomentumPhase=ui::EventMomentumPhase",
]
...@@ -23,6 +23,9 @@ enum EventType { ...@@ -23,6 +23,9 @@ enum EventType {
POINTER_WHEEL_CHANGED, POINTER_WHEEL_CHANGED,
MOUSE_EXIT, MOUSE_EXIT,
GESTURE_TAP, GESTURE_TAP,
SCROLL,
SCROLL_FLING_START,
SCROLL_FLING_CANCEL,
}; };
// This mirrors ui::EventFlags // This mirrors ui::EventFlags
...@@ -63,3 +66,12 @@ enum WheelMode { ...@@ -63,3 +66,12 @@ enum WheelMode {
PAGE, PAGE,
SCALING, SCALING,
}; };
// Momentum phase information used for a ScrollEvent.
// These values match ui::EventMomentumPhase in ui/events/event_constants.h
enum EventMomentumPhase {
NONE,
MAY_BEGIN,
INERTIAL_UPDATE,
END,
};
\ No newline at end of file
...@@ -43,6 +43,15 @@ ui::mojom::EventType UIEventTypeToMojo(ui::EventType type) { ...@@ -43,6 +43,15 @@ ui::mojom::EventType UIEventTypeToMojo(ui::EventType type) {
case ui::ET_GESTURE_TAP: case ui::ET_GESTURE_TAP:
return ui::mojom::EventType::GESTURE_TAP; return ui::mojom::EventType::GESTURE_TAP;
case ui::ET_SCROLL:
return ui::mojom::EventType::SCROLL;
case ui::ET_SCROLL_FLING_START:
return ui::mojom::EventType::SCROLL_FLING_START;
case ui::ET_SCROLL_FLING_CANCEL:
return ui::mojom::EventType::SCROLL_FLING_CANCEL;
default: default:
NOTREACHED() << "This unsupported event type will close the connection"; NOTREACHED() << "This unsupported event type will close the connection";
break; break;
...@@ -70,6 +79,15 @@ ui::EventType MojoPointerEventTypeToUIEvent(ui::mojom::EventType action) { ...@@ -70,6 +79,15 @@ ui::EventType MojoPointerEventTypeToUIEvent(ui::mojom::EventType action) {
case ui::mojom::EventType::POINTER_WHEEL_CHANGED: case ui::mojom::EventType::POINTER_WHEEL_CHANGED:
return ui::ET_POINTER_WHEEL_CHANGED; return ui::ET_POINTER_WHEEL_CHANGED;
case ui::mojom::EventType::SCROLL:
return ui::ET_SCROLL;
case ui::mojom::EventType::SCROLL_FLING_START:
return ui::ET_SCROLL_FLING_START;
case ui::mojom::EventType::SCROLL_FLING_CANCEL:
return ui::ET_SCROLL_FLING_CANCEL;
default: default:
NOTREACHED(); NOTREACHED();
} }
...@@ -77,7 +95,7 @@ ui::EventType MojoPointerEventTypeToUIEvent(ui::mojom::EventType action) { ...@@ -77,7 +95,7 @@ ui::EventType MojoPointerEventTypeToUIEvent(ui::mojom::EventType action) {
return ui::ET_UNKNOWN; return ui::ET_UNKNOWN;
} }
ui::mojom::LocationDataPtr GetLocationData(ui::LocatedEvent* event) { ui::mojom::LocationDataPtr GetLocationData(const ui::LocatedEvent* event) {
ui::mojom::LocationDataPtr location_data(ui::mojom::LocationData::New()); ui::mojom::LocationDataPtr location_data(ui::mojom::LocationData::New());
location_data->x = event->location_f().x(); location_data->x = event->location_f().x();
location_data->y = event->location_f().y(); location_data->y = event->location_f().y();
...@@ -319,6 +337,24 @@ StructTraits<ui::mojom::EventDataView, EventUniquePtr>::gesture_data( ...@@ -319,6 +337,24 @@ StructTraits<ui::mojom::EventDataView, EventUniquePtr>::gesture_data(
return gesture_data; return gesture_data;
} }
ui::mojom::ScrollDataPtr
StructTraits<ui::mojom::EventDataView, EventUniquePtr>::scroll_data(
const EventUniquePtr& event) {
if (!event->IsScrollEvent())
return nullptr;
ui::mojom::ScrollDataPtr scroll_data(ui::mojom::ScrollData::New());
scroll_data->location = GetLocationData(event->AsLocatedEvent());
const ui::ScrollEvent* scroll_event = event->AsScrollEvent();
scroll_data->x_offset = scroll_event->x_offset();
scroll_data->y_offset = scroll_event->y_offset();
scroll_data->x_offset_ordinal = scroll_event->x_offset_ordinal();
scroll_data->y_offset_ordinal = scroll_event->y_offset_ordinal();
scroll_data->finger_count = scroll_event->finger_count();
scroll_data->momentum_phase = scroll_event->momentum_phase();
return scroll_data;
}
bool StructTraits<ui::mojom::EventDataView, EventUniquePtr>::Read( bool StructTraits<ui::mojom::EventDataView, EventUniquePtr>::Read(
ui::mojom::EventDataView event, ui::mojom::EventDataView event,
EventUniquePtr* out) { EventUniquePtr* out) {
...@@ -386,6 +422,22 @@ bool StructTraits<ui::mojom::EventDataView, EventUniquePtr>::Read( ...@@ -386,6 +422,22 @@ bool StructTraits<ui::mojom::EventDataView, EventUniquePtr>::Read(
time_stamp, ui::GestureEventDetails(ui::ET_GESTURE_TAP)); time_stamp, ui::GestureEventDetails(ui::ET_GESTURE_TAP));
break; break;
} }
case ui::mojom::EventType::SCROLL:
case ui::mojom::EventType::SCROLL_FLING_START:
case ui::mojom::EventType::SCROLL_FLING_CANCEL: {
ui::mojom::ScrollDataPtr scroll_data;
if (!event.ReadScrollData<ui::mojom::ScrollDataPtr>(&scroll_data))
return false;
*out = std::make_unique<ui::ScrollEvent>(
MojoPointerEventTypeToUIEvent(event.action()),
gfx::Point(scroll_data->location->x, scroll_data->location->y),
time_stamp, event.flags(), scroll_data->x_offset,
scroll_data->y_offset, scroll_data->x_offset_ordinal,
scroll_data->y_offset_ordinal, scroll_data->finger_count,
scroll_data->momentum_phase);
break;
}
case ui::mojom::EventType::UNKNOWN: case ui::mojom::EventType::UNKNOWN:
NOTREACHED() << "This unsupported event type will close the connection"; NOTREACHED() << "This unsupported event type will close the connection";
return false; return false;
......
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
#ifndef UI_EVENTS_MOJO_EVENT_STRUCT_TRAITS_H_ #ifndef UI_EVENTS_MOJO_EVENT_STRUCT_TRAITS_H_
#define UI_EVENTS_MOJO_EVENT_STRUCT_TRAITS_H_ #define UI_EVENTS_MOJO_EVENT_STRUCT_TRAITS_H_
#include "ui/events/event_constants.h"
#include "ui/events/mojo/event.mojom.h" #include "ui/events/mojo/event.mojom.h"
#include "ui/events/mojo/event_constants.mojom.h"
namespace ui { namespace ui {
class Event; class Event;
...@@ -25,9 +27,48 @@ struct StructTraits<ui::mojom::EventDataView, EventUniquePtr> { ...@@ -25,9 +27,48 @@ struct StructTraits<ui::mojom::EventDataView, EventUniquePtr> {
static ui::mojom::KeyDataPtr key_data(const EventUniquePtr& event); static ui::mojom::KeyDataPtr key_data(const EventUniquePtr& event);
static ui::mojom::PointerDataPtr pointer_data(const EventUniquePtr& event); static ui::mojom::PointerDataPtr pointer_data(const EventUniquePtr& event);
static ui::mojom::GestureDataPtr gesture_data(const EventUniquePtr& event); static ui::mojom::GestureDataPtr gesture_data(const EventUniquePtr& event);
static ui::mojom::ScrollDataPtr scroll_data(const EventUniquePtr& event);
static bool Read(ui::mojom::EventDataView r, EventUniquePtr* out); static bool Read(ui::mojom::EventDataView r, EventUniquePtr* out);
}; };
template <>
struct EnumTraits<ui::mojom::EventMomentumPhase, ui::EventMomentumPhase> {
static ui::mojom::EventMomentumPhase ToMojom(ui::EventMomentumPhase input) {
switch (input) {
case ui::EventMomentumPhase::NONE:
return ui::mojom::EventMomentumPhase::NONE;
case ui::EventMomentumPhase::MAY_BEGIN:
return ui::mojom::EventMomentumPhase::MAY_BEGIN;
case ui::EventMomentumPhase::INERTIAL_UPDATE:
return ui::mojom::EventMomentumPhase::INERTIAL_UPDATE;
case ui::EventMomentumPhase::END:
return ui::mojom::EventMomentumPhase::END;
}
NOTREACHED();
return ui::mojom::EventMomentumPhase::NONE;
}
static bool FromMojom(ui::mojom::EventMomentumPhase input,
ui::EventMomentumPhase* out) {
switch (input) {
case ui::mojom::EventMomentumPhase::NONE:
*out = ui::EventMomentumPhase::NONE;
return true;
case ui::mojom::EventMomentumPhase::MAY_BEGIN:
*out = ui::EventMomentumPhase::MAY_BEGIN;
return true;
case ui::mojom::EventMomentumPhase::INERTIAL_UPDATE:
*out = ui::EventMomentumPhase::INERTIAL_UPDATE;
return true;
case ui::mojom::EventMomentumPhase::END:
*out = ui::EventMomentumPhase::END;
return true;
}
NOTREACHED();
return false;
}
};
} // namespace mojo } // namespace mojo
#endif // UI_EVENTS_MOJO_EVENT_STRUCT_TRAITS_H_ #endif // UI_EVENTS_MOJO_EVENT_STRUCT_TRAITS_H_
...@@ -250,4 +250,40 @@ TEST_F(StructTraitsTest, GestureEvent) { ...@@ -250,4 +250,40 @@ TEST_F(StructTraitsTest, GestureEvent) {
} }
} }
TEST_F(StructTraitsTest, ScrollEvent) {
ScrollEvent kTestData[] = {
{ET_SCROLL, gfx::Point(10, 20),
base::TimeTicks() + base::TimeDelta::FromMicroseconds(501), EF_NONE, 1,
2, 3, 4, 5, EventMomentumPhase::NONE},
{ET_SCROLL_FLING_START, gfx::Point(10, 20),
base::TimeTicks() + base::TimeDelta::FromMicroseconds(502), EF_NONE, 1,
2, 3, 4, 5, EventMomentumPhase::MAY_BEGIN},
{ET_SCROLL_FLING_CANCEL, gfx::Point(10, 20),
base::TimeTicks() + base::TimeDelta::FromMicroseconds(502), EF_NONE, 1,
2, 3, 4, 5, EventMomentumPhase::END},
};
mojom::TraitsTestServicePtr proxy = GetTraitsTestProxy();
for (size_t i = 0; i < arraysize(kTestData); i++) {
std::unique_ptr<Event> output;
proxy->EchoEvent(Event::Clone(kTestData[i]), &output);
EXPECT_TRUE(output->IsScrollEvent());
const ScrollEvent* output_ptr_event = output->AsScrollEvent();
EXPECT_EQ(kTestData[i].type(), output_ptr_event->type());
EXPECT_EQ(kTestData[i].location(), output_ptr_event->location());
EXPECT_EQ(kTestData[i].time_stamp(), output_ptr_event->time_stamp());
EXPECT_EQ(kTestData[i].flags(), output_ptr_event->flags());
EXPECT_EQ(kTestData[i].x_offset(), output_ptr_event->x_offset());
EXPECT_EQ(kTestData[i].y_offset(), output_ptr_event->y_offset());
EXPECT_EQ(kTestData[i].x_offset_ordinal(),
output_ptr_event->x_offset_ordinal());
EXPECT_EQ(kTestData[i].y_offset_ordinal(),
output_ptr_event->y_offset_ordinal());
EXPECT_EQ(kTestData[i].finger_count(), output_ptr_event->finger_count());
EXPECT_EQ(kTestData[i].momentum_phase(),
output_ptr_event->momentum_phase());
}
}
} // namespace ui } // namespace ui
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment