diff options
-rw-r--r-- | cc/layers/layer.cc | 14 | ||||
-rw-r--r-- | cc/layers/layer.h | 8 | ||||
-rw-r--r-- | cc/layers/layer_impl.cc | 23 | ||||
-rw-r--r-- | cc/layers/layer_impl.h | 9 | ||||
-rw-r--r-- | cc/layers/layer_impl_unittest.cc | 14 | ||||
-rw-r--r-- | cc/layers/layer_unittest.cc | 1 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl.cc | 2 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl.h | 2 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl_unittest.cc | 55 | ||||
-rw-r--r-- | webkit/renderer/compositor_bindings/web_layer_impl.cc | 12 | ||||
-rw-r--r-- | webkit/renderer/compositor_bindings/web_layer_impl.h | 3 |
11 files changed, 140 insertions, 3 deletions
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index 15de223..80fad6a 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc @@ -41,6 +41,8 @@ Layer::Layer() scrollable_(false), should_scroll_on_main_thread_(false), have_wheel_event_handlers_(false), + user_scrollable_horizontal_(true), + user_scrollable_vertical_(true), anchor_point_(0.5f, 0.5f), background_color_(0), compositing_reasons_(kCompositingReasonUnknown), @@ -646,6 +648,16 @@ void Layer::SetScrollable(bool scrollable) { SetNeedsCommit(); } +void Layer::SetUserScrollable(bool horizontal, bool vertical) { + DCHECK(IsPropertyChangeAllowed()); + if (user_scrollable_horizontal_ == horizontal && + user_scrollable_vertical_ == vertical) + return; + user_scrollable_horizontal_ = horizontal; + user_scrollable_vertical_ = vertical; + SetNeedsCommit(); +} + void Layer::SetShouldScrollOnMainThread(bool should_scroll_on_main_thread) { DCHECK(IsPropertyChangeAllowed()); if (should_scroll_on_main_thread_ == should_scroll_on_main_thread) @@ -833,6 +845,8 @@ void Layer::PushPropertiesTo(LayerImpl* layer) { DCHECK(!(TransformIsAnimating() && layer->TransformIsAnimatingOnImplOnly())); layer->SetScrollable(scrollable_); + layer->set_user_scrollable_horizontal(user_scrollable_horizontal_); + layer->set_user_scrollable_vertical(user_scrollable_vertical_); layer->SetMaxScrollOffset(max_scroll_offset_); LayerImpl* scroll_parent = NULL; diff --git a/cc/layers/layer.h b/cc/layers/layer.h index e1bed9b..1328b07 100644 --- a/cc/layers/layer.h +++ b/cc/layers/layer.h @@ -251,6 +251,12 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>, void SetScrollable(bool scrollable); bool scrollable() const { return scrollable_; } + void SetUserScrollable(bool horizontal, bool vertical); + bool user_scrollable_horizontal() const { + return user_scrollable_horizontal_; + } + bool user_scrollable_vertical() const { return user_scrollable_vertical_; } + void SetShouldScrollOnMainThread(bool should_scroll_on_main_thread); bool should_scroll_on_main_thread() const { return should_scroll_on_main_thread_; @@ -539,6 +545,8 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>, bool scrollable_; bool should_scroll_on_main_thread_; bool have_wheel_event_handlers_; + bool user_scrollable_horizontal_; + bool user_scrollable_vertical_; Region non_fast_scrollable_region_; Region touch_event_handler_region_; gfx::PointF position_; diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index d42ec31..14f3e2a 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc @@ -42,6 +42,8 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id) scrollable_(false), should_scroll_on_main_thread_(false), have_wheel_event_handlers_(false), + user_scrollable_horizontal_(true), + user_scrollable_vertical_(true), background_color_(0), stacking_order_changed_(false), double_sided_(true), @@ -341,6 +343,15 @@ void LayerImpl::SetSentScrollDelta(gfx::Vector2d sent_scroll_delta) { gfx::Vector2dF LayerImpl::ScrollBy(gfx::Vector2dF scroll) { DCHECK(scrollable()); + gfx::Vector2dF scroll_hidden; + if (!user_scrollable_horizontal_) { + scroll_hidden.set_x(scroll.x()); + scroll.set_x(0.f); + } + if (!user_scrollable_vertical_) { + scroll_hidden.set_y(scroll.y()); + scroll.set_y(0.f); + } gfx::Vector2dF min_delta = -scroll_offset_; gfx::Vector2dF max_delta = max_scroll_offset_ - scroll_offset_; @@ -348,7 +359,8 @@ gfx::Vector2dF LayerImpl::ScrollBy(gfx::Vector2dF scroll) { gfx::Vector2dF new_delta = (ScrollDelta() + scroll); new_delta.SetToMax(min_delta); new_delta.SetToMin(max_delta); - gfx::Vector2dF unscrolled = ScrollDelta() + scroll - new_delta; + gfx::Vector2dF unscrolled = + ScrollDelta() + scroll + scroll_hidden - new_delta; SetScrollDelta(new_delta); return unscrolled; } @@ -449,6 +461,13 @@ InputHandler::ScrollStatus LayerImpl::TryScroll( return InputHandler::ScrollIgnored; } + if (!user_scrollable_horizontal_ && !user_scrollable_vertical_) { + TRACE_EVENT0("cc", + "LayerImpl::TryScroll: Ignored. User gesture is not allowed" + " to scroll this layer."); + return InputHandler::ScrollIgnored; + } + return InputHandler::ScrollStarted; } @@ -514,6 +533,8 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) { layer->SetTransform(transform_); layer->SetScrollable(scrollable_); + layer->set_user_scrollable_horizontal(user_scrollable_horizontal_); + layer->set_user_scrollable_vertical(user_scrollable_vertical_); layer->SetScrollOffsetAndDelta( scroll_offset_, layer->ScrollDelta() - layer->sent_scroll_delta()); layer->SetSentScrollDelta(gfx::Vector2d()); diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index 2048840..4bd91da 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h @@ -374,6 +374,13 @@ class CC_EXPORT LayerImpl : LayerAnimationValueObserver { void SetScrollable(bool scrollable) { scrollable_ = scrollable; } bool scrollable() const { return scrollable_; } + void set_user_scrollable_horizontal(bool scrollable) { + user_scrollable_horizontal_ = scrollable; + } + void set_user_scrollable_vertical(bool scrollable) { + user_scrollable_vertical_ = scrollable; + } + void ApplySentScrollDeltasFromAbortedCommit(); void ApplyScrollDeltasSinceBeginFrame(); @@ -544,6 +551,8 @@ class CC_EXPORT LayerImpl : LayerAnimationValueObserver { bool scrollable_; bool should_scroll_on_main_thread_; bool have_wheel_event_handlers_; + bool user_scrollable_horizontal_; + bool user_scrollable_vertical_; Region non_fast_scrollable_region_; Region touch_event_handler_region_; SkColor background_color_; diff --git a/cc/layers/layer_impl_unittest.cc b/cc/layers/layer_impl_unittest.cc index 83cd346..2d3305c 100644 --- a/cc/layers/layer_impl_unittest.cc +++ b/cc/layers/layer_impl_unittest.cc @@ -547,5 +547,19 @@ TEST_F(LayerImplScrollTest, ApplySentScrollsWithAcceptingDelegate) { EXPECT_VECTOR_EQ(gfx::Vector2d(), layer()->sent_scroll_delta()); } +TEST_F(LayerImplScrollTest, ScrollUserUnscrollableLayer) { + gfx::Vector2d max_scroll_offset(50, 80); + gfx::Vector2d scroll_offset(10, 5); + gfx::Vector2dF scroll_delta(20.5f, 8.5f); + + layer()->set_user_scrollable_vertical(false); + layer()->SetMaxScrollOffset(max_scroll_offset); + layer()->SetScrollOffset(scroll_offset); + gfx::Vector2dF unscrolled = layer()->ScrollBy(scroll_delta); + + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 8.5f), unscrolled); + EXPECT_VECTOR_EQ(gfx::Vector2dF(30.5f, 5), layer()->TotalScrollOffset()); +} + } // namespace } // namespace cc diff --git a/cc/layers/layer_unittest.cc b/cc/layers/layer_unittest.cc index 3bbff6b..3a7a1c1 100644 --- a/cc/layers/layer_unittest.cc +++ b/cc/layers/layer_unittest.cc @@ -550,6 +550,7 @@ TEST_F(LayerTest, CheckPropertyChangeCausesCorrectBehavior) { EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetSublayerTransform( gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0))); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetScrollable(true)); + EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUserScrollable(true, false)); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetScrollOffset( gfx::Vector2d(10, 10))); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetShouldScrollOnMainThread(true)); diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index ad81d36..ebc1d83 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -1911,7 +1911,7 @@ static LayerImpl* NextScrollLayer(LayerImpl* layer) { LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( gfx::PointF device_viewport_point, InputHandler::ScrollInputType type, - LayerImpl* layer_impl, bool* scroll_on_main_thread) { + LayerImpl* layer_impl, bool* scroll_on_main_thread) const { DCHECK(scroll_on_main_thread); // Walk up the hierarchy and look for a scrollable layer. diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index d1e0682..555cb24 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h @@ -479,7 +479,7 @@ class CC_EXPORT LayerTreeHostImpl gfx::PointF device_viewport_point, InputHandler::ScrollInputType type, LayerImpl* layer_hit_by_point, - bool* scroll_on_main_thread); + bool* scroll_on_main_thread) const; float DeviceSpaceDistanceToLayer(gfx::PointF device_viewport_point, LayerImpl* layer_impl); void StartScrollbarAnimationRecursive(LayerImpl* layer, base::TimeTicks time); diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index d761c89..f635025 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc @@ -759,6 +759,61 @@ TEST_F(LayerTreeHostImplTest, ScrollVerticallyByPageReturnsCorrectValue) { gfx::Point(), SCROLL_BACKWARD)); } +TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) { + LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(200, 200)); + host_impl_->SetViewportSize(gfx::Size(100, 100)); + + gfx::Size overflow_size(400, 400); + ASSERT_EQ(1u, scroll_layer->children().size()); + LayerImpl* overflow = scroll_layer->children()[0]; + overflow->SetBounds(overflow_size); + overflow->SetContentBounds(overflow_size); + overflow->SetScrollable(true); + overflow->SetMaxScrollOffset(gfx::Vector2d(overflow_size.width(), + overflow_size.height())); + overflow->SetScrollOffset(gfx::Vector2d()); + overflow->SetPosition(gfx::PointF()); + overflow->SetAnchorPoint(gfx::PointF()); + + InitializeRendererAndDrawFrame(); + gfx::Point scroll_position(10, 10); + + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(scroll_position, InputHandler::Wheel)); + EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->TotalScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(), overflow->TotalScrollOffset()); + + gfx::Vector2dF scroll_delta(10, 10); + host_impl_->ScrollBy(scroll_position, scroll_delta); + host_impl_->ScrollEnd(); + EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->TotalScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow->TotalScrollOffset()); + + overflow->set_user_scrollable_horizontal(false); + + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(scroll_position, InputHandler::Wheel)); + EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->TotalScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow->TotalScrollOffset()); + + host_impl_->ScrollBy(scroll_position, scroll_delta); + host_impl_->ScrollEnd(); + EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer->TotalScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->TotalScrollOffset()); + + overflow->set_user_scrollable_vertical(false); + + EXPECT_EQ(InputHandler::ScrollStarted, + host_impl_->ScrollBegin(scroll_position, InputHandler::Wheel)); + EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer->TotalScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->TotalScrollOffset()); + + host_impl_->ScrollBy(scroll_position, scroll_delta); + host_impl_->ScrollEnd(); + EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 10), scroll_layer->TotalScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->TotalScrollOffset()); +} + TEST_F(LayerTreeHostImplTest, ClearRootRenderSurfaceAndHitTestTouchHandlerRegion) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); diff --git a/webkit/renderer/compositor_bindings/web_layer_impl.cc b/webkit/renderer/compositor_bindings/web_layer_impl.cc index 28b4964..fb9f72e 100644 --- a/webkit/renderer/compositor_bindings/web_layer_impl.cc +++ b/webkit/renderer/compositor_bindings/web_layer_impl.cc @@ -251,6 +251,18 @@ void WebLayerImpl::setScrollable(bool scrollable) { bool WebLayerImpl::scrollable() const { return layer_->scrollable(); } +void WebLayerImpl::setUserScrollable(bool horizontal, bool vertical) { + layer_->SetUserScrollable(horizontal, vertical); +} + +bool WebLayerImpl::userScrollableHorizontal() const { + return layer_->user_scrollable_horizontal(); +} + +bool WebLayerImpl::userScrollableVertical() const { + return layer_->user_scrollable_vertical(); +} + void WebLayerImpl::setHaveWheelEventHandlers(bool have_wheel_event_handlers) { layer_->SetHaveWheelEventHandlers(have_wheel_event_handlers); } diff --git a/webkit/renderer/compositor_bindings/web_layer_impl.h b/webkit/renderer/compositor_bindings/web_layer_impl.h index 8e4ab38..3a4a866 100644 --- a/webkit/renderer/compositor_bindings/web_layer_impl.h +++ b/webkit/renderer/compositor_bindings/web_layer_impl.h @@ -103,6 +103,9 @@ class WebLayerImpl : public WebKit::WebLayer, public cc::LayerClient { virtual WebKit::WebSize maxScrollPosition() const; virtual void setScrollable(bool scrollable); virtual bool scrollable() const; + virtual void setUserScrollable(bool horizontal, bool vertical); + virtual bool userScrollableHorizontal() const; + virtual bool userScrollableVertical() const; virtual void setHaveWheelEventHandlers(bool have_wheel_event_handlers); virtual bool haveWheelEventHandlers() const; virtual void setShouldScrollOnMainThread(bool scroll_on_main); |