blob: 4542e379eb11bda6dcd5a79a07375aabb24d264e [file] [log] [blame]
// 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));
WebGestureEvent logical_scroll, logical_pinch;
std::tie(logical_scroll, logical_pinch) =
WebGestureEvent::CoalesceScrollAndPinch(nullptr, coalesced_event,
event_to_be_coalesced);
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