diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-01-20 13:40:20 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-01-22 12:41:23 +0000 |
commit | 7961cea6d1041e3e454dae6a1da660b453efd238 (patch) | |
tree | c0eeb4a9ff9ba32986289c1653d9608e53ccb444 /chromium/third_party/blink/renderer/core/input/scroll_manager.cc | |
parent | b7034d0803538058e5c9d904ef03cf5eab34f6ef (diff) | |
download | qtwebengine-chromium-7961cea6d1041e3e454dae6a1da660b453efd238.tar.gz |
BASELINE: Update Chromium to 78.0.3904.130
Change-Id: If185e0c0061b3437531c97c9c8c78f239352a68b
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/core/input/scroll_manager.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/core/input/scroll_manager.cc | 105 |
1 files changed, 82 insertions, 23 deletions
diff --git a/chromium/third_party/blink/renderer/core/input/scroll_manager.cc b/chromium/third_party/blink/renderer/core/input/scroll_manager.cc index 4c6de7e4e61..8408fb7ff18 100644 --- a/chromium/third_party/blink/renderer/core/input/scroll_manager.cc +++ b/chromium/third_party/blink/renderer/core/input/scroll_manager.cc @@ -101,6 +101,7 @@ void ScrollManager::ClearGestureScrollState() { last_gesture_scroll_over_embedded_content_view_ = false; scroll_gesture_handling_node_ = nullptr; previous_gesture_scrolled_node_ = nullptr; + last_scroll_delta_for_scroll_gesture_ = FloatSize(); delta_consumed_for_scroll_sequence_ = false; did_scroll_x_for_scroll_gesture_ = false; did_scroll_y_for_scroll_gesture_ = false; @@ -113,6 +114,15 @@ void ScrollManager::ClearGestureScrollState() { } } +Node* ScrollManager::GetScrollEventTarget() { + // Send the overscroll event to the node that scrolling is latched to which + // is either previously scrolled node or the last node in the scroll chain. + Node* scroll_target = previous_gesture_scrolled_node_; + if (!scroll_target && !current_scroll_chain_.IsEmpty()) + scroll_target = DOMNodeIds::NodeForId(current_scroll_chain_.front()); + return scroll_target; +} + void ScrollManager::StopAutoscroll() { if (AutoscrollController* controller = GetAutoscrollController()) controller->StopAutoscroll(); @@ -200,6 +210,17 @@ bool ScrollManager::CanScroll(const ScrollState& scroll_state, if (current_node.GetLayoutBox()->IsGlobalRootScroller()) return true; + // If this is the main LayoutView, and it's not the root scroller, that means + // we have a non-default root scroller on the page. In this case, attempts to + // scroll the LayoutView should cause panning of the visual viewport as well + // so ensure it gets added to the scroll chain. See LTHI::ApplyScroll for the + // equivalent behavior in CC. Node::NativeApplyScroll contains a special + // handler for this case. + if (current_node.GetLayoutBox()->IsLayoutView() && + current_node.GetDocument().GetFrame()->IsMainFrame()) { + return true; + } + ScrollableArea* scrollable_area = current_node.GetLayoutBox()->GetScrollableArea(); @@ -317,11 +338,12 @@ bool ScrollManager::LogicalScroll(ScrollDirection direction, } ScrollableArea::ScrollCallback callback; - if (RuntimeEnabledFeatures::UpdateHoverAtBeginFrameEnabled()) { + if (RuntimeEnabledFeatures::UpdateHoverAtBeginFrameEnabled() || + RuntimeEnabledFeatures::OverscrollCustomizationEnabled()) { callback = ScrollableArea::ScrollCallback(WTF::Bind( [](WeakPersistent<ScrollableArea> area) { if (area) - area->MarkHoverStateDirty(); + area->OnScrollFinished(); }, WrapWeakPersistent(scrollable_area))); } @@ -478,8 +500,21 @@ WebInputEventResult ScrollManager::HandleGestureScrollBegin( scroll_state_data->delta_consumed_for_scroll_sequence = delta_consumed_for_scroll_sequence_; ScrollState* scroll_state = ScrollState::Create(std::move(scroll_state_data)); - RecomputeScrollChain(*scroll_gesture_handling_node_.Get(), *scroll_state, - current_scroll_chain_); + // For middle click autoscroll, only scrollable area for + // |scroll_gesture_handling_node_| should receive and handle all scroll + // events. It should not bubble up to the ancestor. + if (gesture_event.SourceDevice() == WebGestureDevice::kSyntheticAutoscroll) { + LayoutBox* scrollable = LayoutBox::FindAutoscrollable( + scroll_gesture_handling_node_->GetLayoutObject(), + /*is_middle_click_autoscroll*/ true); + if (scrollable) { + Node* scrollable_node = scrollable->GetNode(); + current_scroll_chain_.push_back(DOMNodeIds::IdForNode(scrollable_node)); + } + } else { + RecomputeScrollChain(*scroll_gesture_handling_node_.Get(), *scroll_state, + current_scroll_chain_); + } TRACE_EVENT_INSTANT1("input", "Computed Scroll Chain", TRACE_EVENT_SCOPE_THREAD, "length", @@ -607,6 +642,8 @@ WebInputEventResult ScrollManager::HandleGestureScrollUpdate( delta_consumed_for_scroll_sequence_ = scroll_state->DeltaConsumedForScrollSequence(); + last_scroll_delta_for_scroll_gesture_ = delta; + bool did_scroll_x = scroll_state->deltaX() != delta.Width(); bool did_scroll_y = scroll_state->deltaY() != delta.Height(); @@ -625,13 +662,7 @@ WebInputEventResult ScrollManager::HandleGestureScrollUpdate( return WebInputEventResult::kHandledSystem; if (RuntimeEnabledFeatures::OverscrollCustomizationEnabled()) { - // Send the overscroll event to the node that scrolling is latched to which - // is either previously scrolled node or the last node in the scroll chain. - Node* overscroll_target = previous_gesture_scrolled_node_; - if (!overscroll_target && !current_scroll_chain_.IsEmpty()) - overscroll_target = DOMNodeIds::NodeForId(current_scroll_chain_.front()); - - if (overscroll_target) { + if (Node* overscroll_target = GetScrollEventTarget()) { overscroll_target->GetDocument().EnqueueOverscrollEventForNode( overscroll_target, delta.Width(), delta.Height()); } @@ -689,19 +720,13 @@ WebInputEventResult ScrollManager::HandleGestureScrollEnd( ScrollState* scroll_state = ScrollState::Create(std::move(scroll_state_data)); CustomizedScroll(*scroll_state); - snap_at_gesture_scroll_end = SnapAtGestureScrollEnd(); + + snap_at_gesture_scroll_end = SnapAtGestureScrollEnd(gesture_event); NotifyScrollPhaseEndForCustomizedScroll(); - if (RuntimeEnabledFeatures::OverscrollCustomizationEnabled()) { - // Send the scrollend event to the node that scrolling is latched to - // which is either previously scrolled node or the last node in the - // scroll chain. - DCHECK(!current_scroll_chain_.IsEmpty()); - if (previous_gesture_scrolled_node_) { - previous_gesture_scrolled_node_->GetDocument() - .EnqueueScrollEndEventForNode(previous_gesture_scrolled_node_); - } else if (Node* scroll_end_target = - DOMNodeIds::NodeForId(current_scroll_chain_.front())) { + if (RuntimeEnabledFeatures::OverscrollCustomizationEnabled() && + !snap_at_gesture_scroll_end) { + if (Node* scroll_end_target = GetScrollEventTarget()) { scroll_end_target->GetDocument().EnqueueScrollEndEventForNode( scroll_end_target); } @@ -727,7 +752,11 @@ LayoutBox* ScrollManager::LayoutBoxForSnapping() const { return previous_gesture_scrolled_node_->GetLayoutBox(); } -bool ScrollManager::SnapAtGestureScrollEnd() { +ScrollOffset GetScrollDirection(FloatSize delta) { + return delta.ShrunkTo(FloatSize(1, 1)).ExpandedTo(FloatSize(-1, -1)); +} + +bool ScrollManager::SnapAtGestureScrollEnd(const WebGestureEvent& end_event) { if (!previous_gesture_scrolled_node_ || (!did_scroll_x_for_scroll_gesture_ && !did_scroll_y_for_scroll_gesture_)) return false; @@ -737,6 +766,30 @@ bool ScrollManager::SnapAtGestureScrollEnd() { if (!snap_coordinator || !layout_box) return false; + bool is_mouse_wheel = + end_event.SourceDevice() == WebGestureDevice::kTouchpad && + end_event.data.scroll_end.delta_units != + ScrollGranularity::kScrollByPrecisePixel; + + // Treat mouse wheel scrolls as direction only scroll with its last scroll + // delta amout. This means each wheel tick will prefer the next snap position + // in the given direction. This leads to a much better UX for wheels. + // + // Precise wheel and trackpads continue to be treated similar as end position + // scrolling. + if (is_mouse_wheel && !last_scroll_delta_for_scroll_gesture_.IsZero()) { + // TODO(majidvp): Currently DirectionStrategy uses current offset + delta as + // the intended offset and chooses snap offset closest to that intended + // offset. In this case, this is not correct because we are already at the + // intended position. DirectionStategy should be updated to use current + // offset as intended position. This requires changing how we snap in + // |ScrollManager::LogicalScroll()|. For now use a unit scroll offset to + // limit the miscalculation to 1px. + ScrollOffset scroll_direction = + GetScrollDirection(last_scroll_delta_for_scroll_gesture_); + return snap_coordinator->SnapForDirection(*layout_box, scroll_direction); + } + return snap_coordinator->SnapAtCurrentPosition( *layout_box, did_scroll_x_for_scroll_gesture_, did_scroll_y_for_scroll_gesture_); @@ -795,6 +848,12 @@ gfx::Vector2dF ScrollManager::ScrollByForSnapFling( } void ScrollManager::ScrollEndForSnapFling() { + if (RuntimeEnabledFeatures::OverscrollCustomizationEnabled()) { + if (Node* scroll_end_target = GetScrollEventTarget()) { + scroll_end_target->GetDocument().EnqueueScrollEndEventForNode( + scroll_end_target); + } + } if (current_scroll_chain_.IsEmpty()) { NotifyScrollPhaseEndForCustomizedScroll(); ClearGestureScrollState(); |