summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortony@chromium.org <tony@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-26 05:43:02 +0000
committertony@chromium.org <tony@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-26 05:43:02 +0000
commitbf1cfd9ac86dcfa25731db6cb1a502bd91d2bfae (patch)
treecf636b9c3a46f3d9a4b349bf34574d60c18d05bd
parent5ddc86faaa5e866f87c16e9178eb8d8b9834c2ee (diff)
downloadchromium_src-bf1cfd9ac86dcfa25731db6cb1a502bd91d2bfae.zip
chromium_src-bf1cfd9ac86dcfa25731db6cb1a502bd91d2bfae.tar.gz
chromium_src-bf1cfd9ac86dcfa25731db6cb1a502bd91d2bfae.tar.bz2
Trigger overlay scrollbar animation when the pointer is nearby.
When the mouse cursor is near a scrollbar, trigger the scrollbar animation so it's easier to find and grab the thinning scrollbars. BUG=274010 Review URL: https://codereview.chromium.org/23983035 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@225352 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cc/animation/scrollbar_animation_controller.h1
-rw-r--r--cc/animation/scrollbar_animation_controller_linear_fade.cc6
-rw-r--r--cc/animation/scrollbar_animation_controller_linear_fade.h1
-rw-r--r--cc/animation/scrollbar_animation_controller_thinning.cc15
-rw-r--r--cc/animation/scrollbar_animation_controller_thinning.h6
-rw-r--r--cc/input/input_handler.h2
-rw-r--r--cc/layers/painted_scrollbar_layer.cc2
-rw-r--r--cc/trees/layer_tree_host_impl.cc108
-rw-r--r--cc/trees/layer_tree_host_impl.h8
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc85
-rw-r--r--content/renderer/gpu/input_handler_proxy.cc6
-rw-r--r--content/renderer/gpu/input_handler_proxy_unittest.cc1
-rw-r--r--ui/gfx/rect_base.h4
-rw-r--r--ui/gfx/rect_base_impl.h16
-rw-r--r--ui/gfx/rect_unittest.cc28
-rw-r--r--webkit/renderer/compositor_bindings/web_compositor_support_impl.cc7
-rw-r--r--webkit/renderer/compositor_bindings/web_compositor_support_impl.h2
17 files changed, 264 insertions, 34 deletions
diff --git a/cc/animation/scrollbar_animation_controller.h b/cc/animation/scrollbar_animation_controller.h
index d3667f1..d0794a2 100644
--- a/cc/animation/scrollbar_animation_controller.h
+++ b/cc/animation/scrollbar_animation_controller.h
@@ -27,6 +27,7 @@ class CC_EXPORT ScrollbarAnimationController {
// Returns true if we should start an animation.
virtual bool DidScrollUpdate(base::TimeTicks now) = 0;
+ virtual bool DidMouseMoveNear(base::TimeTicks now, float distance) = 0;
};
} // namespace cc
diff --git a/cc/animation/scrollbar_animation_controller_linear_fade.cc b/cc/animation/scrollbar_animation_controller_linear_fade.cc
index 962b26a..451c45d 100644
--- a/cc/animation/scrollbar_animation_controller_linear_fade.cc
+++ b/cc/animation/scrollbar_animation_controller_linear_fade.cc
@@ -80,6 +80,12 @@ bool ScrollbarAnimationControllerLinearFade::DidScrollUpdate(
return false;
}
+bool ScrollbarAnimationControllerLinearFade::DidMouseMoveNear(
+ base::TimeTicks now, float distance) {
+ // Ignore mouse move events.
+ return false;
+}
+
float ScrollbarAnimationControllerLinearFade::OpacityAtTime(
base::TimeTicks now) {
if (scroll_gesture_has_scrolled_)
diff --git a/cc/animation/scrollbar_animation_controller_linear_fade.h b/cc/animation/scrollbar_animation_controller_linear_fade.h
index eca4c4f..b490f2e 100644
--- a/cc/animation/scrollbar_animation_controller_linear_fade.h
+++ b/cc/animation/scrollbar_animation_controller_linear_fade.h
@@ -30,6 +30,7 @@ class CC_EXPORT ScrollbarAnimationControllerLinearFade
virtual void DidScrollGestureBegin() OVERRIDE;
virtual void DidScrollGestureEnd(base::TimeTicks now) OVERRIDE;
virtual bool DidScrollUpdate(base::TimeTicks now) OVERRIDE;
+ virtual bool DidMouseMoveNear(base::TimeTicks now, float distance) OVERRIDE;
protected:
ScrollbarAnimationControllerLinearFade(LayerImpl* scroll_layer,
diff --git a/cc/animation/scrollbar_animation_controller_thinning.cc b/cc/animation/scrollbar_animation_controller_thinning.cc
index fcacfaa..e439daf 100644
--- a/cc/animation/scrollbar_animation_controller_thinning.cc
+++ b/cc/animation/scrollbar_animation_controller_thinning.cc
@@ -35,7 +35,8 @@ ScrollbarAnimationControllerThinning::ScrollbarAnimationControllerThinning(
scroll_layer_(scroll_layer),
scroll_gesture_in_progress_(false),
animation_delay_(animation_delay),
- animation_duration_(animation_duration) {}
+ animation_duration_(animation_duration),
+ mouse_move_distance_to_trigger_animation_(100.f) {}
ScrollbarAnimationControllerThinning::~ScrollbarAnimationControllerThinning() {
}
@@ -82,6 +83,14 @@ bool ScrollbarAnimationControllerThinning::DidScrollUpdate(
return true;
}
+bool ScrollbarAnimationControllerThinning::DidMouseMoveNear(
+ base::TimeTicks now, float distance) {
+ if (distance < mouse_move_distance_to_trigger_animation_)
+ return DidScrollUpdate(now);
+
+ return false;
+}
+
float ScrollbarAnimationControllerThinning::AnimationProgressAtTime(
base::TimeTicks now) {
if (scroll_gesture_in_progress_)
@@ -100,7 +109,7 @@ float ScrollbarAnimationControllerThinning::OpacityAtAnimationProgress(
float progress) {
const float kIdleOpacity = 0.7f;
- return ((1 - kIdleOpacity) * (1.f - progress)) + kIdleOpacity;
+ return ((1.f - kIdleOpacity) * (1.f - progress)) + kIdleOpacity;
}
float
@@ -108,7 +117,7 @@ ScrollbarAnimationControllerThinning::ThumbThicknessScaleAtAnimationProgress(
float progress) {
const float kIdleThicknessScale = 0.4f;
- return ((1 - kIdleThicknessScale) * (1.f - progress)) + kIdleThicknessScale;
+ return ((1.f - kIdleThicknessScale) * (1.f - progress)) + kIdleThicknessScale;
}
void ScrollbarAnimationControllerThinning::ApplyOpacityAndThumbThicknessScale(
diff --git a/cc/animation/scrollbar_animation_controller_thinning.h b/cc/animation/scrollbar_animation_controller_thinning.h
index 0211479..1f0d41d 100644
--- a/cc/animation/scrollbar_animation_controller_thinning.h
+++ b/cc/animation/scrollbar_animation_controller_thinning.h
@@ -26,6 +26,10 @@ class CC_EXPORT ScrollbarAnimationControllerThinning
virtual ~ScrollbarAnimationControllerThinning();
+ void set_mouse_move_distance_for_test(float distance) {
+ mouse_move_distance_to_trigger_animation_ = distance;
+ }
+
// ScrollbarAnimationController overrides.
virtual bool IsAnimating() const OVERRIDE;
virtual base::TimeDelta DelayBeforeStart(base::TimeTicks now) const OVERRIDE;
@@ -34,6 +38,7 @@ class CC_EXPORT ScrollbarAnimationControllerThinning
virtual void DidScrollGestureBegin() OVERRIDE;
virtual void DidScrollGestureEnd(base::TimeTicks now) OVERRIDE;
virtual bool DidScrollUpdate(base::TimeTicks now) OVERRIDE;
+ virtual bool DidMouseMoveNear(base::TimeTicks now, float distance) OVERRIDE;
protected:
ScrollbarAnimationControllerThinning(LayerImpl* scroll_layer,
@@ -56,6 +61,7 @@ class CC_EXPORT ScrollbarAnimationControllerThinning
base::TimeDelta animation_delay_;
base::TimeDelta animation_duration_;
+ float mouse_move_distance_to_trigger_animation_;
DISALLOW_COPY_AND_ASSIGN(ScrollbarAnimationControllerThinning);
};
diff --git a/cc/input/input_handler.h b/cc/input/input_handler.h
index db26561..26fc480 100644
--- a/cc/input/input_handler.h
+++ b/cc/input/input_handler.h
@@ -96,6 +96,8 @@ class CC_EXPORT InputHandler {
virtual void NotifyCurrentFlingVelocity(gfx::Vector2dF velocity) = 0;
+ virtual void MouseMoveAt(gfx::Point mouse_position) = 0;
+
// Stop scrolling the selected layer. Should only be called if ScrollBegin()
// returned ScrollStarted.
virtual void ScrollEnd() = 0;
diff --git a/cc/layers/painted_scrollbar_layer.cc b/cc/layers/painted_scrollbar_layer.cc
index 4272fe6..dc0cd73 100644
--- a/cc/layers/painted_scrollbar_layer.cc
+++ b/cc/layers/painted_scrollbar_layer.cc
@@ -183,7 +183,7 @@ void PaintedScrollbarLayer::UpdateThumbAndTrackGeometry() {
}
bool PaintedScrollbarLayer::Update(ResourceUpdateQueue* queue,
- const OcclusionTracker* occlusion) {
+ const OcclusionTracker* occlusion) {
UpdateThumbAndTrackGeometry();
gfx::Rect scaled_track_rect = ScrollbarLayerRectToContentRect(
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 4a7bad4..90bd247 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -31,6 +31,7 @@
#include "cc/layers/layer_iterator.h"
#include "cc/layers/painted_scrollbar_layer_impl.h"
#include "cc/layers/render_surface_impl.h"
+#include "cc/layers/scrollbar_layer_impl_base.h"
#include "cc/output/compositor_frame_metadata.h"
#include "cc/output/copy_output_request.h"
#include "cc/output/delegating_renderer.h"
@@ -1479,7 +1480,7 @@ LayerImpl* LayerTreeHostImpl::CurrentlyScrollingLayer() const {
// this function returns the associated scroll layer if any.
static LayerImpl* FindScrollLayerForContentLayer(LayerImpl* layer_impl) {
if (!layer_impl)
- return 0;
+ return NULL;
if (layer_impl->scrollable())
return layer_impl;
@@ -1489,7 +1490,7 @@ static LayerImpl* FindScrollLayerForContentLayer(LayerImpl* layer_impl) {
layer_impl->parent()->scrollable())
return layer_impl->parent();
- return 0;
+ return NULL;
}
void LayerTreeHostImpl::CreatePendingTree() {
@@ -1931,18 +1932,10 @@ static LayerImpl* NextScrollLayer(LayerImpl* layer) {
return layer->parent();
}
-InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin(
- gfx::Point viewport_point, InputHandler::ScrollInputType type) {
- TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBegin");
-
- if (top_controls_manager_)
- top_controls_manager_->ScrollBegin();
-
- DCHECK(!CurrentlyScrollingLayer());
- ClearCurrentlyScrollingLayer();
-
- if (!EnsureRenderSurfaceLayerList())
- return ScrollIgnored;
+LayerImpl* LayerTreeHostImpl::FindScrollLayerForViewportPoint(
+ gfx::Point viewport_point, InputHandler::ScrollInputType type,
+ bool* scroll_on_main_thread) {
+ DCHECK(scroll_on_main_thread);
gfx::PointF device_viewport_point = gfx::ScalePoint(viewport_point,
device_scale_factor_);
@@ -1959,9 +1952,8 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin(
// thread.
ScrollStatus status = layer_impl->TryScroll(device_viewport_point, type);
if (status == ScrollOnMainThread) {
- rendering_stats_instrumentation_->IncrementMainThreadScrolls();
- UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true);
- return ScrollOnMainThread;
+ *scroll_on_main_thread = true;
+ return NULL;
}
LayerImpl* scroll_layer_impl = FindScrollLayerForContentLayer(layer_impl);
@@ -1969,12 +1961,10 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin(
continue;
status = scroll_layer_impl->TryScroll(device_viewport_point, type);
-
// If any layer wants to divert the scroll event to the main thread, abort.
if (status == ScrollOnMainThread) {
- rendering_stats_instrumentation_->IncrementMainThreadScrolls();
- UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true);
- return ScrollOnMainThread;
+ *scroll_on_main_thread = true;
+ return NULL;
}
if (status == ScrollStarted && !potentially_scrolling_layer_impl)
@@ -1990,6 +1980,32 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin(
potentially_scrolling_layer_impl = RootScrollLayer();
}
+ return potentially_scrolling_layer_impl;
+}
+
+InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin(
+ gfx::Point viewport_point, InputHandler::ScrollInputType type) {
+ TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBegin");
+
+ if (top_controls_manager_)
+ top_controls_manager_->ScrollBegin();
+
+ DCHECK(!CurrentlyScrollingLayer());
+ ClearCurrentlyScrollingLayer();
+
+ if (!EnsureRenderSurfaceLayerList())
+ return ScrollIgnored;
+
+ bool scroll_on_main_thread = false;
+ LayerImpl* potentially_scrolling_layer_impl = FindScrollLayerForViewportPoint(
+ viewport_point, type, &scroll_on_main_thread);
+
+ if (scroll_on_main_thread) {
+ rendering_stats_instrumentation_->IncrementMainThreadScrolls();
+ UMA_HISTOGRAM_BOOLEAN("TryScroll.SlowScroll", true);
+ return ScrollOnMainThread;
+ }
+
if (potentially_scrolling_layer_impl) {
active_tree_->SetCurrentlyScrollingLayer(
potentially_scrolling_layer_impl);
@@ -2283,6 +2299,56 @@ void LayerTreeHostImpl::NotifyCurrentFlingVelocity(gfx::Vector2dF velocity) {
current_fling_velocity_ = velocity;
}
+float LayerTreeHostImpl::DeviceSpaceDistanceToLayer(
+ gfx::PointF device_viewport_point,
+ LayerImpl* layer_impl) {
+ if (!layer_impl)
+ return std::numeric_limits<float>::max();
+
+ gfx::Rect layer_impl_bounds(
+ layer_impl->content_bounds());
+
+ gfx::RectF device_viewport_layer_impl_bounds = MathUtil::MapClippedRect(
+ layer_impl->screen_space_transform(),
+ layer_impl_bounds);
+
+ return device_viewport_layer_impl_bounds.ManhattanDistanceToPoint(
+ device_viewport_point);
+}
+
+void LayerTreeHostImpl::MouseMoveAt(gfx::Point viewport_point) {
+ if (!EnsureRenderSurfaceLayerList())
+ return;
+
+ // TODO(tony): What should happen if the mouse cursor is over the scrollbar?
+ bool scroll_on_main_thread = false;
+ LayerImpl* scroll_layer_impl = FindScrollLayerForViewportPoint(
+ viewport_point, InputHandler::Gesture,
+ &scroll_on_main_thread);
+ if (scroll_on_main_thread || !scroll_layer_impl)
+ return;
+
+ ScrollbarAnimationController* animation_controller =
+ scroll_layer_impl->scrollbar_animation_controller();
+ if (!animation_controller)
+ return;
+
+ gfx::PointF device_viewport_point = gfx::ScalePoint(viewport_point,
+ device_scale_factor_);
+ float distance_to_scrollbar = std::min(
+ DeviceSpaceDistanceToLayer(device_viewport_point,
+ scroll_layer_impl->horizontal_scrollbar_layer()),
+ DeviceSpaceDistanceToLayer(device_viewport_point,
+ scroll_layer_impl->vertical_scrollbar_layer()));
+
+ bool should_animate = animation_controller->DidMouseMoveNear(
+ CurrentPhysicalTimeTicks(), distance_to_scrollbar / device_scale_factor_);
+ if (should_animate) {
+ client_->SetNeedsRedrawOnImplThread();
+ StartScrollbarAnimation();
+ }
+}
+
void LayerTreeHostImpl::PinchGestureBegin() {
pinch_gesture_active_ = true;
previous_pinch_anchor_ = gfx::Point();
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index 17dc747..b022933 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -47,6 +47,7 @@ class PaintTimeCounter;
class MemoryHistory;
class RenderingStatsInstrumentation;
class RenderPassDrawQuad;
+class ScrollbarLayerImplBase;
class TextureMailboxDeleter;
class TopControlsManager;
class UIResourceBitmap;
@@ -116,6 +117,7 @@ class CC_EXPORT LayerTreeHostImpl
virtual void ScrollEnd() OVERRIDE;
virtual InputHandler::ScrollStatus FlingScrollBegin() OVERRIDE;
virtual void NotifyCurrentFlingVelocity(gfx::Vector2dF velocity) OVERRIDE;
+ virtual void MouseMoveAt(gfx::Point viewport_point) OVERRIDE;
virtual void PinchGestureBegin() OVERRIDE;
virtual void PinchGestureUpdate(float magnify_delta,
gfx::Point anchor) OVERRIDE;
@@ -480,6 +482,12 @@ class CC_EXPORT LayerTreeHostImpl
void UpdateCurrentFrameTime(base::TimeTicks* ticks, base::Time* now) const;
+ LayerImpl* FindScrollLayerForViewportPoint(
+ gfx::Point viewport_point,
+ InputHandler::ScrollInputType type,
+ bool* scroll_on_main_thread);
+ float DeviceSpaceDistanceToLayer(gfx::PointF device_viewport_point,
+ LayerImpl* layer_impl);
void StartScrollbarAnimationRecursive(LayerImpl* layer, base::TimeTicks time);
void SetManagedMemoryPolicy(const ManagedMemoryPolicy& policy,
bool zero_budget);
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index d0bd7c1..29e5343 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -10,6 +10,7 @@
#include "base/command_line.h"
#include "base/containers/hash_tables.h"
#include "base/containers/scoped_ptr_hash_map.h"
+#include "cc/animation/scrollbar_animation_controller_thinning.h"
#include "cc/base/math_util.h"
#include "cc/debug/test_web_graphics_context_3d.h"
#include "cc/input/top_controls_manager.h"
@@ -343,6 +344,8 @@ class LayerTreeHostImplTest : public testing::Test,
on_can_draw_state_changed_called_ = false;
}
+ void SetupMouseMoveAtWithDeviceScale(float device_scale_factor);
+
protected:
virtual scoped_ptr<OutputSurface> CreateOutputSurface() {
return CreateFakeOutputSurface();
@@ -1206,6 +1209,88 @@ TEST_F(LayerTreeHostImplTest, ScrollbarLinearFadeScheduling) {
EXPECT_EQ(fake_now, host_impl_->CurrentFrameTimeTicks());
}
+void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale(
+ float device_scale_factor) {
+ LayerTreeSettings settings;
+ settings.scrollbar_animator = LayerTreeSettings::Thinning;
+
+ gfx::Size viewport_size(300, 200);
+ gfx::Size device_viewport_size = gfx::ToFlooredSize(
+ gfx::ScaleSize(viewport_size, device_scale_factor));
+ gfx::Size content_size(1000, 1000);
+
+ host_impl_ = LayerTreeHostImpl::Create(
+ settings, this, &proxy_, &stats_instrumentation_);
+ host_impl_->InitializeRenderer(CreateOutputSurface());
+ host_impl_->SetDeviceScaleFactor(device_scale_factor);
+ host_impl_->SetViewportSize(device_viewport_size);
+
+ scoped_ptr<LayerImpl> root =
+ LayerImpl::Create(host_impl_->active_tree(), 1);
+ root->SetBounds(viewport_size);
+
+ scoped_ptr<LayerImpl> scroll =
+ LayerImpl::Create(host_impl_->active_tree(), 2);
+ scroll->SetScrollable(true);
+ scroll->SetScrollOffset(gfx::Vector2d());
+ scroll->SetMaxScrollOffset(gfx::Vector2d(content_size.width(),
+ content_size.height()));
+ scroll->SetBounds(content_size);
+ scroll->SetContentBounds(content_size);
+
+ scoped_ptr<LayerImpl> contents =
+ LayerImpl::Create(host_impl_->active_tree(), 3);
+ contents->SetDrawsContent(true);
+ contents->SetBounds(content_size);
+ contents->SetContentBounds(content_size);
+
+ // The scrollbar is on the right side.
+ scoped_ptr<PaintedScrollbarLayerImpl> scrollbar =
+ PaintedScrollbarLayerImpl::Create(host_impl_->active_tree(), 5, VERTICAL);
+ scrollbar->SetContentBounds(gfx::Size(15, viewport_size.height()));
+ scrollbar->SetPosition(gfx::Point(285, 0));
+ scroll->SetVerticalScrollbarLayer(scrollbar.get());
+
+ scroll->AddChild(contents.Pass());
+ root->AddChild(scroll.Pass());
+ root->AddChild(scrollbar.PassAs<LayerImpl>());
+
+ host_impl_->active_tree()->SetRootLayer(root.Pass());
+ host_impl_->active_tree()->DidBecomeActive();
+ InitializeRendererAndDrawFrame();
+
+ LayerImpl* root_scroll = host_impl_->active_tree()->RootScrollLayer();
+ ASSERT_TRUE(root_scroll->scrollbar_animation_controller());
+ ScrollbarAnimationControllerThinning* scrollbar_animation_controller =
+ static_cast<ScrollbarAnimationControllerThinning*>(
+ root_scroll->scrollbar_animation_controller());
+ scrollbar_animation_controller->set_mouse_move_distance_for_test(100.f);
+
+ host_impl_->MouseMoveAt(gfx::Point(1, 1));
+ EXPECT_FALSE(did_request_redraw_);
+
+ did_request_redraw_ = false;
+ host_impl_->MouseMoveAt(gfx::Point(200, 50));
+ EXPECT_TRUE(did_request_redraw_);
+
+ did_request_redraw_ = false;
+ host_impl_->MouseMoveAt(gfx::Point(184, 100));
+ EXPECT_FALSE(did_request_redraw_);
+
+ scrollbar_animation_controller->set_mouse_move_distance_for_test(102.f);
+ did_request_redraw_ = false;
+ host_impl_->MouseMoveAt(gfx::Point(184, 100));
+ EXPECT_TRUE(did_request_redraw_);
+}
+
+TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf1) {
+ SetupMouseMoveAtWithDeviceScale(1.f);
+}
+
+TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf2) {
+ SetupMouseMoveAtWithDeviceScale(2.f);
+}
+
TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) {
SetupScrollAndContentsLayers(gfx::Size(100, 100));
host_impl_->SetViewportSize(gfx::Size(50, 50));
diff --git a/content/renderer/gpu/input_handler_proxy.cc b/content/renderer/gpu/input_handler_proxy.cc
index f1ca2a5..77dd0f0 100644
--- a/content/renderer/gpu/input_handler_proxy.cc
+++ b/content/renderer/gpu/input_handler_proxy.cc
@@ -16,6 +16,7 @@ using WebKit::WebFloatPoint;
using WebKit::WebFloatSize;
using WebKit::WebGestureEvent;
using WebKit::WebInputEvent;
+using WebKit::WebMouseEvent;
using WebKit::WebMouseWheelEvent;
using WebKit::WebPoint;
using WebKit::WebTouchEvent;
@@ -223,6 +224,11 @@ InputHandlerProxy::EventDisposition InputHandlerProxy::HandleInputEvent(
return DROP_EVENT;
} else if (WebInputEvent::isKeyboardEventType(event.type)) {
CancelCurrentFling();
+ } else if (event.type == WebInputEvent::MouseMove) {
+ const WebMouseEvent& mouse_event =
+ *static_cast<const WebMouseEvent*>(&event);
+ // TODO(tony): Ignore when mouse buttons are down?
+ input_handler_->MouseMoveAt(gfx::Point(mouse_event.x, mouse_event.y));
}
return DID_NOT_HANDLE;
diff --git a/content/renderer/gpu/input_handler_proxy_unittest.cc b/content/renderer/gpu/input_handler_proxy_unittest.cc
index 4c74513..52ee66d 100644
--- a/content/renderer/gpu/input_handler_proxy_unittest.cc
+++ b/content/renderer/gpu/input_handler_proxy_unittest.cc
@@ -63,6 +63,7 @@ class MockInputHandler : public cc::InputHandler {
base::TimeDelta duration) OVERRIDE {}
virtual void NotifyCurrentFlingVelocity(gfx::Vector2dF velocity) OVERRIDE {}
+ virtual void MouseMoveAt(gfx::Point mouse_position) OVERRIDE {}
virtual bool HaveTouchEventHandlersAt(gfx::Point point) OVERRIDE {
return false;
diff --git a/ui/gfx/rect_base.h b/ui/gfx/rect_base.h
index f1a2863..30fc1f1 100644
--- a/ui/gfx/rect_base.h
+++ b/ui/gfx/rect_base.h
@@ -143,6 +143,10 @@ class UI_EXPORT RectBase {
// same height) with the given rectangle, and the rectangles do not overlap.
bool SharesEdgeWith(const Class& rect) const;
+ // Returns the manhattan distance from the rect to the point. If the point is
+ // inside the rect, returns 0.
+ Type ManhattanDistanceToPoint(const PointClass& point) const;
+
protected:
RectBase(const PointClass& origin, const SizeClass& size)
: origin_(origin), size_(size) {}
diff --git a/ui/gfx/rect_base_impl.h b/ui/gfx/rect_base_impl.h
index e44bc00..a068d15 100644
--- a/ui/gfx/rect_base_impl.h
+++ b/ui/gfx/rect_base_impl.h
@@ -314,4 +314,20 @@ bool RectBase<Class, PointClass, SizeClass, InsetsClass, VectorClass, Type>::
(y() == rect.bottom() || bottom() == rect.y()));
}
+template<typename Class,
+ typename PointClass,
+ typename SizeClass,
+ typename InsetsClass,
+ typename VectorClass,
+ typename Type>
+Type RectBase<Class, PointClass, SizeClass, InsetsClass, VectorClass, Type>::
+ ManhattanDistanceToPoint(const PointClass& point) const {
+ Type x_distance = std::max<Type>(0, std::max(
+ x() - point.x(), point.x() - right()));
+ Type y_distance = std::max<Type>(0, std::max(
+ y() - point.y(), point.y() - bottom()));
+
+ return x_distance + y_distance;
+}
+
} // namespace gfx
diff --git a/ui/gfx/rect_unittest.cc b/ui/gfx/rect_unittest.cc
index 0b5f01e..d62abb6 100644
--- a/ui/gfx/rect_unittest.cc
+++ b/ui/gfx/rect_unittest.cc
@@ -865,4 +865,32 @@ TEST(RectTest, Corners) {
EXPECT_EQ(PointF(4.2f, 6.2f).ToString(), f.bottom_right().ToString());
}
+TEST(RectTest, ManhattanDistanceToPoint) {
+ Rect i(1, 2, 3, 4);
+ EXPECT_EQ(0, i.ManhattanDistanceToPoint(Point(1, 2)));
+ EXPECT_EQ(0, i.ManhattanDistanceToPoint(Point(4, 6)));
+ EXPECT_EQ(0, i.ManhattanDistanceToPoint(Point(2, 4)));
+ EXPECT_EQ(3, i.ManhattanDistanceToPoint(Point(0, 0)));
+ EXPECT_EQ(2, i.ManhattanDistanceToPoint(Point(2, 0)));
+ EXPECT_EQ(3, i.ManhattanDistanceToPoint(Point(5, 0)));
+ EXPECT_EQ(1, i.ManhattanDistanceToPoint(Point(5, 4)));
+ EXPECT_EQ(3, i.ManhattanDistanceToPoint(Point(5, 8)));
+ EXPECT_EQ(2, i.ManhattanDistanceToPoint(Point(3, 8)));
+ EXPECT_EQ(2, i.ManhattanDistanceToPoint(Point(0, 7)));
+ EXPECT_EQ(1, i.ManhattanDistanceToPoint(Point(0, 3)));
+
+ RectF f(1.1f, 2.1f, 3.1f, 4.1f);
+ EXPECT_FLOAT_EQ(0.f, f.ManhattanDistanceToPoint(PointF(1.1f, 2.1f)));
+ EXPECT_FLOAT_EQ(0.f, f.ManhattanDistanceToPoint(PointF(4.2f, 6.f)));
+ EXPECT_FLOAT_EQ(0.f, f.ManhattanDistanceToPoint(PointF(2.f, 4.f)));
+ EXPECT_FLOAT_EQ(3.2f, f.ManhattanDistanceToPoint(PointF(0.f, 0.f)));
+ EXPECT_FLOAT_EQ(2.1f, f.ManhattanDistanceToPoint(PointF(2.f, 0.f)));
+ EXPECT_FLOAT_EQ(2.9f, f.ManhattanDistanceToPoint(PointF(5.f, 0.f)));
+ EXPECT_FLOAT_EQ(.8f, f.ManhattanDistanceToPoint(PointF(5.f, 4.f)));
+ EXPECT_FLOAT_EQ(2.6f, f.ManhattanDistanceToPoint(PointF(5.f, 8.f)));
+ EXPECT_FLOAT_EQ(1.8f, f.ManhattanDistanceToPoint(PointF(3.f, 8.f)));
+ EXPECT_FLOAT_EQ(1.9f, f.ManhattanDistanceToPoint(PointF(0.f, 7.f)));
+ EXPECT_FLOAT_EQ(1.1f, f.ManhattanDistanceToPoint(PointF(0.f, 3.f)));
+}
+
} // namespace gfx
diff --git a/webkit/renderer/compositor_bindings/web_compositor_support_impl.cc b/webkit/renderer/compositor_bindings/web_compositor_support_impl.cc
index 4805dc6..8fb7fbf 100644
--- a/webkit/renderer/compositor_bindings/web_compositor_support_impl.cc
+++ b/webkit/renderer/compositor_bindings/web_compositor_support_impl.cc
@@ -82,13 +82,6 @@ WebScrollbarLayer* WebCompositorSupportImpl::createScrollbarLayer(
}
WebScrollbarLayer* WebCompositorSupportImpl::createSolidColorScrollbarLayer(
- WebScrollbar::Orientation orientation, int thumb_thickness) {
- // TODO(tony): Remove this after the caller in blink is migrated to
- // the version which includes |should_place_vertical_scrollbar_on_left|.
- return new WebScrollbarLayerImpl(orientation, thumb_thickness, false);
-}
-
-WebScrollbarLayer* WebCompositorSupportImpl::createSolidColorScrollbarLayer(
WebScrollbar::Orientation orientation, int thumb_thickness,
bool is_left_side_vertical_scrollbar) {
return new WebScrollbarLayerImpl(orientation, thumb_thickness,
diff --git a/webkit/renderer/compositor_bindings/web_compositor_support_impl.h b/webkit/renderer/compositor_bindings/web_compositor_support_impl.h
index f2c2505..8cf1dc1 100644
--- a/webkit/renderer/compositor_bindings/web_compositor_support_impl.h
+++ b/webkit/renderer/compositor_bindings/web_compositor_support_impl.h
@@ -35,8 +35,6 @@ class WebCompositorSupportImpl : public WebKit::WebCompositorSupport {
WebKit::WebScrollbarThemePainter painter,
WebKit::WebScrollbarThemeGeometry*);
virtual WebKit::WebScrollbarLayer* createSolidColorScrollbarLayer(
- WebKit::WebScrollbar::Orientation orientation, int thumb_thickness);
- virtual WebKit::WebScrollbarLayer* createSolidColorScrollbarLayer(
WebKit::WebScrollbar::Orientation orientation, int thumb_thickness,
bool is_left_side_vertical_scrollbar);
virtual WebKit::WebAnimation* createAnimation(