| Index: ui/events/blink/event_with_callback.cc
|
| diff --git a/ui/events/blink/event_with_callback.cc b/ui/events/blink/event_with_callback.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..7d1aaa171637502df9d3931348bb740bc90c12a5
|
| --- /dev/null
|
| +++ b/ui/events/blink/event_with_callback.cc
|
| @@ -0,0 +1,141 @@
|
| +// 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 "ui/events/blink/event_with_callback.h"
|
| +
|
| +#include "base/memory/ptr_util.h"
|
| +#include "ui/events/blink/did_overscroll_params.h"
|
| +#include "ui/events/blink/web_input_event_traits.h"
|
| +
|
| +using blink::WebInputEvent;
|
| +using blink::WebGestureEvent;
|
| +
|
| +namespace ui {
|
| +
|
| +namespace {
|
| +
|
| +bool CanCoalesce(const WebGestureEvent& event_to_coalesce,
|
| + const WebGestureEvent& event) {
|
| + if (event.type != event_to_coalesce.type ||
|
| + event.sourceDevice != event_to_coalesce.sourceDevice ||
|
| + event.modifiers != event_to_coalesce.modifiers)
|
| + return false;
|
| +
|
| + if (event.type == WebInputEvent::GestureScrollUpdate)
|
| + return true;
|
| +
|
| + // GesturePinchUpdate scales can be combined only if they share a focal point,
|
| + // e.g., with double-tap drag zoom.
|
| + if (event.type == WebInputEvent::GesturePinchUpdate &&
|
| + event.x == event_to_coalesce.x && event.y == event_to_coalesce.y)
|
| + return true;
|
| +
|
| + return false;
|
| +}
|
| +
|
| +void Coalesce(const WebGestureEvent& event_to_coalesce,
|
| + WebGestureEvent* event) {
|
| + DCHECK(CanCoalesce(event_to_coalesce, *event));
|
| + if (event->type == WebInputEvent::GestureScrollUpdate) {
|
| + event->data.scrollUpdate.deltaX +=
|
| + event_to_coalesce.data.scrollUpdate.deltaX;
|
| + event->data.scrollUpdate.deltaY +=
|
| + event_to_coalesce.data.scrollUpdate.deltaY;
|
| + DCHECK_EQ(
|
| + event->data.scrollUpdate.previousUpdateInSequencePrevented,
|
| + event_to_coalesce.data.scrollUpdate.previousUpdateInSequencePrevented);
|
| + } else if (event->type == WebInputEvent::GesturePinchUpdate) {
|
| + event->data.pinchUpdate.scale *= event_to_coalesce.data.pinchUpdate.scale;
|
| + // Ensure the scale remains bounded above 0 and below Infinity so that
|
| + // we can reliably perform operations like log on the values.
|
| + if (event->data.pinchUpdate.scale < std::numeric_limits<float>::min())
|
| + event->data.pinchUpdate.scale = std::numeric_limits<float>::min();
|
| + else if (event->data.pinchUpdate.scale > std::numeric_limits<float>::max())
|
| + event->data.pinchUpdate.scale = std::numeric_limits<float>::max();
|
| + }
|
| +}
|
| +
|
| +bool CanCoalesce(const blink::WebInputEvent& event_to_coalesce,
|
| + const blink::WebInputEvent& event) {
|
| + if (blink::WebInputEvent::isGestureEventType(event_to_coalesce.type) &&
|
| + blink::WebInputEvent::isGestureEventType(event.type)) {
|
| + return CanCoalesce(
|
| + static_cast<const blink::WebGestureEvent&>(event_to_coalesce),
|
| + static_cast<const blink::WebGestureEvent&>(event));
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +void Coalesce(const blink::WebInputEvent& event_to_coalesce,
|
| + blink::WebInputEvent* event) {
|
| + if (blink::WebInputEvent::isGestureEventType(event_to_coalesce.type) &&
|
| + blink::WebInputEvent::isGestureEventType(event->type)) {
|
| + Coalesce(static_cast<const blink::WebGestureEvent&>(event_to_coalesce),
|
| + static_cast<blink::WebGestureEvent*>(event));
|
| + }
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +EventWithCallback::EventWithCallback(
|
| + ScopedWebInputEvent event,
|
| + const LatencyInfo& latency,
|
| + const InputHandlerProxy::EventDispositionCallback& callback)
|
| + : event_(WebInputEventTraits::Clone(*event)),
|
| + latency_(latency),
|
| + creation_timestamp_(base::TimeTicks::Now()),
|
| + last_coalesced_timestamp_(creation_timestamp_) {
|
| + original_events_.emplace_back(std::move(event), callback);
|
| +}
|
| +
|
| +EventWithCallback::~EventWithCallback() {}
|
| +
|
| +bool EventWithCallback::CanCoalesceWith(const EventWithCallback& other) const {
|
| + return CanCoalesce(other.event(), event());
|
| +}
|
| +
|
| +void EventWithCallback::CoalesceWith(EventWithCallback* other) {
|
| + // |other| should be a newer event than |this|.
|
| + if (other->latency_.trace_id() >= 0 && latency_.trace_id() >= 0)
|
| + DCHECK_GT(other->latency_.trace_id(), latency_.trace_id());
|
| +
|
| + // New events get coalesced into older events, and the newer timestamp
|
| + // should always be preserved.
|
| + const double time_stamp_seconds = other->event().timeStampSeconds;
|
| + Coalesce(other->event(), event_.get());
|
| + event_->timeStampSeconds = time_stamp_seconds;
|
| +
|
| + // When coalescing two input events, we keep the oldest LatencyInfo
|
| + // since it will represent the longest latency.
|
| + other->latency_ = latency_;
|
| + other->latency_.set_coalesced();
|
| +
|
| + // Move original events.
|
| + original_events_.splice(original_events_.end(), other->original_events_);
|
| + last_coalesced_timestamp_ = base::TimeTicks::Now();
|
| +}
|
| +
|
| +void EventWithCallback::RunCallbacks(
|
| + InputHandlerProxy::EventDisposition disposition,
|
| + const LatencyInfo& latency,
|
| + std::unique_ptr<DidOverscrollParams> did_overscroll_params) {
|
| + for (auto& original_event : original_events_) {
|
| + std::unique_ptr<DidOverscrollParams> did_overscroll_params_copy;
|
| + if (did_overscroll_params) {
|
| + did_overscroll_params_copy =
|
| + base::MakeUnique<DidOverscrollParams>(*did_overscroll_params);
|
| + }
|
| + original_event.callback_.Run(disposition, std::move(original_event.event_),
|
| + latency, std::move(did_overscroll_params));
|
| + }
|
| +}
|
| +
|
| +EventWithCallback::OriginalEventWithCallback::OriginalEventWithCallback(
|
| + ScopedWebInputEvent event,
|
| + const InputHandlerProxy::EventDispositionCallback& callback)
|
| + : event_(std::move(event)), callback_(callback) {}
|
| +
|
| +EventWithCallback::OriginalEventWithCallback::~OriginalEventWithCallback() {}
|
| +
|
| +} // namespace ui
|
|
|