Commit 71247087 authored by Christopher Cameron's avatar Christopher Cameron Committed by Commit Bot

Support Mouse event types in Mojo events.

This allows mouse type events to be passed through Mojo.

Bug: 881509
Change-Id: I8bdcf980e7dce0fea5b71c285f86956cd334f7e5
Reviewed-on: https://chromium-review.googlesource.com/1211916
Commit-Queue: ccameron <ccameron@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarMichael Wasserman <msw@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#593113}
parent 77d1f8fe
......@@ -29,6 +29,17 @@ enum EventType {
SCROLL_FLING_START,
SCROLL_FLING_CANCEL,
CANCEL_MODE,
// MOUSE_MOVED has a naming conflict in Windows, where there is a
// #define MOUSE_MOVED. Therefore we had to add the suffix, _EVENT. for
// consistency, all other mouse event types also were given this suffix.
MOUSE_PRESSED_EVENT,
MOUSE_DRAGGED_EVENT,
MOUSE_RELEASED_EVENT,
MOUSE_MOVED_EVENT,
MOUSE_ENTERED_EVENT,
MOUSE_EXITED_EVENT,
MOUSE_WHEEL_EVENT,
MOUSE_CAPTURE_CHANGED_EVENT,
};
// This mirrors ui::EventFlags
......
......@@ -41,12 +41,28 @@ ui::EventPointerType PointerTypeFromPointerKind(ui::mojom::PointerKind kind) {
return ui::EventPointerType::POINTER_TYPE_UNKNOWN;
}
void UpdateEventLocation(const ui::mojom::PointerData& pointer_data,
EventUniquePtr* out) {
// TODO(katie): Update LocationData to have two PointF instead of storing this
// as four floats.
const gfx::PointF location(pointer_data.location->x,
pointer_data.location->y);
const gfx::PointF screen_location(pointer_data.location->screen_x,
pointer_data.location->screen_y);
// Set the float location, as the constructor only takes a gfx::Point.
// This uses the event root_location field to store screen pixel
// coordinates. See http://crbug.com/608547
out->get()->AsLocatedEvent()->set_location_f(location);
out->get()->AsLocatedEvent()->set_root_location_f(screen_location);
}
bool ReadPointerDetails(ui::mojom::EventType event_type,
const ui::mojom::PointerData& pointer_data,
ui::PointerDetails* out) {
switch (pointer_data.kind) {
case ui::mojom::PointerKind::MOUSE: {
if (event_type == ui::mojom::EventType::POINTER_WHEEL_CHANGED) {
if (event_type == ui::mojom::EventType::POINTER_WHEEL_CHANGED ||
event_type == ui::mojom::EventType::MOUSE_WHEEL_EVENT) {
*out = ui::PointerDetails(
ui::EventPointerType::POINTER_TYPE_MOUSE,
gfx::Vector2d(static_cast<int>(pointer_data.wheel_data->delta_x),
......@@ -193,6 +209,22 @@ ui::mojom::EventType TypeConverter<ui::mojom::EventType,
return ui::mojom::EventType::SCROLL_FLING_CANCEL;
case ui::ET_CANCEL_MODE:
return ui::mojom::EventType::CANCEL_MODE;
case ui::ET_MOUSE_PRESSED:
return ui::mojom::EventType::MOUSE_PRESSED_EVENT;
case ui::ET_MOUSE_DRAGGED:
return ui::mojom::EventType::MOUSE_DRAGGED_EVENT;
case ui::ET_MOUSE_RELEASED:
return ui::mojom::EventType::MOUSE_RELEASED_EVENT;
case ui::ET_MOUSE_MOVED:
return ui::mojom::EventType::MOUSE_MOVED_EVENT;
case ui::ET_MOUSE_ENTERED:
return ui::mojom::EventType::MOUSE_ENTERED_EVENT;
case ui::ET_MOUSE_EXITED:
return ui::mojom::EventType::MOUSE_EXITED_EVENT;
case ui::ET_MOUSEWHEEL:
return ui::mojom::EventType::MOUSE_WHEEL_EVENT;
case ui::ET_MOUSE_CAPTURE_CHANGED:
return ui::mojom::EventType::MOUSE_CAPTURE_CHANGED_EVENT;
default:
NOTREACHED() << "Using unknown event types closes connections:"
<< ui::EventTypeName(type);
......@@ -235,6 +267,22 @@ ui::EventType TypeConverter<ui::EventType, ui::mojom::EventType>::Convert(
return ui::ET_SCROLL_FLING_START;
case ui::mojom::EventType::SCROLL_FLING_CANCEL:
return ui::ET_SCROLL_FLING_CANCEL;
case ui::mojom::EventType::MOUSE_PRESSED_EVENT:
return ui::ET_MOUSE_PRESSED;
case ui::mojom::EventType::MOUSE_DRAGGED_EVENT:
return ui::ET_MOUSE_DRAGGED;
case ui::mojom::EventType::MOUSE_RELEASED_EVENT:
return ui::ET_MOUSE_RELEASED;
case ui::mojom::EventType::MOUSE_MOVED_EVENT:
return ui::ET_MOUSE_MOVED;
case ui::mojom::EventType::MOUSE_ENTERED_EVENT:
return ui::ET_MOUSE_ENTERED;
case ui::mojom::EventType::MOUSE_EXITED_EVENT:
return ui::ET_MOUSE_EXITED;
case ui::mojom::EventType::MOUSE_WHEEL_EVENT:
return ui::ET_MOUSEWHEEL;
case ui::mojom::EventType::MOUSE_CAPTURE_CHANGED_EVENT:
return ui::ET_MOUSE_CAPTURE_CHANGED;
default:
NOTREACHED();
}
......@@ -293,14 +341,25 @@ StructTraits<ui::mojom::EventDataView, EventUniquePtr>::key_data(
ui::mojom::PointerDataPtr
StructTraits<ui::mojom::EventDataView, EventUniquePtr>::pointer_data(
const EventUniquePtr& event) {
if (!event->IsPointerEvent())
if (!event->IsPointerEvent() && !event->IsMouseEvent())
return nullptr;
const ui::PointerEvent* pointer_event = event->AsPointerEvent();
ui::mojom::PointerDataPtr pointer_data(ui::mojom::PointerData::New());
pointer_data->pointer_id = pointer_event->pointer_details().id;
pointer_data->changed_button_flags = pointer_event->changed_button_flags();
const ui::PointerDetails* pointer_details = &pointer_event->pointer_details();
const ui::PointerDetails* pointer_details;
if (event->IsPointerEvent()) {
const ui::PointerEvent* pointer_event = event->AsPointerEvent();
pointer_data->changed_button_flags = pointer_event->changed_button_flags();
pointer_data->location = GetLocationData(event->AsLocatedEvent());
pointer_details = &pointer_event->pointer_details();
} else {
// Mouse event
const ui::MouseEvent* mouse_event = event->AsMouseEvent();
pointer_data->changed_button_flags = mouse_event->changed_button_flags();
pointer_data->location = GetLocationData(mouse_event);
pointer_details = &mouse_event->pointer_details();
}
pointer_data->pointer_id = pointer_details->id;
ui::EventPointerType pointer_type = pointer_details->pointer_type;
switch (pointer_type) {
......@@ -338,9 +397,8 @@ StructTraits<ui::mojom::EventDataView, EventUniquePtr>::pointer_data(
// TODO(rjkroege): Handle force-touch on MacOS
// TODO(rjkroege): Adjust brush data appropriately for Android.
pointer_data->location = GetLocationData(event->AsLocatedEvent());
if (event->type() == ui::ET_POINTER_WHEEL_CHANGED) {
if (event->type() == ui::ET_POINTER_WHEEL_CHANGED ||
event->type() == ui::ET_MOUSEWHEEL) {
ui::mojom::WheelDataPtr wheel_data(ui::mojom::WheelData::New());
// TODO(rjkroege): Support page scrolling on windows by directly
......@@ -451,16 +509,12 @@ bool StructTraits<ui::mojom::EventDataView, EventUniquePtr>::Read(
if (!ReadPointerDetails(event.action(), *pointer_data, &pointer_details))
return false;
const gfx::Point location(pointer_data->location->x,
pointer_data->location->y);
const gfx::Point screen_location(pointer_data->location->screen_x,
pointer_data->location->screen_y);
// This uses the event root_location field to store screen pixel
// coordinates. See http://crbug.com/608547
*out = std::make_unique<ui::PointerEvent>(
mojo::ConvertTo<ui::EventType>(event.action()), location,
screen_location, event.flags(), pointer_data->changed_button_flags,
mojo::ConvertTo<ui::EventType>(event.action()), gfx::Point(),
gfx::Point(), event.flags(), pointer_data->changed_button_flags,
pointer_details, time_stamp);
UpdateEventLocation(*pointer_data, out);
break;
}
case ui::mojom::EventType::GESTURE_TAP:
......@@ -485,6 +539,42 @@ bool StructTraits<ui::mojom::EventDataView, EventUniquePtr>::Read(
case ui::mojom::EventType::CANCEL_MODE:
*out = std::make_unique<ui::CancelModeEvent>();
break;
case ui::mojom::EventType::MOUSE_PRESSED_EVENT:
case ui::mojom::EventType::MOUSE_RELEASED_EVENT:
case ui::mojom::EventType::MOUSE_DRAGGED_EVENT:
case ui::mojom::EventType::MOUSE_MOVED_EVENT:
case ui::mojom::EventType::MOUSE_ENTERED_EVENT:
case ui::mojom::EventType::MOUSE_EXITED_EVENT:
case ui::mojom::EventType::MOUSE_WHEEL_EVENT:
case ui::mojom::EventType::MOUSE_CAPTURE_CHANGED_EVENT: {
ui::mojom::PointerDataPtr pointer_data;
if (!event.ReadPointerData<ui::mojom::PointerDataPtr>(&pointer_data))
return false;
ui::PointerDetails pointer_details;
if (!ReadPointerDetails(event.action(), *pointer_data, &pointer_details))
return false;
if (event.action() == ui::mojom::EventType::MOUSE_WHEEL_EVENT) {
// Use the mouse event to construct a MouseWheel event to avoid asserts
// in ui::MouseEvent's constructor that ensure it is not used to create
// a wheel event.
ui::MouseEvent mouse_event(
ui::ET_MOUSE_MOVED, gfx::Point(), gfx::Point(), time_stamp,
event.flags(), pointer_data->changed_button_flags, pointer_details);
*out = std::make_unique<ui::MouseWheelEvent>(
mouse_event, pointer_details.offset.x(),
pointer_details.offset.y());
} else {
*out = std::make_unique<ui::MouseEvent>(
mojo::ConvertTo<ui::EventType>(event.action()), gfx::Point(),
gfx::Point(), time_stamp, event.flags(),
pointer_data->changed_button_flags, pointer_details);
}
UpdateEventLocation(*pointer_data, out);
break;
}
case ui::mojom::EventType::UNKNOWN:
NOTREACHED() << "Using unknown event types closes connections";
return false;
......
......@@ -189,6 +189,63 @@ TEST_F(StructTraitsTest, PointerEvent) {
}
}
TEST_F(StructTraitsTest, MouseEvent) {
MouseEvent kTestData[] = {
{ET_MOUSE_PRESSED, gfx::Point(10, 10), gfx::Point(20, 30),
base::TimeTicks() + base::TimeDelta::FromMicroseconds(201), EF_NONE, 0,
PointerDetails(EventPointerType::POINTER_TYPE_MOUSE,
MouseEvent::kMousePointerId)},
{ET_MOUSE_DRAGGED, gfx::Point(1, 5), gfx::Point(5, 1),
base::TimeTicks() + base::TimeDelta::FromMicroseconds(202),
EF_LEFT_MOUSE_BUTTON, EF_LEFT_MOUSE_BUTTON,
PointerDetails(EventPointerType::POINTER_TYPE_MOUSE,
MouseEvent::kMousePointerId)},
{ET_MOUSE_RELEASED, gfx::Point(411, 130), gfx::Point(20, 30),
base::TimeTicks() + base::TimeDelta::FromMicroseconds(203),
EF_MIDDLE_MOUSE_BUTTON | EF_RIGHT_MOUSE_BUTTON, EF_RIGHT_MOUSE_BUTTON,
PointerDetails(EventPointerType::POINTER_TYPE_MOUSE,
MouseEvent::kMousePointerId)},
{ET_MOUSE_MOVED, gfx::Point(0, 1), gfx::Point(2, 3),
base::TimeTicks() + base::TimeDelta::FromMicroseconds(204), EF_ALT_DOWN,
0,
PointerDetails(EventPointerType::POINTER_TYPE_MOUSE,
MouseEvent::kMousePointerId)},
{ET_MOUSE_ENTERED, gfx::Point(6, 7), gfx::Point(8, 9),
base::TimeTicks() + base::TimeDelta::FromMicroseconds(205), EF_NONE, 0,
PointerDetails(EventPointerType::POINTER_TYPE_MOUSE,
MouseEvent::kMousePointerId)},
{ET_MOUSE_EXITED, gfx::Point(10, 10), gfx::Point(20, 30),
base::TimeTicks() + base::TimeDelta::FromMicroseconds(206),
EF_BACK_MOUSE_BUTTON, 0,
PointerDetails(EventPointerType::POINTER_TYPE_MOUSE,
MouseEvent::kMousePointerId)},
{ET_MOUSE_CAPTURE_CHANGED, gfx::Point(99, 99), gfx::Point(99, 99),
base::TimeTicks() + base::TimeDelta::FromMicroseconds(207),
EF_CONTROL_DOWN, 0,
PointerDetails(EventPointerType::POINTER_TYPE_MOUSE,
MouseEvent::kMousePointerId)},
};
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);
ASSERT_TRUE(output->IsMouseEvent());
const MouseEvent* output_event = output->AsMouseEvent();
EXPECT_EQ(kTestData[i].type(), output_event->type());
EXPECT_EQ(kTestData[i].flags(), output_event->flags());
EXPECT_EQ(kTestData[i].location(), output_event->location());
EXPECT_EQ(kTestData[i].root_location(), output_event->root_location());
EXPECT_EQ(kTestData[i].pointer_details().id,
output_event->pointer_details().id);
EXPECT_EQ(kTestData[i].changed_button_flags(),
output_event->changed_button_flags());
EXPECT_EQ(kTestData[i].pointer_details(), output_event->pointer_details());
EXPECT_EQ(kTestData[i].time_stamp(), output_event->time_stamp());
}
}
TEST_F(StructTraitsTest, PointerWheelEvent) {
MouseWheelEvent kTestData[] = {
{gfx::Vector2d(11, 15), gfx::Point(3, 4), gfx::Point(40, 30),
......@@ -221,6 +278,62 @@ TEST_F(StructTraitsTest, PointerWheelEvent) {
}
}
TEST_F(StructTraitsTest, MouseWheelEvent) {
MouseWheelEvent kTestData[] = {
{gfx::Vector2d(11, 15), gfx::Point(3, 4), gfx::Point(40, 30),
base::TimeTicks() + base::TimeDelta::FromMicroseconds(301),
EF_LEFT_MOUSE_BUTTON, EF_LEFT_MOUSE_BUTTON},
{gfx::Vector2d(-5, 3), gfx::Point(40, 3), gfx::Point(4, 0),
base::TimeTicks() + base::TimeDelta::FromMicroseconds(302),
EF_MIDDLE_MOUSE_BUTTON | EF_RIGHT_MOUSE_BUTTON,
EF_MIDDLE_MOUSE_BUTTON | EF_RIGHT_MOUSE_BUTTON},
{gfx::Vector2d(1, 0), gfx::Point(3, 4), gfx::Point(40, 30),
base::TimeTicks() + base::TimeDelta::FromMicroseconds(303), EF_NONE,
EF_NONE},
};
mojom::TraitsTestServicePtr proxy = GetTraitsTestProxy();
for (size_t i = 0; i < arraysize(kTestData); i++) {
std::unique_ptr<Event> output;
proxy->EchoEvent(
Event::Clone(ui::MouseWheelEvent(ui::PointerEvent(kTestData[i]))),
&output);
ASSERT_EQ(ET_MOUSEWHEEL, output->type());
const MouseWheelEvent* output_event = output->AsMouseWheelEvent();
EXPECT_EQ(ET_MOUSEWHEEL, output_event->type());
EXPECT_EQ(kTestData[i].flags(), output_event->flags());
EXPECT_EQ(kTestData[i].location(), output_event->location());
EXPECT_EQ(kTestData[i].root_location(), output_event->root_location());
EXPECT_EQ(kTestData[i].offset(), output_event->offset());
EXPECT_EQ(kTestData[i].time_stamp(), output_event->time_stamp());
}
}
TEST_F(StructTraitsTest, FloatingPointLocations) {
ui::MouseEvent input_event = ui::MouseEvent(
ET_MOUSE_PRESSED, gfx::Point(10, 10), gfx::Point(20, 30),
base::TimeTicks() + base::TimeDelta::FromMicroseconds(201), EF_NONE, 0,
PointerDetails(EventPointerType::POINTER_TYPE_MOUSE,
MouseEvent::kMousePointerId));
mojom::TraitsTestServicePtr proxy = GetTraitsTestProxy();
input_event.set_location_f(gfx::PointF(10.1, 10.2));
input_event.set_root_location_f(gfx::PointF(20.2, 30.3));
std::unique_ptr<Event> output;
proxy->EchoEvent(Event::Clone(input_event), &output);
ASSERT_TRUE(output->IsMouseEvent());
const MouseEvent* output_event = output->AsMouseEvent();
EXPECT_EQ(input_event.type(), output_event->type());
EXPECT_EQ(input_event.flags(), output_event->flags());
EXPECT_EQ(input_event.location(), output_event->location());
EXPECT_EQ(input_event.root_location(), output_event->root_location());
EXPECT_EQ(input_event.location_f(), output_event->location_f());
EXPECT_EQ(input_event.root_location_f(), output_event->root_location_f());
}
TEST_F(StructTraitsTest, KeyEventPropertiesSerialized) {
KeyEvent key_event(ET_KEY_PRESSED, VKEY_T, EF_NONE);
const std::string key = "key";
......
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