blob: a7f5411a38d3dcc3d4bcb6e3814b834046b08129 [file] [log] [blame]
// Copyright 2016 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_mouse_wheel_event.h"
namespace blink {
namespace {
float GetUnacceleratedDelta(float accelerated_delta, float acceleration_ratio) {
return accelerated_delta * acceleration_ratio;
}
float GetAccelerationRatio(float accelerated_delta, float unaccelerated_delta) {
if (unaccelerated_delta == 0.f || accelerated_delta == 0.f)
return 1.f;
return unaccelerated_delta / accelerated_delta;
}
} // namespace
std::unique_ptr<WebInputEvent> WebMouseWheelEvent::Clone() const {
return std::make_unique<WebMouseWheelEvent>(*this);
}
bool WebMouseWheelEvent::CanCoalesce(const WebInputEvent& event) const {
if (event.GetType() != WebInputEvent::Type::kMouseWheel)
return false;
const WebMouseWheelEvent& mouse_wheel_event =
static_cast<const WebMouseWheelEvent&>(event);
return GetModifiers() == mouse_wheel_event.GetModifiers() &&
delta_units == mouse_wheel_event.delta_units &&
HaveConsistentPhase(mouse_wheel_event);
}
bool WebMouseWheelEvent::HaveConsistentPhase(
const WebMouseWheelEvent& event) const {
if (has_synthetic_phase != event.has_synthetic_phase)
return false;
if (phase == event.phase && momentum_phase == event.momentum_phase) {
return true;
}
if (has_synthetic_phase) {
// It is alright to coalesce a wheel event with synthetic phaseChanged to
// its previous one with synthetic phaseBegan.
return (phase == WebMouseWheelEvent::kPhaseBegan &&
event.phase == WebMouseWheelEvent::kPhaseChanged);
}
return false;
}
void WebMouseWheelEvent::Coalesce(const WebInputEvent& event) {
DCHECK(CanCoalesce(event));
const WebMouseWheelEvent& mouse_wheel_event =
static_cast<const WebMouseWheelEvent&>(event);
float unaccelerated_x =
GetUnacceleratedDelta(delta_x, acceleration_ratio_x) +
GetUnacceleratedDelta(mouse_wheel_event.delta_x,
mouse_wheel_event.acceleration_ratio_x);
float unaccelerated_y =
GetUnacceleratedDelta(delta_y, acceleration_ratio_y) +
GetUnacceleratedDelta(mouse_wheel_event.delta_y,
mouse_wheel_event.acceleration_ratio_y);
float old_deltaX = delta_x;
float old_deltaY = delta_y;
float old_wheelTicksX = wheel_ticks_x;
float old_wheelTicksY = wheel_ticks_y;
float old_movementX = movement_x;
float old_movementY = movement_y;
WebMouseWheelEvent::Phase old_phase = phase;
WebInputEvent::DispatchType old_dispatch_type = dispatch_type;
*this = mouse_wheel_event;
delta_x += old_deltaX;
delta_y += old_deltaY;
wheel_ticks_x += old_wheelTicksX;
wheel_ticks_y += old_wheelTicksY;
movement_x += old_movementX;
movement_y += old_movementY;
acceleration_ratio_x = GetAccelerationRatio(delta_x, unaccelerated_x);
acceleration_ratio_y = GetAccelerationRatio(delta_y, unaccelerated_y);
dispatch_type =
MergeDispatchTypes(old_dispatch_type, mouse_wheel_event.dispatch_type);
if (mouse_wheel_event.has_synthetic_phase &&
mouse_wheel_event.phase != old_phase) {
// Coalesce a wheel event with synthetic phase changed to a wheel event
// with synthetic phase began.
DCHECK_EQ(WebMouseWheelEvent::kPhaseChanged, mouse_wheel_event.phase);
DCHECK_EQ(WebMouseWheelEvent::kPhaseBegan, old_phase);
phase = WebMouseWheelEvent::kPhaseBegan;
}
}
float WebMouseWheelEvent::DeltaXInRootFrame() const {
return delta_x / frame_scale_;
}
float WebMouseWheelEvent::DeltaYInRootFrame() const {
return delta_y / frame_scale_;
}
WebMouseWheelEvent WebMouseWheelEvent::FlattenTransform() const {
WebMouseWheelEvent result = *this;
result.delta_x /= result.frame_scale_;
result.delta_y /= result.frame_scale_;
result.FlattenTransformSelf();
return result;
}
// static
WebMouseWheelEvent::EventAction
WebMouseWheelEvent::GetPlatformSpecificDefaultEventAction(
const WebMouseWheelEvent& event) {
#if defined(USE_AURA)
// Scroll events generated from the mouse wheel when the control key is held
// don't trigger scrolling. Instead, they may cause zooming.
if (event.delta_units != ui::ScrollGranularity::kScrollByPrecisePixel &&
(event.GetModifiers() & WebInputEvent::kControlKey)) {
return blink::WebMouseWheelEvent::EventAction::kPageZoom;
}
if (event.delta_x == 0 && (event.GetModifiers() & WebInputEvent::kShiftKey))
return blink::WebMouseWheelEvent::EventAction::kScrollHorizontal;
#endif
if (event.rails_mode == WebInputEvent::kRailsModeHorizontal ||
(event.delta_x != 0 && event.delta_y == 0)) {
return blink::WebMouseWheelEvent::EventAction::kScrollHorizontal;
}
if (event.rails_mode == WebInputEvent::kRailsModeVertical ||
(event.delta_x == 0 && event.delta_y != 0)) {
return blink::WebMouseWheelEvent::EventAction::kScrollVertical;
}
return blink::WebMouseWheelEvent::EventAction::kScroll;
}
} // namespace blink