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 398ef81895ae08bc199b823c30c9bd27861a3c29..1a1046959e062e7fb368f9f803a85404789395e3 100644 |
--- a/cc/trees/layer_tree_host_impl.cc |
+++ b/cc/trees/layer_tree_host_impl.cc |
@@ -469,16 +469,39 @@ bool LayerTreeHostImpl::HaveWheelEventHandlersAt( |
return layer_impl != NULL; |
} |
-bool LayerTreeHostImpl::HaveTouchEventHandlersAt( |
- const gfx::Point& viewport_point) { |
+static LayerImpl* NextScrollLayer(LayerImpl* layer) { |
+ if (LayerImpl* scroll_parent = layer->scroll_parent()) |
+ return scroll_parent; |
+ return layer->parent(); |
+} |
+static ScrollBlocksOn EffectiveScrollBlocksOn(LayerImpl* layer) { |
+ ScrollBlocksOn blocks = ScrollBlocksOnNone; |
+ for (; layer; layer = NextScrollLayer(layer)) { |
+ blocks |= layer->scroll_blocks_on(); |
+ } |
+ return blocks; |
+} |
+ |
+bool LayerTreeHostImpl::DoTouchEventsBlockScrollAt( |
+ const gfx::Point& viewport_point) { |
gfx::PointF device_viewport_point = |
gfx::ScalePoint(viewport_point, device_scale_factor_); |
+ // First check if scrolling at this point is required to block on any |
+ // touch event handlers. Note that we must start at the innermost layer |
+ // (as opposed to only the layer found to contain a touch handler region |
+ // below) to ensure all relevant scroll-blocks-on values are applied. |
LayerImpl* layer_impl = |
- active_tree_->FindLayerThatIsHitByPointInTouchHandlerRegion( |
- device_viewport_point); |
+ active_tree_->FindLayerThatIsHitByPoint(device_viewport_point); |
+ ScrollBlocksOn blocking = EffectiveScrollBlocksOn(layer_impl); |
+ if (!(blocking & ScrollBlocksOnStartTouch)) |
+ return false; |
+ // Now determine if there are actually any handlers at that point. |
+ // TODO(rbyers): Consider also honoring touch-action (crbug.com/347272). |
+ layer_impl = active_tree_->FindLayerThatIsHitByPointInTouchHandlerRegion( |
+ device_viewport_point); |
return layer_impl != NULL; |
} |
@@ -2255,12 +2278,6 @@ void LayerTreeHostImpl::BindToClient(InputHandlerClient* client) { |
input_handler_client_ = client; |
} |
-static LayerImpl* NextScrollLayer(LayerImpl* layer) { |
- if (LayerImpl* scroll_parent = layer->scroll_parent()) |
- return scroll_parent; |
- return layer->parent(); |
-} |
- |
LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( |
const gfx::PointF& device_viewport_point, |
InputHandler::ScrollInputType type, |
@@ -2269,12 +2286,15 @@ LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( |
bool* optional_has_ancestor_scroll_handler) const { |
DCHECK(scroll_on_main_thread); |
+ ScrollBlocksOn block_mode = EffectiveScrollBlocksOn(layer_impl); |
+ |
// Walk up the hierarchy and look for a scrollable layer. |
LayerImpl* potentially_scrolling_layer_impl = NULL; |
for (; layer_impl; layer_impl = NextScrollLayer(layer_impl)) { |
// The content layer can also block attempts to scroll outside the main |
// thread. |
- ScrollStatus status = layer_impl->TryScroll(device_viewport_point, type); |
+ ScrollStatus status = |
+ layer_impl->TryScroll(device_viewport_point, type, block_mode); |
if (status == ScrollOnMainThread) { |
*scroll_on_main_thread = true; |
return NULL; |
@@ -2284,7 +2304,8 @@ LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint( |
if (!scroll_layer_impl) |
continue; |
- status = scroll_layer_impl->TryScroll(device_viewport_point, type); |
+ status = |
+ scroll_layer_impl->TryScroll(device_viewport_point, type, block_mode); |
// If any layer wants to divert the scroll event to the main thread, abort. |
if (status == ScrollOnMainThread) { |
*scroll_on_main_thread = true; |