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 d8b021a0ba9c3260278bea282a0dbf8cd8d011b3..1def91f9045d7c15c1cce995e0ca20d13e8a982d 100644 |
--- a/cc/trees/layer_tree_host_impl.cc |
+++ b/cc/trees/layer_tree_host_impl.cc |
@@ -387,11 +387,14 @@ void LayerTreeHostImpl::StartPageScaleAnimation(gfx::Vector2d target_offset, |
bool anchor_point, |
float page_scale, |
base::TimeDelta duration) { |
- if (!RootScrollLayer()) |
+ if (!InnerViewportScrollLayer()) |
return; |
+ // Should we attempt to set to OuterViewportScrollingLayer if it's available? |
+ active_tree_->SetCurrentlyScrollingLayer(InnerViewportScrollLayer()); |
+ |
gfx::Vector2dF scroll_total = |
- RootScrollLayer()->scroll_offset() + RootScrollLayer()->ScrollDelta(); |
+ active_tree_->TotalScrollOffset() + active_tree_->TotalScrollDelta(); |
gfx::SizeF scaled_scrollable_size = active_tree_->ScrollableSize(); |
gfx::SizeF viewport_size = UnscaledScrollableViewportSize(); |
@@ -1244,10 +1247,10 @@ CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() const { |
metadata.overdraw_bottom_height = overdraw_bottom_height_; |
} |
- if (!RootScrollLayer()) |
+ if (!InnerViewportScrollLayer()) |
return metadata; |
- metadata.root_scroll_offset = RootScrollLayer()->TotalScrollOffset(); |
+ metadata.root_scroll_offset = active_tree_->TotalScrollOffset(); |
return metadata; |
} |
@@ -1435,15 +1438,19 @@ void LayerTreeHostImpl::Readback(void* pixels, |
} |
bool LayerTreeHostImpl::HaveRootScrollLayer() const { |
- return !!RootScrollLayer(); |
+ return !!InnerViewportScrollLayer(); |
} |
LayerImpl* LayerTreeHostImpl::RootLayer() const { |
return active_tree_->root_layer(); |
} |
-LayerImpl* LayerTreeHostImpl::RootScrollLayer() const { |
- return active_tree_->RootScrollLayer(); |
+LayerImpl* LayerTreeHostImpl::InnerViewportScrollLayer() const { |
+ return active_tree_->InnerViewportScrollLayer(); |
+} |
+ |
+LayerImpl* LayerTreeHostImpl::OuterViewportScrollLayer() const { |
+ return active_tree_->OuterViewportScrollLayer(); |
} |
LayerImpl* LayerTreeHostImpl::CurrentlyScrollingLayer() const { |
@@ -1452,7 +1459,10 @@ LayerImpl* LayerTreeHostImpl::CurrentlyScrollingLayer() const { |
bool LayerTreeHostImpl::IsCurrentlyScrolling() const { |
return CurrentlyScrollingLayer() || |
- (RootScrollLayer() && RootScrollLayer()->IsExternalFlingActive()); |
+ (InnerViewportScrollLayer() && |
+ InnerViewportScrollLayer()->IsExternalFlingActive()) || |
+ (OuterViewportScrollLayer() && |
+ OuterViewportScrollLayer()->IsExternalFlingActive()); |
} |
// Content layers can be either directly scrollable or contained in an outer |
@@ -1826,8 +1836,6 @@ void LayerTreeHostImpl::SetViewportSize(gfx::Size device_viewport_size) { |
device_viewport_size_ = device_viewport_size; |
- UpdateMaxScrollOffset(); |
- |
if (renderer_) |
renderer_->ViewportChanged(); |
@@ -1840,7 +1848,6 @@ void LayerTreeHostImpl::SetOverdrawBottomHeight(float overdraw_bottom_height) { |
return; |
overdraw_bottom_height_ = overdraw_bottom_height; |
- UpdateMaxScrollOffset(); |
SetFullRootLayerDamage(); |
} |
@@ -1859,7 +1866,6 @@ void LayerTreeHostImpl::SetDeviceScaleFactor(float device_scale_factor) { |
if (renderer_) |
renderer_->ViewportChanged(); |
- UpdateMaxScrollOffset(); |
SetFullRootLayerDamage(); |
} |
@@ -1885,10 +1891,6 @@ const gfx::Transform& LayerTreeHostImpl::DrawTransform() const { |
return external_transform_; |
} |
-void LayerTreeHostImpl::UpdateMaxScrollOffset() { |
- active_tree_->UpdateMaxScrollOffset(); |
-} |
- |
void LayerTreeHostImpl::DidChangeTopControlsPosition() { |
client_->SetNeedsRedrawOnImplThread(); |
active_tree_->set_needs_update_draw_properties(); |
@@ -1948,7 +1950,9 @@ LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( |
if (!potentially_scrolling_layer_impl && top_controls_manager_ && |
top_controls_manager_->content_top_offset() != |
settings_.top_controls_height) { |
- potentially_scrolling_layer_impl = RootScrollLayer(); |
+ potentially_scrolling_layer_impl = |
+ OuterViewportScrollLayer() ? OuterViewportScrollLayer() |
+ : InnerViewportScrollLayer(); |
} |
return potentially_scrolling_layer_impl; |
@@ -1984,7 +1988,9 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin( |
// If we want to send a DidOverscroll for this scroll it can't be ignored. |
if (!potentially_scrolling_layer_impl && settings_.always_overscroll) |
- potentially_scrolling_layer_impl = RootScrollLayer(); |
+ potentially_scrolling_layer_impl = |
+ OuterViewportScrollLayer() ? OuterViewportScrollLayer() |
+ : InnerViewportScrollLayer(); |
if (potentially_scrolling_layer_impl) { |
active_tree_->SetCurrentlyScrollingLayer( |
@@ -2093,7 +2099,7 @@ bool LayerTreeHostImpl::ScrollBy(gfx::Point viewport_point, |
bool did_scroll_x = false; |
bool did_scroll_y = false; |
bool consume_by_top_controls = top_controls_manager_ && |
- (CurrentlyScrollingLayer() == RootScrollLayer() || scroll_delta.y() < 0); |
+ (CurrentlyScrollingLayer() == InnerViewportScrollLayer() || scroll_delta.y() < 0); |
last_scroll_did_bubble_ = false; |
for (LayerImpl* layer_impl = CurrentlyScrollingLayer(); |
@@ -2102,13 +2108,11 @@ bool LayerTreeHostImpl::ScrollBy(gfx::Point viewport_point, |
if (!layer_impl->scrollable()) |
continue; |
- if (layer_impl == RootScrollLayer()) { |
+ if (layer_impl == InnerViewportScrollLayer()) { |
// Only allow bubble scrolling when the scroll is in the direction to make |
// the top controls visible. |
- if (consume_by_top_controls && layer_impl == RootScrollLayer()) { |
+ if (consume_by_top_controls && layer_impl == InnerViewportScrollLayer()) |
pending_delta = top_controls_manager_->ScrollBy(pending_delta); |
- UpdateMaxScrollOffset(); |
- } |
// Track root layer deltas for reporting overscroll. |
unused_root_delta = pending_delta; |
} |
@@ -2146,7 +2150,8 @@ bool LayerTreeHostImpl::ScrollBy(gfx::Point viewport_point, |
break; |
} |
- if (layer_impl == RootScrollLayer()) |
+ if (layer_impl == InnerViewportScrollLayer() || |
+ layer_impl == OuterViewportScrollLayer()) |
unused_root_delta.Subtract(applied_delta); |
did_lock_scrolling_layer_ = true; |
@@ -2213,10 +2218,11 @@ bool LayerTreeHostImpl::ScrollVerticallyByPage(gfx::Point viewport_point, |
if (!layer_impl->scrollable()) |
continue; |
- if (!layer_impl->vertical_scrollbar_layer()) |
+ if (!layer_impl->HasScrollbar(VERTICAL)) |
continue; |
- float height = layer_impl->vertical_scrollbar_layer()->bounds().height(); |
+ // TODO(wjmaclean) make sure this is ok! |
+ float height = layer_impl->clip_height(); |
// These magical values match WebKit and are designed to scroll nearly the |
// entire visible content height but leave a bit of overlap. |
@@ -2272,8 +2278,8 @@ InputHandler::ScrollStatus LayerTreeHostImpl::FlingScrollBegin() { |
return ScrollIgnored; |
if (settings_.ignore_root_layer_flings && |
- active_tree_->CurrentlyScrollingLayer() == |
- active_tree_->RootScrollLayer()) { |
+ (active_tree_->CurrentlyScrollingLayer() == InnerViewportScrollLayer() || |
+ active_tree_->CurrentlyScrollingLayer() == OuterViewportScrollLayer())) { |
ClearCurrentlyScrollingLayer(); |
return ScrollIgnored; |
} |
@@ -2333,6 +2339,7 @@ void LayerTreeHostImpl::MouseMoveAt(gfx::Point viewport_point) { |
} |
bool scroll_on_main_thread = false; |
+ // wjm - what does FindScrollLayerForDeviceViewportPoint exactly do? |
LayerImpl* scroll_layer_impl = FindScrollLayerForDeviceViewportPoint( |
device_viewport_point, InputHandler::Gesture, layer_impl, |
&scroll_on_main_thread); |
@@ -2344,11 +2351,15 @@ void LayerTreeHostImpl::MouseMoveAt(gfx::Point viewport_point) { |
if (!animation_controller) |
return; |
- 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())); |
+ // TODO(wjmaclean) What to do with this? is it ok to choose from more than |
+ // two scrollbars? |
+ float distance_to_scrollbar = std::numeric_limits<float>::max(); |
+ for (LayerImpl::ScrollbarSet::iterator it = |
+ scroll_layer_impl->scrollbars()->begin(); |
+ it != scroll_layer_impl->scrollbars()->end(); |
+ ++it) |
+ distance_to_scrollbar = std::min(distance_to_scrollbar, |
+ DeviceSpaceDistanceToLayer(device_viewport_point, *it)); |
bool should_animate = animation_controller->DidMouseMoveNear( |
CurrentPhysicalTimeTicks(), distance_to_scrollbar / device_scale_factor_); |
@@ -2382,14 +2393,24 @@ void LayerTreeHostImpl::PinchGestureBegin() { |
previous_pinch_anchor_ = gfx::Point(); |
client_->RenewTreePriority(); |
pinch_gesture_end_should_clear_scrolling_layer_ = !CurrentlyScrollingLayer(); |
- active_tree_->SetCurrentlyScrollingLayer(RootScrollLayer()); |
+ if (active_tree_->OuterViewportScrollLayer()) { |
+ active_tree_->SetCurrentlyScrollingLayer( |
+ active_tree_->OuterViewportScrollLayer()); |
+ } else { |
+ active_tree_->SetCurrentlyScrollingLayer( |
+ active_tree_->InnerViewportScrollLayer()); |
+ } |
} |
void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta, |
gfx::Point anchor) { |
TRACE_EVENT0("cc", "LayerTreeHostImpl::PinchGestureUpdate"); |
- if (!RootScrollLayer()) |
+ LayerImpl* pinch_scroll_layer = CurrentlyScrollingLayer(); |
+ if (!pinch_scroll_layer) |
+ pinch_scroll_layer = InnerViewportScrollLayer(); |
+ |
+ if (!pinch_scroll_layer) |
return; |
// Keep the center-of-pinch anchor specified by (x, y) in a stable |
@@ -2406,9 +2427,43 @@ void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta, |
previous_pinch_anchor_ = anchor; |
move.Scale(1 / active_tree_->page_scale_factor()); |
- |
- RootScrollLayer()->ScrollBy(move); |
- |
+ // When shrinking the page, the current scroll offset of the inner viewport |
+ // scroll layer may need to be adjusted so that it doesn't exceed its maximum |
+ // at the new page scale factor. |
+ if (magnify_delta < 1.f) { |
+ // If clamping the inner viewport scroll offset causes a change, it should |
+ // be accounted for from the intended move. |
+ move -= InnerViewportScrollLayer()->ClampScrollToMaxScrollOffset(); |
+ } |
+ |
+ // We manually manage the bubbling behaviour here as it is different to that |
+ // implemented in LayerTreeHostImpl::ScrollBy(). Specifically: |
+ // 1) we want to explicit limit the bubbling to the outer/inner viewports, |
+ // 2) we don't want the directional limitations on the unused parts that |
+ // ScrollBy() implements, and |
+ // 3) pinching should not engage the top controls manager. |
+ gfx::Vector2dF unused = pinch_scroll_layer->ScrollBy(move); |
+ |
+ if (!unused.IsZero() && pinch_scroll_layer == OuterViewportScrollLayer()) { |
+ InnerViewportScrollLayer()->ScrollBy(unused); |
+ InnerViewportScrollLayer()->ClampScrollToMaxScrollOffset(); |
+ active_tree_->SetCurrentlyScrollingLayer( |
+ active_tree_->InnerViewportScrollLayer()); |
+ } |
+/* |
+ // Don't enable during unit tests. |
+ { |
+ gfx::Vector2d maxi = InnerViewportScrollLayer()->MaxScrollOffset(); |
+ gfx::Vector2d maxo = OuterViewportScrollLayer()->MaxScrollOffset(); |
+ gfx::Vector2dF offi = InnerViewportScrollLayer()->TotalScrollOffset(); |
+ gfx::Vector2dF offo = OuterViewportScrollLayer()->TotalScrollOffset(); |
+ fprintf(stderr, "wjm: Viewport summary: ovsl = (%f,%f) of (%d,%d), ivsl = (%f,%f) of (%d,%d)\n", |
+ offo.x(), offo.y(), |
+ maxo.x(), maxo.y(), |
+ offi.x(), offi.y(), |
+ maxi.x(), maxi.y()); |
+ } |
+*/ |
client_->SetNeedsCommitOnImplThread(); |
client_->SetNeedsRedrawOnImplThread(); |
client_->RenewTreePriority(); |
@@ -2457,12 +2512,11 @@ void LayerTreeHostImpl::SetFullRootLayerDamage() { |
} |
void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks time) { |
- if (!page_scale_animation_ || !RootScrollLayer()) |
+ if (!page_scale_animation_) |
return; |
double monotonic_time = (time - base::TimeTicks()).InSecondsF(); |
- gfx::Vector2dF scroll_total = RootScrollLayer()->scroll_offset() + |
- RootScrollLayer()->ScrollDelta(); |
+ gfx::Vector2dF scroll_total = active_tree_->TotalScrollOffset(); |
if (!page_scale_animation_->IsAnimationStarted()) |
page_scale_animation_->StartAnimation(monotonic_time); |
@@ -2473,7 +2527,7 @@ void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks time) { |
gfx::Vector2dF next_scroll = |
page_scale_animation_->ScrollOffsetAtTime(monotonic_time); |
- RootScrollLayer()->ScrollBy(next_scroll - scroll_total); |
+ ScrollBy(gfx::Point(), next_scroll - scroll_total); |
client_->SetNeedsRedrawOnImplThread(); |
if (page_scale_animation_->IsAnimationCompleteAtTime(monotonic_time)) { |
@@ -2484,14 +2538,14 @@ void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks time) { |
} |
void LayerTreeHostImpl::AnimateTopControls(base::TimeTicks time) { |
- if (!top_controls_manager_ || !RootScrollLayer()) |
+ if (!top_controls_manager_) |
return; |
gfx::Vector2dF scroll = top_controls_manager_->Animate(time); |
- UpdateMaxScrollOffset(); |
- if (RootScrollLayer()->TotalScrollOffset().y() == 0.f) |
+ if (active_tree_->TotalScrollOffset().y() == 0.f) |
return; |
- RootScrollLayer()->ScrollBy(gfx::ScaleVector2d( |
- scroll, 1.f / active_tree_->total_page_scale_factor())); |
+ ScrollBy(gfx::Point(), |
+ gfx::ScaleVector2d(scroll, |
+ 1.f / active_tree_->total_page_scale_factor())); |
} |
void LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time, |