| Index: cc/trees/layer_tree_host_impl.cc
|
| diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
|
| index 542143cea7af64c6cfc63ed93ba67bb66b77e5e8..ff3f99f803543494ce5d9547a7939281c8d49d7e 100644
|
| --- a/cc/trees/layer_tree_host_impl.cc
|
| +++ b/cc/trees/layer_tree_host_impl.cc
|
| @@ -78,6 +78,42 @@
|
| namespace cc {
|
| namespace {
|
|
|
| +// Small helper class that saves the current viewport location as the user sees
|
| +// it and resets to the same location.
|
| +class ViewportAnchor {
|
| + public:
|
| + ViewportAnchor(LayerImpl* inner_scroll, LayerImpl* outer_scroll)
|
| + : inner_(inner_scroll),
|
| + outer_(outer_scroll) {
|
| + viewport_in_content_coordinates_ = inner_->TotalScrollOffset();
|
| +
|
| + if (outer_)
|
| + viewport_in_content_coordinates_ += outer_->TotalScrollOffset();
|
| + }
|
| +
|
| + void ResetViewportToAnchoredPosition() {
|
| + DCHECK(outer_);
|
| +
|
| + inner_->ClampScrollToMaxScrollOffset();
|
| + outer_->ClampScrollToMaxScrollOffset();
|
| +
|
| + gfx::ScrollOffset viewport_location = inner_->TotalScrollOffset() +
|
| + outer_->TotalScrollOffset();
|
| +
|
| + gfx::Vector2dF delta =
|
| + viewport_in_content_coordinates_.DeltaFrom(viewport_location);
|
| +
|
| + delta = outer_->ScrollBy(delta);
|
| + inner_->ScrollBy(delta);
|
| + }
|
| +
|
| + private:
|
| + LayerImpl* inner_;
|
| + LayerImpl* outer_;
|
| + gfx::ScrollOffset viewport_in_content_coordinates_;
|
| +};
|
| +
|
| +
|
| void DidVisibilityChange(LayerTreeHostImpl* id, bool visible) {
|
| if (visible) {
|
| TRACE_EVENT_ASYNC_BEGIN1("webkit",
|
| @@ -1654,16 +1690,41 @@ void LayerTreeHostImpl::WillBeginImplFrame(const BeginFrameArgs& args) {
|
| begin_impl_frame_interval_ = args.interval;
|
| }
|
|
|
| -void LayerTreeHostImpl::UpdateInnerViewportContainerSize() {
|
| - LayerImpl* container_layer = active_tree_->InnerViewportContainerLayer();
|
| - if (!container_layer)
|
| +void LayerTreeHostImpl::UpdateViewportContainerSizes() {
|
| + LayerImpl* inner_container = active_tree_->InnerViewportContainerLayer();
|
| + LayerImpl* outer_container = active_tree_->OuterViewportContainerLayer();
|
| +
|
| + if (!inner_container || !top_controls_manager_)
|
| return;
|
|
|
| - if (top_controls_manager_) {
|
| - container_layer->SetBoundsDelta(
|
| - gfx::Vector2dF(0, active_tree_->top_controls_layout_height() -
|
| - active_tree_->total_top_controls_content_offset()));
|
| - }
|
| + ViewportAnchor anchor(InnerViewportScrollLayer(),
|
| + OuterViewportScrollLayer());
|
| +
|
| + // Adjust the inner viewport by shrinking/expanding the container to account
|
| + // for the change in top controls height since the last Resize from Blink.
|
| + inner_container->SetBoundsDelta(
|
| + gfx::Vector2dF(0, active_tree_->top_controls_layout_height() -
|
| + active_tree_->total_top_controls_content_offset()));
|
| +
|
| + if (!outer_container || outer_container->BoundsForScrolling().IsEmpty())
|
| + return;
|
| +
|
| + // Adjust the outer viewport container as well, since adjusting only the
|
| + // inner may cause its bounds to exceed those of the outer, causing scroll
|
| + // clamping. We adjust it so it maintains the same aspect ratio as the
|
| + // inner viewport.
|
| + float aspect_ratio = inner_container->BoundsForScrolling().width() /
|
| + inner_container->BoundsForScrolling().height();
|
| + float target_height = outer_container->BoundsForScrolling().width() /
|
| + aspect_ratio;
|
| + float current_outer_height = outer_container->BoundsForScrolling().height() -
|
| + outer_container->bounds_delta().y();
|
| + gfx::Vector2dF delta(0, target_height - current_outer_height);
|
| +
|
| + outer_container->SetBoundsDelta(delta);
|
| + active_tree_->InnerViewportScrollLayer()->SetBoundsDelta(delta);
|
| +
|
| + anchor.ResetViewportToAnchoredPosition();
|
| }
|
|
|
| void LayerTreeHostImpl::SetTopControlsLayoutHeight(float height) {
|
| @@ -1671,7 +1732,7 @@ void LayerTreeHostImpl::SetTopControlsLayoutHeight(float height) {
|
| return;
|
|
|
| active_tree_->set_top_controls_layout_height(height);
|
| - UpdateInnerViewportContainerSize();
|
| + UpdateViewportContainerSizes();
|
| SetFullRootLayerDamage();
|
| }
|
|
|
| @@ -1792,7 +1853,7 @@ void LayerTreeHostImpl::ActivateSyncTree() {
|
| top_controls_manager_->top_controls_height());
|
| }
|
|
|
| - UpdateInnerViewportContainerSize();
|
| + UpdateViewportContainerSizes();
|
| } else {
|
| active_tree_->ProcessUIResourceRequestQueue();
|
| }
|
| @@ -2155,7 +2216,7 @@ void LayerTreeHostImpl::SetViewportSize(const gfx::Size& device_viewport_size) {
|
|
|
| device_viewport_size_ = device_viewport_size;
|
|
|
| - UpdateInnerViewportContainerSize();
|
| + UpdateViewportContainerSizes();
|
| client_->OnCanDrawStateChanged(CanDraw());
|
| SetFullRootLayerDamage();
|
| active_tree_->set_needs_update_draw_properties();
|
| @@ -2206,7 +2267,7 @@ const gfx::Transform& LayerTreeHostImpl::DrawTransform() const {
|
| }
|
|
|
| void LayerTreeHostImpl::DidChangeTopControlsPosition() {
|
| - UpdateInnerViewportContainerSize();
|
| + UpdateViewportContainerSizes();
|
| SetNeedsRedraw();
|
| SetNeedsAnimate();
|
| active_tree_->set_needs_update_draw_properties();
|
| @@ -2502,6 +2563,31 @@ static gfx::Vector2dF ScrollLayerWithLocalDelta(LayerImpl* layer_impl,
|
| return layer_impl->ScrollDelta() - previous_delta;
|
| }
|
|
|
| +bool LayerTreeHostImpl::ShouldTopControlsConsumeScroll(
|
| + const gfx::Vector2dF& scroll_delta) const {
|
| + DCHECK(CurrentlyScrollingLayer());
|
| +
|
| + if (!top_controls_manager_)
|
| + return false;
|
| +
|
| + // Always consume if it's in the direction to show the top controls.
|
| + if (scroll_delta.y() < 0)
|
| + return true;
|
| +
|
| + if (CurrentlyScrollingLayer() != InnerViewportScrollLayer() &&
|
| + CurrentlyScrollingLayer() != OuterViewportScrollLayer())
|
| + return false;
|
| +
|
| + if (InnerViewportScrollLayer()->MaxScrollOffset().y() > 0)
|
| + return true;
|
| +
|
| + if (OuterViewportScrollLayer() &&
|
| + OuterViewportScrollLayer()->MaxScrollOffset().y() > 0)
|
| + return true;
|
| +
|
| + return false;
|
| +}
|
| +
|
| bool LayerTreeHostImpl::ScrollBy(const gfx::Point& viewport_point,
|
| const gfx::Vector2dF& scroll_delta) {
|
| TRACE_EVENT0("cc", "LayerTreeHostImpl::ScrollBy");
|
| @@ -2513,14 +2599,8 @@ bool LayerTreeHostImpl::ScrollBy(const gfx::Point& viewport_point,
|
| bool did_scroll_x = false;
|
| bool did_scroll_y = false;
|
| bool did_scroll_top_controls = false;
|
| - // TODO(wjmaclean) Should we guard against CurrentlyScrollingLayer() == 0
|
| - // here?
|
| - bool consume_by_top_controls =
|
| - top_controls_manager_ &&
|
| - (((CurrentlyScrollingLayer() == InnerViewportScrollLayer() ||
|
| - CurrentlyScrollingLayer() == OuterViewportScrollLayer()) &&
|
| - InnerViewportScrollLayer()->MaxScrollOffset().y() > 0) ||
|
| - scroll_delta.y() < 0);
|
| +
|
| + bool consume_by_top_controls = ShouldTopControlsConsumeScroll(scroll_delta);
|
|
|
| for (LayerImpl* layer_impl = CurrentlyScrollingLayer();
|
| layer_impl;
|
| @@ -2528,23 +2608,20 @@ bool LayerTreeHostImpl::ScrollBy(const gfx::Point& viewport_point,
|
| if (!layer_impl->scrollable())
|
| continue;
|
|
|
| - if (layer_impl == InnerViewportScrollLayer()) {
|
| - // Only allow bubble scrolling when the scroll is in the direction to make
|
| - // the top controls visible.
|
| - gfx::Vector2dF applied_delta;
|
| - gfx::Vector2dF excess_delta;
|
| + if (layer_impl == InnerViewportScrollLayer() ||
|
| + layer_impl == OuterViewportScrollLayer()) {
|
| if (consume_by_top_controls) {
|
| - excess_delta = top_controls_manager_->ScrollBy(pending_delta);
|
| - applied_delta = pending_delta - excess_delta;
|
| + gfx::Vector2dF excess_delta =
|
| + top_controls_manager_->ScrollBy(pending_delta);
|
| + gfx::Vector2dF applied_delta = pending_delta - excess_delta;
|
| pending_delta = excess_delta;
|
| // Force updating of vertical adjust values if needed.
|
| - if (applied_delta.y() != 0) {
|
| + if (applied_delta.y() != 0)
|
| did_scroll_top_controls = true;
|
| - layer_impl->ScrollbarParametersDidChange(false);
|
| - }
|
| }
|
| // Track root layer deltas for reporting overscroll.
|
| - unused_root_delta = pending_delta;
|
| + if (layer_impl == InnerViewportScrollLayer())
|
| + unused_root_delta = pending_delta;
|
| }
|
|
|
| gfx::Vector2dF applied_delta;
|
|
|