| Index: content/browser/renderer_host/render_widget_host_view_aura.cc
|
| diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
|
| index a59880e6a98cec1506666c278943ce2fdaa17069..a3cab6ada3b22a5fd9ac998e3978fcb248a8be08 100644
|
| --- a/content/browser/renderer_host/render_widget_host_view_aura.cc
|
| +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
|
| @@ -65,9 +65,11 @@
|
| #include "ui/compositor/dip_util.h"
|
| #include "ui/events/event.h"
|
| #include "ui/events/event_utils.h"
|
| +#include "ui/events/gestures/fling_curve.h"
|
| #include "ui/events/gestures/gesture_recognizer.h"
|
| #include "ui/gfx/canvas.h"
|
| #include "ui/gfx/display.h"
|
| +#include "ui/gfx/frame_time.h"
|
| #include "ui/gfx/rect_conversions.h"
|
| #include "ui/gfx/screen.h"
|
| #include "ui/gfx/size_conversions.h"
|
| @@ -104,6 +106,91 @@ using blink::WebTouchEvent;
|
|
|
| namespace content {
|
|
|
| +class Flinger : public ui::CompositorAnimationObserver {
|
| + public:
|
| + class Delegate {
|
| + public:
|
| + virtual ~Delegate() {}
|
| +
|
| + virtual void OnScroll(const gfx::Vector2dF& scroll_delta) = 0;
|
| +
|
| + virtual void OnScrollEnd() = 0;
|
| + };
|
| +
|
| + Flinger(Delegate* delegate,
|
| + const gfx::Vector2dF& velocity,
|
| + ui::Compositor* compositor)
|
| + : delegate_(delegate),
|
| + compositor_(compositor),
|
| + fling_curve_(velocity, gfx::FrameTime::Now()) {
|
| + CHECK(delegate_);
|
| + compositor_->AddAnimationObserver(this);
|
| + }
|
| +
|
| + virtual ~Flinger() { Done(); }
|
| +
|
| + private:
|
| + void Done() {
|
| + if (!delegate_)
|
| + return;
|
| + compositor_->RemoveAnimationObserver(this);
|
| + Delegate* delegate = delegate_;
|
| + delegate_ = NULL;
|
| + delegate->OnScrollEnd();
|
| + }
|
| +
|
| + // ui::CompositorAnimationObserver:
|
| + virtual void OnAnimationStep(base::TimeTicks timestamp) OVERRIDE {
|
| + CHECK(delegate_);
|
| + if (fling_curve_.start_timestamp() > timestamp)
|
| + return;
|
| + gfx::Vector2dF scroll = fling_curve_.GetScrollAmountAtTime(timestamp);
|
| + if (scroll.IsZero())
|
| + Done();
|
| + else
|
| + delegate_->OnScroll(scroll);
|
| + }
|
| +
|
| + Delegate* delegate_;
|
| + ui::Compositor* compositor_;
|
| + ui::FlingCurve fling_curve_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(Flinger);
|
| +};
|
| +
|
| +class FlingerDelegate : public Flinger::Delegate {
|
| + public:
|
| + FlingerDelegate(RenderWidgetHostView* view,
|
| + const blink::WebGestureEvent& gesture_event)
|
| + : view_(view), gesture_(gesture_event) {}
|
| +
|
| + virtual ~FlingerDelegate() {}
|
| +
|
| + private:
|
| + // Flinger::Delegate:
|
| + virtual void OnScroll(const gfx::Vector2dF& scroll_delta) OVERRIDE {
|
| + blink::WebGestureEvent gesture = gesture_;
|
| + gesture.type = blink::WebInputEvent::GestureScrollUpdateWithoutPropagation;
|
| + gesture.data.scrollUpdate.deltaX = scroll_delta.x();
|
| + gesture.data.scrollUpdate.deltaY = scroll_delta.y();
|
| + RenderWidgetHostImpl::From(view_->GetRenderWidgetHost())
|
| + ->ForwardGestureEvent(gesture);
|
| + }
|
| +
|
| + virtual void OnScrollEnd() OVERRIDE {
|
| + blink::WebGestureEvent gesture = gesture_;
|
| + gesture.type = blink::WebInputEvent::GestureScrollEnd;
|
| + RenderWidgetHostImpl::From(view_->GetRenderWidgetHost())
|
| + ->ForwardGestureEvent(gesture);
|
| + delete this;
|
| + }
|
| +
|
| + RenderWidgetHostView* view_;
|
| + blink::WebGestureEvent gesture_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(FlingerDelegate);
|
| +};
|
| +
|
| namespace {
|
|
|
| // In mouse lock mode, we need to prevent the (invisible) cursor from hitting
|
| @@ -1965,6 +2052,11 @@ void RenderWidgetHostViewAura::OnGestureEvent(ui::GestureEvent* event) {
|
| if (host_->IsRenderView())
|
| delegate = RenderViewHost::From(host_)->GetDelegate();
|
|
|
| + // If there is an active fling, then any incoming new gesture event should
|
| + // terminate the fling.
|
| + if (flinger_ && event->type() == ui::ET_GESTURE_BEGIN)
|
| + flinger_.reset();
|
| +
|
| if (delegate && event->type() == ui::ET_GESTURE_BEGIN &&
|
| event->details().touch_points() == 1) {
|
| delegate->HandleGestureBegin();
|
| @@ -1980,7 +2072,13 @@ void RenderWidgetHostViewAura::OnGestureEvent(ui::GestureEvent* event) {
|
| host_->ForwardGestureEvent(fling_cancel);
|
| }
|
|
|
| - if (gesture.type != blink::WebInputEvent::Undefined) {
|
| + if (gesture.type == blink::WebInputEvent::GestureFlingStart) {
|
| + flinger_.reset(
|
| + new Flinger(new FlingerDelegate(this, gesture),
|
| + gfx::Vector2dF(gesture.data.flingStart.velocityX,
|
| + gesture.data.flingStart.velocityY),
|
| + window_->GetHost()->compositor()));
|
| + } else if (gesture.type != blink::WebInputEvent::Undefined) {
|
| host_->ForwardGestureEventWithLatencyInfo(gesture, *event->latency());
|
|
|
| if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN ||
|
|
|