summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cc/layers/layer.cc14
-rw-r--r--cc/layers/layer.h8
-rw-r--r--cc/layers/layer_impl.cc23
-rw-r--r--cc/layers/layer_impl.h9
-rw-r--r--cc/layers/layer_impl_unittest.cc14
-rw-r--r--cc/layers/layer_unittest.cc1
-rw-r--r--cc/trees/layer_tree_host_impl.cc2
-rw-r--r--cc/trees/layer_tree_host_impl.h2
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc55
-rw-r--r--webkit/renderer/compositor_bindings/web_layer_impl.cc12
-rw-r--r--webkit/renderer/compositor_bindings/web_layer_impl.h3
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);