| // Copyright 2020 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/public/common/input/web_input_event.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "third_party/blink/public/common/input/web_gesture_event.h" |
| #include "third_party/blink/public/common/input/web_mouse_wheel_event.h" |
| #include "third_party/blink/public/common/input/web_pointer_event.h" |
| |
| namespace blink { |
| |
| namespace { |
| |
| WebMouseEvent CreateWebMouseMoveEvent() { |
| WebMouseEvent mouse_event; |
| mouse_event.SetType(WebInputEvent::Type::kMouseMove); |
| mouse_event.id = 1; |
| mouse_event.pointer_type = WebPointerProperties::PointerType::kMouse; |
| return mouse_event; |
| } |
| |
| WebPointerEvent CreateWebPointerMoveEvent() { |
| WebPointerEvent pointer_event; |
| pointer_event.SetType(WebInputEvent::Type::kPointerMove); |
| pointer_event.id = 1; |
| pointer_event.pointer_type = WebPointerProperties::PointerType::kMouse; |
| return pointer_event; |
| } |
| |
| WebTouchEvent CreateWebTouchMoveEvent() { |
| WebTouchPoint touch_point; |
| touch_point.id = 1; |
| touch_point.state = WebTouchPoint::State::kStateMoved; |
| touch_point.pointer_type = WebPointerProperties::PointerType::kTouch; |
| |
| WebTouchEvent touch_event; |
| touch_event.SetType(WebInputEvent::Type::kTouchMove); |
| touch_event.touches[touch_event.touches_length++] = touch_point; |
| return touch_event; |
| } |
| |
| } // namespace |
| |
| TEST(WebInputEventTest, TouchEventCoalescing) { |
| WebTouchEvent coalesced_event = CreateWebTouchMoveEvent(); |
| coalesced_event.SetType(WebInputEvent::Type::kTouchMove); |
| coalesced_event.touches[0].movement_x = 5; |
| coalesced_event.touches[0].movement_y = 10; |
| |
| WebTouchEvent event_to_be_coalesced = CreateWebTouchMoveEvent(); |
| event_to_be_coalesced.touches[0].movement_x = 3; |
| event_to_be_coalesced.touches[0].movement_y = -4; |
| |
| EXPECT_TRUE(coalesced_event.CanCoalesce(event_to_be_coalesced)); |
| coalesced_event.Coalesce(event_to_be_coalesced); |
| EXPECT_EQ(8, coalesced_event.touches[0].movement_x); |
| EXPECT_EQ(6, coalesced_event.touches[0].movement_y); |
| |
| coalesced_event.touches[0].pointer_type = |
| WebPointerProperties::PointerType::kPen; |
| EXPECT_FALSE(coalesced_event.CanCoalesce(event_to_be_coalesced)); |
| |
| coalesced_event = CreateWebTouchMoveEvent(); |
| event_to_be_coalesced = CreateWebTouchMoveEvent(); |
| event_to_be_coalesced.SetModifiers(WebInputEvent::kControlKey); |
| EXPECT_FALSE(coalesced_event.CanCoalesce(event_to_be_coalesced)); |
| } |
| |
| TEST(WebInputEventTest, WebMouseWheelEventCoalescing) { |
| WebMouseWheelEvent coalesced_event( |
| WebInputEvent::Type::kMouseWheel, WebInputEvent::kNoModifiers, |
| WebInputEvent::GetStaticTimeStampForTests()); |
| coalesced_event.delta_x = 1; |
| coalesced_event.delta_y = 1; |
| |
| WebMouseWheelEvent event_to_be_coalesced( |
| WebInputEvent::Type::kMouseWheel, WebInputEvent::kNoModifiers, |
| WebInputEvent::GetStaticTimeStampForTests()); |
| event_to_be_coalesced.delta_x = 3; |
| event_to_be_coalesced.delta_y = 4; |
| |
| EXPECT_TRUE(coalesced_event.CanCoalesce(event_to_be_coalesced)); |
| coalesced_event.Coalesce(event_to_be_coalesced); |
| EXPECT_EQ(4, coalesced_event.delta_x); |
| EXPECT_EQ(5, coalesced_event.delta_y); |
| |
| event_to_be_coalesced.phase = WebMouseWheelEvent::kPhaseBegan; |
| coalesced_event.phase = WebMouseWheelEvent::kPhaseEnded; |
| EXPECT_FALSE(coalesced_event.CanCoalesce(event_to_be_coalesced)); |
| |
| // With timer based wheel scroll latching, we break the latching sequence on |
| // direction change when all prior GSU events in the current sequence are |
| // ignored. To do so we dispatch the pending wheel event with phaseEnded and |
| // the first wheel event in the opposite direction will have phaseBegan. The |
| // GSB generated from this wheel event will cause a new hittesting. To make |
| // sure that a GSB will actually get created we should not coalesce the wheel |
| // event with synthetic kPhaseBegan to one with synthetic kPhaseEnded. |
| event_to_be_coalesced.has_synthetic_phase = true; |
| coalesced_event.has_synthetic_phase = true; |
| EXPECT_FALSE(coalesced_event.CanCoalesce(event_to_be_coalesced)); |
| |
| event_to_be_coalesced.phase = WebMouseWheelEvent::kPhaseChanged; |
| coalesced_event.phase = WebMouseWheelEvent::kPhaseBegan; |
| EXPECT_TRUE(coalesced_event.CanCoalesce(event_to_be_coalesced)); |
| coalesced_event.Coalesce(event_to_be_coalesced); |
| EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, coalesced_event.phase); |
| EXPECT_EQ(7, coalesced_event.delta_x); |
| EXPECT_EQ(9, coalesced_event.delta_y); |
| } |
| |
| TEST(WebInputEventTest, WebGestureEventCoalescing) { |
| WebGestureEvent coalesced_event(WebInputEvent::Type::kGestureScrollUpdate, |
| WebInputEvent::kNoModifiers, |
| WebInputEvent::GetStaticTimeStampForTests()); |
| coalesced_event.data.scroll_update.delta_x = 1; |
| coalesced_event.data.scroll_update.delta_y = 1; |
| |
| WebGestureEvent event_to_be_coalesced( |
| WebInputEvent::Type::kGestureScrollUpdate, WebInputEvent::kNoModifiers, |
| WebInputEvent::GetStaticTimeStampForTests()); |
| event_to_be_coalesced.data.scroll_update.delta_x = 3; |
| event_to_be_coalesced.data.scroll_update.delta_y = 4; |
| |
| EXPECT_TRUE(coalesced_event.CanCoalesce(event_to_be_coalesced)); |
| coalesced_event.Coalesce(event_to_be_coalesced); |
| EXPECT_EQ(4, coalesced_event.data.scroll_update.delta_x); |
| EXPECT_EQ(5, coalesced_event.data.scroll_update.delta_y); |
| } |
| |
| TEST(WebInputEventTest, GesturePinchUpdateCoalescing) { |
| gfx::PointF position(10.f, 10.f); |
| WebGestureEvent coalesced_event( |
| WebInputEvent::Type::kGesturePinchUpdate, WebInputEvent::kNoModifiers, |
| WebInputEvent::GetStaticTimeStampForTests(), WebGestureDevice::kTouchpad); |
| coalesced_event.data.pinch_update.scale = 1.1f; |
| coalesced_event.SetPositionInWidget(position); |
| |
| WebGestureEvent event_to_be_coalesced(coalesced_event); |
| |
| ASSERT_TRUE(coalesced_event.CanCoalesce(event_to_be_coalesced)); |
| coalesced_event.Coalesce(event_to_be_coalesced); |
| EXPECT_FLOAT_EQ(1.21, coalesced_event.data.pinch_update.scale); |
| |
| // Allow the updates to be coalesced if the anchors are nearly equal. |
| position.Offset(0.1f, 0.1f); |
| event_to_be_coalesced.SetPositionInWidget(position); |
| coalesced_event.data.pinch_update.scale = 1.1f; |
| ASSERT_TRUE(coalesced_event.CanCoalesce(event_to_be_coalesced)); |
| coalesced_event.Coalesce(event_to_be_coalesced); |
| EXPECT_FLOAT_EQ(1.21, coalesced_event.data.pinch_update.scale); |
| |
| // The anchors are no longer considered equal, so don't coalesce. |
| position.Offset(1.f, 1.f); |
| event_to_be_coalesced.SetPositionInWidget(position); |
| EXPECT_FALSE(coalesced_event.CanCoalesce(event_to_be_coalesced)); |
| |
| // Don't logically coalesce touchpad pinch events as touchpad pinch events |
| // don't occur within a gesture scroll sequence. |
| EXPECT_FALSE(WebGestureEvent::IsCompatibleScrollorPinch(event_to_be_coalesced, |
| coalesced_event)); |
| |
| // Touchscreen pinch events can be logically coalesced. |
| coalesced_event.SetSourceDevice(WebGestureDevice::kTouchscreen); |
| event_to_be_coalesced.SetSourceDevice(WebGestureDevice::kTouchscreen); |
| coalesced_event.data.pinch_update.scale = 1.1f; |
| ASSERT_TRUE(WebGestureEvent::IsCompatibleScrollorPinch(event_to_be_coalesced, |
| coalesced_event)); |
| |
| std::unique_ptr<WebGestureEvent> logical_scroll, logical_pinch; |
| std::tie(logical_scroll, logical_pinch) = |
| WebGestureEvent::CoalesceScrollAndPinch(nullptr, coalesced_event, |
| event_to_be_coalesced); |
| ASSERT_NE(nullptr, logical_scroll); |
| ASSERT_NE(nullptr, logical_pinch); |
| ASSERT_EQ(WebInputEvent::Type::kGestureScrollUpdate, |
| logical_scroll->GetType()); |
| ASSERT_EQ(WebInputEvent::Type::kGesturePinchUpdate, logical_pinch->GetType()); |
| EXPECT_FLOAT_EQ(1.21, logical_pinch->data.pinch_update.scale); |
| } |
| |
| TEST(WebInputEventTest, MouseEventCoalescing) { |
| WebMouseEvent coalesced_event = CreateWebMouseMoveEvent(); |
| WebMouseEvent event_to_be_coalesced = CreateWebMouseMoveEvent(); |
| EXPECT_TRUE(coalesced_event.CanCoalesce(event_to_be_coalesced)); |
| |
| // Test coalescing movements. |
| coalesced_event.movement_x = 5; |
| coalesced_event.movement_y = 10; |
| |
| event_to_be_coalesced.movement_x = 3; |
| event_to_be_coalesced.movement_y = -4; |
| EXPECT_TRUE(coalesced_event.CanCoalesce(event_to_be_coalesced)); |
| coalesced_event.Coalesce(event_to_be_coalesced); |
| EXPECT_EQ(8, coalesced_event.movement_x); |
| EXPECT_EQ(6, coalesced_event.movement_y); |
| |
| // Test id. |
| coalesced_event = CreateWebMouseMoveEvent(); |
| event_to_be_coalesced = CreateWebMouseMoveEvent(); |
| event_to_be_coalesced.id = 3; |
| EXPECT_FALSE(coalesced_event.CanCoalesce(event_to_be_coalesced)); |
| |
| // Test pointer_type. |
| coalesced_event = CreateWebMouseMoveEvent(); |
| event_to_be_coalesced = CreateWebMouseMoveEvent(); |
| event_to_be_coalesced.pointer_type = WebPointerProperties::PointerType::kPen; |
| EXPECT_FALSE(coalesced_event.CanCoalesce(event_to_be_coalesced)); |
| |
| // Test modifiers |
| coalesced_event = CreateWebMouseMoveEvent(); |
| event_to_be_coalesced = CreateWebMouseMoveEvent(); |
| event_to_be_coalesced.SetModifiers(WebInputEvent::kControlKey); |
| EXPECT_FALSE(coalesced_event.CanCoalesce(event_to_be_coalesced)); |
| } |
| |
| TEST(WebInputEventTest, PointerEventCoalescing) { |
| WebPointerEvent coalesced_event = CreateWebPointerMoveEvent(); |
| WebPointerEvent event_to_be_coalesced = CreateWebPointerMoveEvent(); |
| EXPECT_TRUE(coalesced_event.CanCoalesce(event_to_be_coalesced)); |
| |
| // Test coalescing movements. |
| coalesced_event.movement_x = 5; |
| coalesced_event.movement_y = 10; |
| |
| event_to_be_coalesced.movement_x = 3; |
| event_to_be_coalesced.movement_y = -4; |
| EXPECT_TRUE(coalesced_event.CanCoalesce(event_to_be_coalesced)); |
| coalesced_event.Coalesce(event_to_be_coalesced); |
| EXPECT_EQ(8, coalesced_event.movement_x); |
| EXPECT_EQ(6, coalesced_event.movement_y); |
| |
| // Test id. |
| coalesced_event = CreateWebPointerMoveEvent(); |
| event_to_be_coalesced = CreateWebPointerMoveEvent(); |
| event_to_be_coalesced.id = 3; |
| EXPECT_FALSE(coalesced_event.CanCoalesce(event_to_be_coalesced)); |
| |
| // Test pointer_type. |
| coalesced_event = CreateWebPointerMoveEvent(); |
| event_to_be_coalesced = CreateWebPointerMoveEvent(); |
| event_to_be_coalesced.pointer_type = WebPointerProperties::PointerType::kPen; |
| EXPECT_FALSE(coalesced_event.CanCoalesce(event_to_be_coalesced)); |
| |
| // Test modifiers |
| coalesced_event = CreateWebPointerMoveEvent(); |
| event_to_be_coalesced = CreateWebPointerMoveEvent(); |
| event_to_be_coalesced.SetModifiers(WebInputEvent::kControlKey); |
| EXPECT_FALSE(coalesced_event.CanCoalesce(event_to_be_coalesced)); |
| } |
| |
| } // namespace blink |