blob: fafa81c72778267f4988ec1b2f7858989bd89d3c [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/input/pointer_event_manager.h"
#include <limits>
#include <memory>
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
namespace blink {
namespace {
class CheckPointerEventListenerCallback final : public NativeEventListener {
public:
void Invoke(ExecutionContext*, Event* event) override {
num_events_received_++;
const String pointer_type =
static_cast<PointerEvent*>(event)->pointerType();
if (pointer_type == "mouse")
num_type_mouse_received_++;
else if (pointer_type == "touch")
num_type_touch_received_++;
else if (pointer_type == "pen")
num_type_pen_received_++;
}
int numEventsReceived() const { return num_events_received_; }
int numTypeMouseReceived() const { return num_type_mouse_received_; }
int numTypeTouchReceived() const { return num_type_touch_received_; }
int numTypePenReceived() const { return num_type_pen_received_; }
private:
int num_events_received_ = 0;
int num_type_mouse_received_ = 0;
int num_type_touch_received_ = 0;
int num_type_pen_received_ = 0;
};
class PointerEventCoordinateListenerCallback final
: public NativeEventListener {
public:
static PointerEventCoordinateListenerCallback* Create() {
return MakeGarbageCollected<PointerEventCoordinateListenerCallback>();
}
void Invoke(ExecutionContext*, Event* event) override {
const PointerEvent* pointer_event = static_cast<PointerEvent*>(event);
last_client_x_ = pointer_event->clientX();
last_client_y_ = pointer_event->clientY();
last_page_x_ = pointer_event->pageX();
last_page_y_ = pointer_event->pageY();
last_screen_x_ = pointer_event->screenX();
last_screen_y_ = pointer_event->screenY();
last_width_ = pointer_event->width();
last_height_ = pointer_event->height();
last_movement_x_ = pointer_event->movementX();
last_movement_y_ = pointer_event->movementY();
}
double last_client_x_ = 0;
double last_client_y_ = 0;
double last_page_x_ = 0;
double last_page_y_ = 0;
double last_screen_x_ = 0;
double last_screen_y_ = 0;
double last_width_ = 0;
double last_height_ = 0;
double last_movement_x_ = 0;
double last_movement_y_ = 0;
};
} // namespace
class PointerEventManagerTest : public SimTest {
protected:
EventHandler& GetEventHandler() {
return GetDocument().GetFrame()->GetEventHandler();
}
std::unique_ptr<WebPointerEvent> CreateTestPointerEvent(
WebInputEvent::Type type,
WebPointerProperties::PointerType pointer_type,
PointerId id = 1) {
return CreateTestPointerEvent(type, pointer_type, id, gfx::PointF(100, 100),
gfx::PointF(100, 100), 0, 0, 1, 1);
}
std::unique_ptr<WebPointerEvent> CreateTestPointerEvent(
WebInputEvent::Type type,
WebPointerProperties::PointerType pointer_type,
gfx::PointF position_in_widget,
gfx::PointF position_in_screen,
int movement_x,
int movement_y,
float width = 1,
float height = 1) {
return CreateTestPointerEvent(type, pointer_type, 1, position_in_widget,
position_in_screen, movement_x, movement_y,
width, height);
}
WebMouseEvent CreateTestMouseEvent(WebInputEvent::Type type,
const gfx::PointF& coordinates) {
WebMouseEvent event(type, coordinates, coordinates,
WebPointerProperties::Button::kLeft, 0,
WebInputEvent::kLeftButtonDown,
WebInputEvent::GetStaticTimeStampForTests());
event.SetFrameScale(1);
return event;
}
private:
std::unique_ptr<WebPointerEvent> CreateTestPointerEvent(
WebInputEvent::Type type,
WebPointerProperties::PointerType pointer_type,
PointerId id,
gfx::PointF position_in_widget,
gfx::PointF position_in_screen,
int movement_x,
int movement_y,
float width,
float height) {
return std::make_unique<WebPointerEvent>(
type,
WebPointerProperties(
id, pointer_type, WebPointerProperties::Button::kLeft,
position_in_widget, position_in_screen, movement_x, movement_y),
width, height);
}
};
TEST_F(PointerEventManagerTest, HasPointerCapture) {
WebView().MainFrameViewWidget()->Resize(gfx::Size(400, 400));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
request.Complete(
"<body style='padding: 0px; width: 400px; height: 400px;'>"
"</body>");
ASSERT_FALSE(GetDocument().body()->hasPointerCapture(4));
ASSERT_FALSE(GetDocument().body()->hasPointerCapture(
std::numeric_limits<PointerId>::max()));
ASSERT_FALSE(GetDocument().body()->hasPointerCapture(0));
ASSERT_FALSE(GetDocument().body()->hasPointerCapture(-1));
ASSERT_FALSE(
GetDocument().body()->hasPointerCapture(PointerEventFactory::kMouseId));
ExceptionState exception(nullptr, ExceptionState::kExecutionContext, "", "");
GetEventHandler().HandleMousePressEvent(CreateTestMouseEvent(
WebInputEvent::Type::kMouseDown, gfx::PointF(100, 100)));
ASSERT_FALSE(
GetDocument().body()->hasPointerCapture(PointerEventFactory::kMouseId));
GetDocument().body()->setPointerCapture(PointerEventFactory::kMouseId,
exception);
ASSERT_TRUE(
GetDocument().body()->hasPointerCapture(PointerEventFactory::kMouseId));
GetEventHandler().HandleMouseMoveEvent(
CreateTestMouseEvent(WebInputEvent::Type::kMouseMove,
gfx::PointF(200, 200)),
Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
ASSERT_TRUE(
GetDocument().body()->hasPointerCapture(PointerEventFactory::kMouseId));
GetDocument().body()->releasePointerCapture(PointerEventFactory::kMouseId,
exception);
ASSERT_FALSE(
GetDocument().body()->hasPointerCapture(PointerEventFactory::kMouseId));
}
TEST_F(PointerEventManagerTest, PointerCancelsOfAllTypes) {
WebView().MainFrameViewWidget()->Resize(gfx::Size(400, 400));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
request.Complete(
"<body style='padding: 0px; width: 400px; height: 400px;'>"
"<div draggable='true' style='width: 150px; height: 150px;'></div>"
"</body>");
auto* callback = MakeGarbageCollected<CheckPointerEventListenerCallback>();
GetDocument().body()->addEventListener(event_type_names::kPointercancel,
callback);
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::Type::kPointerDown,
WebPointerProperties::PointerType::kTouch),
{}, {}, ui::LatencyInfo()));
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::Type::kPointerDown,
WebPointerProperties::PointerType::kPen),
{}, {}, ui::LatencyInfo()));
GetEventHandler().HandleMousePressEvent(CreateTestMouseEvent(
WebInputEvent::Type::kMouseDown, gfx::PointF(100, 100)));
ASSERT_EQ(callback->numTypeMouseReceived(), 0);
ASSERT_EQ(callback->numTypeTouchReceived(), 0);
ASSERT_EQ(callback->numTypePenReceived(), 0);
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::Type::kPointerCausedUaAction,
WebPointerProperties::PointerType::kPen),
{}, {}, ui::LatencyInfo()));
ASSERT_EQ(callback->numTypeMouseReceived(), 0);
ASSERT_EQ(callback->numTypeTouchReceived(), 1);
ASSERT_EQ(callback->numTypePenReceived(), 1);
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::Type::kPointerCausedUaAction,
WebPointerProperties::PointerType::kTouch),
{}, {}, ui::LatencyInfo()));
ASSERT_EQ(callback->numTypeMouseReceived(), 0);
ASSERT_EQ(callback->numTypeTouchReceived(), 1);
ASSERT_EQ(callback->numTypePenReceived(), 1);
GetEventHandler().HandleMouseMoveEvent(
CreateTestMouseEvent(WebInputEvent::Type::kMouseMove,
gfx::PointF(200, 200)),
Vector<WebMouseEvent>(), Vector<WebMouseEvent>());
ASSERT_EQ(callback->numTypeMouseReceived(), 1);
ASSERT_EQ(callback->numTypeTouchReceived(), 1);
ASSERT_EQ(callback->numTypePenReceived(), 1);
}
TEST_F(PointerEventManagerTest, PointerCancelForNonExistentid) {
WebView().MainFrameViewWidget()->Resize(gfx::Size(400, 400));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
request.Complete(
"<body style='padding: 0px; width: 400px; height: 400px;'>"
"<div draggable='true' style='width: 150px; height: 150px;'></div>"
"</body>");
auto* callback = MakeGarbageCollected<CheckPointerEventListenerCallback>();
GetDocument().body()->addEventListener(event_type_names::kPointercancel,
callback);
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::Type::kPointerCancel,
WebPointerProperties::PointerType::kTouch, 100),
{}, {}, ui::LatencyInfo()));
ASSERT_EQ(callback->numEventsReceived(), 0);
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::Type::kPointerDown,
WebPointerProperties::PointerType::kTouch, 100),
{}, {}, ui::LatencyInfo()));
ASSERT_EQ(callback->numEventsReceived(), 0);
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::Type::kPointerCancel,
WebPointerProperties::PointerType::kTouch, 100),
{}, {}, ui::LatencyInfo()));
ASSERT_EQ(callback->numEventsReceived(), 1);
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::Type::kPointerCancel,
WebPointerProperties::PointerType::kTouch, 200),
{}, {}, ui::LatencyInfo()));
ASSERT_EQ(callback->numEventsReceived(), 1);
}
TEST_F(PointerEventManagerTest, PointerEventCoordinates) {
WebView().MainFrameViewWidget()->Resize(gfx::Size(400, 400));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
request.Complete(
"<body style='padding: 0px; width: 400px; height: 400px;'>"
"</body>");
WebView().SetPageScaleFactor(2);
PointerEventCoordinateListenerCallback* callback =
PointerEventCoordinateListenerCallback::Create();
GetDocument().body()->addEventListener(event_type_names::kPointerdown,
callback);
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::Type::kPointerDown,
WebPointerProperties::PointerType::kTouch,
gfx::PointF(150, 200), gfx::PointF(100, 50), 10,
10, 16, 24),
{}, {}, ui::LatencyInfo()));
ASSERT_EQ(callback->last_client_x_, 75);
ASSERT_EQ(callback->last_client_y_, 100);
ASSERT_EQ(callback->last_page_x_, 75);
ASSERT_EQ(callback->last_page_y_, 100);
ASSERT_EQ(callback->last_screen_x_, 100);
ASSERT_EQ(callback->last_screen_y_, 50);
ASSERT_EQ(callback->last_width_, 8);
ASSERT_EQ(callback->last_height_, 12);
ASSERT_EQ(callback->last_movement_x_, 10);
ASSERT_EQ(callback->last_movement_y_, 10);
}
TEST_F(PointerEventManagerTest, PointerEventMovements) {
WebView().MainFrameViewWidget()->Resize(gfx::Size(400, 400));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
request.Complete(
"<body style='padding: 0px; width: 400px; height: 400px;'>"
"</body>");
PointerEventCoordinateListenerCallback* callback =
PointerEventCoordinateListenerCallback::Create();
GetDocument().body()->addEventListener(event_type_names::kPointermove,
callback);
{
// Turn on the flag for test.
ScopedConsolidatedMovementXYForTest scoped_feature(true);
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::Type::kPointerMove,
WebPointerProperties::PointerType::kMouse,
gfx::PointF(150, 210), gfx::PointF(100, 50), 10,
10),
{}, {}, ui::LatencyInfo()));
// The first pointermove event has movement_x/y 0.
ASSERT_EQ(callback->last_screen_x_, 100);
ASSERT_EQ(callback->last_screen_y_, 50);
ASSERT_EQ(callback->last_movement_x_, 0);
ASSERT_EQ(callback->last_movement_y_, 0);
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::Type::kPointerMove,
WebPointerProperties::PointerType::kMouse,
gfx::PointF(150, 200), gfx::PointF(132, 29), 10,
10),
{}, {}, ui::LatencyInfo()));
// pointermove event movement = event.screenX/Y - last_event.screenX/Y.
ASSERT_EQ(callback->last_screen_x_, 132);
ASSERT_EQ(callback->last_screen_y_, 29);
ASSERT_EQ(callback->last_movement_x_, 32);
ASSERT_EQ(callback->last_movement_y_, -21);
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::Type::kPointerMove,
WebPointerProperties::PointerType::kMouse,
gfx::PointF(150, 210), gfx::PointF(113.8, 32.7),
10, 10),
{}, {}, ui::LatencyInfo()));
// fractional screen coordinates result in fractional movement.
ASSERT_FLOAT_EQ(callback->last_screen_x_, 113.8);
ASSERT_FLOAT_EQ(callback->last_screen_y_, 32.7);
// TODO(eirage): These should be float value once mouse_event.idl change.
ASSERT_FLOAT_EQ(callback->last_movement_x_, -19);
ASSERT_FLOAT_EQ(callback->last_movement_y_, 3);
}
{
// When flag is off, movementX/Y follows the value in WebPointerProperties.
ScopedConsolidatedMovementXYForTest scoped_feature(false);
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::Type::kPointerMove,
WebPointerProperties::PointerType::kMouse,
gfx::PointF(150, 210), gfx::PointF(100, 16.25),
1024, -8765),
{}, {}, ui::LatencyInfo()));
ASSERT_EQ(callback->last_screen_x_, 100);
ASSERT_EQ(callback->last_screen_y_, 16.25);
ASSERT_EQ(callback->last_movement_x_, 1024);
ASSERT_EQ(callback->last_movement_y_, -8765);
}
}
// Test that we are not losing fractions when truncating movements.
TEST_F(PointerEventManagerTest, PointerEventSmallFractionMovements) {
WebView().MainFrameViewWidget()->Resize(gfx::Size(400, 400));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
request.Complete(
"<body style='padding: 0px; width: 400px; height: 400px;'>"
"</body>");
PointerEventCoordinateListenerCallback* callback =
PointerEventCoordinateListenerCallback::Create();
GetDocument().body()->addEventListener(event_type_names::kPointermove,
callback);
// Turn on the flag for test.
ScopedConsolidatedMovementXYForTest scoped_feature(true);
std::unique_ptr<WebPointerEvent> pointer_event = CreateTestPointerEvent(
WebInputEvent::Type::kPointerMove,
WebPointerProperties::PointerType::kMouse, gfx::PointF(150, 210),
gfx::PointF(113.8, 32.7), 0, 0);
ASSERT_NE(nullptr, pointer_event);
WebView().MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(pointer_event->Clone(), ui::LatencyInfo()));
ASSERT_FLOAT_EQ(callback->last_movement_x_, 0);
ASSERT_FLOAT_EQ(callback->last_movement_y_, 0);
pointer_event->SetPositionInScreen(113.4, 32.9);
WebView().MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(pointer_event->Clone(), ui::LatencyInfo()));
ASSERT_FLOAT_EQ(callback->last_movement_x_, 0);
ASSERT_FLOAT_EQ(callback->last_movement_y_, 0);
pointer_event->SetPositionInScreen(113.0, 33.1);
WebView().MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(pointer_event->Clone(), ui::LatencyInfo()));
ASSERT_FLOAT_EQ(callback->last_movement_x_, 0);
ASSERT_FLOAT_EQ(callback->last_movement_y_, 1);
pointer_event->SetPositionInScreen(112.6, 33.3);
WebView().MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(std::move(pointer_event), ui::LatencyInfo()));
ASSERT_FLOAT_EQ(callback->last_movement_x_, -1);
ASSERT_FLOAT_EQ(callback->last_movement_y_, 0);
}
TEST_F(PointerEventManagerTest, PointerRawUpdateMovements) {
WebView().MainFrameViewWidget()->Resize(gfx::Size(400, 400));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
request.Complete(
"<body style='padding: 0px; width: 400px; height: 400px;'>"
"</body>");
PointerEventCoordinateListenerCallback* callback =
PointerEventCoordinateListenerCallback::Create();
GetDocument().body()->addEventListener(event_type_names::kPointermove,
callback);
GetDocument().body()->addEventListener(event_type_names::kPointerrawupdate,
callback);
// Turn on the flag for test.
ScopedConsolidatedMovementXYForTest scoped_feature(true);
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::Type::kPointerRawUpdate,
WebPointerProperties::PointerType::kMouse,
gfx::PointF(150, 210), gfx::PointF(100, 50), 10,
10),
{}, {}, ui::LatencyInfo()));
// The first pointerrawupdate event has movement_x/y 0.
ASSERT_EQ(callback->last_screen_x_, 100);
ASSERT_EQ(callback->last_screen_y_, 50);
ASSERT_EQ(callback->last_movement_x_, 0);
ASSERT_EQ(callback->last_movement_y_, 0);
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::Type::kPointerRawUpdate,
WebPointerProperties::PointerType::kMouse,
gfx::PointF(150, 200), gfx::PointF(132, 29), 10,
10),
{}, {}, ui::LatencyInfo()));
// pointerrawupdate event movement = event.screenX/Y - last_event.screenX/Y.
ASSERT_EQ(callback->last_screen_x_, 132);
ASSERT_EQ(callback->last_screen_y_, 29);
ASSERT_EQ(callback->last_movement_x_, 32);
ASSERT_EQ(callback->last_movement_y_, -21);
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::Type::kPointerMove,
WebPointerProperties::PointerType::kMouse,
gfx::PointF(150, 200), gfx::PointF(144, 30), 10,
10),
{}, {}, ui::LatencyInfo()));
// First pointermove, have 0 movements.
ASSERT_EQ(callback->last_screen_x_, 144);
ASSERT_EQ(callback->last_screen_y_, 30);
ASSERT_EQ(callback->last_movement_x_, 0);
ASSERT_EQ(callback->last_movement_y_, 0);
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::Type::kPointerRawUpdate,
WebPointerProperties::PointerType::kMouse,
gfx::PointF(150, 200), gfx::PointF(142, 32), 10,
10),
{}, {}, ui::LatencyInfo()));
// pointerrawupdate event's movement is independent from pointermoves.
ASSERT_EQ(callback->last_screen_x_, 142);
ASSERT_EQ(callback->last_screen_y_, 32);
ASSERT_EQ(callback->last_movement_x_, 10);
ASSERT_EQ(callback->last_movement_y_, 3);
}
TEST_F(PointerEventManagerTest, PointerRawUpdateWithRelativeMotionEvent) {
ScopedConsolidatedMovementXYForTest scoped_feature(true);
WebView().MainFrameViewWidget()->Resize(gfx::Size(400, 400));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
request.Complete(
"<body style='padding:0px; width:400px; height:400px;'></body>");
PointerEventCoordinateListenerCallback* callback =
PointerEventCoordinateListenerCallback::Create();
GetDocument().body()->addEventListener(event_type_names::kPointerrawupdate,
callback);
// Initial movement_x/y are both 0.
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::Type::kPointerRawUpdate,
WebPointerProperties::PointerType::kMouse,
gfx::PointF(350, 350), gfx::PointF(350, 350), 10,
10),
{}, {}, ui::LatencyInfo()));
ASSERT_EQ(callback->last_movement_x_, 0);
ASSERT_EQ(callback->last_movement_y_, 0);
// After moving the mouse by (+40,+20), movement_x/y have same deltas.
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::Type::kPointerRawUpdate,
WebPointerProperties::PointerType::kMouse,
gfx::PointF(390, 370), gfx::PointF(390, 370), 10,
10),
{}, {}, ui::LatencyInfo()));
ASSERT_EQ(callback->last_movement_x_, 40);
ASSERT_EQ(callback->last_movement_y_, 20);
// A relative motion event to pull the mouse pointer back towards the center
// is not exposed to JS, so the event handler is not called and the cached
// coordinates remain unchanged.
std::unique_ptr<WebInputEvent> synthetic_event = CreateTestPointerEvent(
WebInputEvent::Type::kPointerRawUpdate,
WebPointerProperties::PointerType::kMouse, gfx::PointF(200, 200),
gfx::PointF(200, 200), 10, 10);
synthetic_event->SetModifiers(WebInputEvent::Modifiers::kRelativeMotionEvent);
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
std::move(synthetic_event), {}, {}, ui::LatencyInfo()));
ASSERT_EQ(callback->last_movement_x_, 40);
ASSERT_EQ(callback->last_movement_y_, 20);
// After moving the mouse by (+15,-10) from the last unexposed event,
// movement_x/y have deltas from the last event, not the deltas from the last
// exposed event.
WebView().MainFrameWidget()->HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::Type::kPointerRawUpdate,
WebPointerProperties::PointerType::kMouse,
gfx::PointF(215, 190), gfx::PointF(215, 190), 10,
10),
{}, {}, ui::LatencyInfo()));
ASSERT_EQ(callback->last_movement_x_, 15);
ASSERT_EQ(callback->last_movement_y_, -10);
}
TEST_F(PointerEventManagerTest, PointerUnadjustedMovement) {
WebView().MainFrameViewWidget()->Resize(gfx::Size(400, 400));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
request.Complete(
"<body style='padding: 0px; width: 400px; height: 400px;'>"
"</body>");
PointerEventCoordinateListenerCallback* callback =
PointerEventCoordinateListenerCallback::Create();
GetDocument().body()->addEventListener(event_type_names::kPointermove,
callback);
std::unique_ptr<WebPointerEvent> event = CreateTestPointerEvent(
WebInputEvent::Type::kPointerMove,
WebPointerProperties::PointerType::kMouse, gfx::PointF(150, 210),
gfx::PointF(100, 50), 120, -321);
ASSERT_NE(nullptr, event);
event->is_raw_movement_event = true;
WebView().MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(std::move(event), {}, {}, ui::LatencyInfo()));
// If is_raw_movement_event is true, PE use the raw movement value from
// movement_x/y.
ASSERT_EQ(callback->last_screen_x_, 100);
ASSERT_EQ(callback->last_screen_y_, 50);
ASSERT_EQ(callback->last_movement_x_, 120);
ASSERT_EQ(callback->last_movement_y_, -321);
}
} // namespace blink