ScrollResult RootFrameViewport::handleWheel(const PlatformWheelEvent& event) { updateScrollAnimator(); ScrollableArea& primary = !m_invertScrollOrder ? layoutViewport() : visualViewport(); ScrollableArea& secondary = !m_invertScrollOrder ? visualViewport() : layoutViewport(); ScrollResult viewScrollResult = primary.handleWheel(event); // The visual viewport will only accept pixel scrolls. if (!event.canScroll() || event.granularity() == ScrollByPageWheelEvent) return viewScrollResult; // TODO(sataya.m) : The delta in PlatformWheelEvent is negative when scrolling the // wheel towards the user, so negate it to get the scroll delta that should be applied // to the page. unusedScrollDelta computed in the ScrollResult is also negative. Say // there is WheelEvent({0, -10} and page scroll by 2px and unusedScrollDelta computed // is {0, -8}. Due to which we have to negate the unusedScrollDelta to obtain the expected // animation.Please address http://crbug.com/504389. DoublePoint oldOffset = secondary.scrollPositionDouble(); DoublePoint locationDelta; if (viewScrollResult.didScroll()) { locationDelta = -DoublePoint(viewScrollResult.unusedScrollDeltaX, viewScrollResult.unusedScrollDeltaY); } else { if (event.railsMode() != PlatformEvent::RailsModeVertical) locationDelta.setX(-event.deltaX()); if (event.railsMode() != PlatformEvent::RailsModeHorizontal) locationDelta.setY(-event.deltaY()); } DoublePoint targetPosition = secondary.clampScrollPosition( secondary.scrollPositionDouble() + toDoubleSize(locationDelta)); secondary.setScrollPosition(targetPosition, UserScroll); DoublePoint usedLocationDelta(secondary.scrollPositionDouble() - oldOffset); bool didScrollX = viewScrollResult.didScrollX || usedLocationDelta.x(); bool didScrollY = viewScrollResult.didScrollY || usedLocationDelta.y(); return ScrollResult(didScrollX, didScrollY, -viewScrollResult.unusedScrollDeltaX - usedLocationDelta.x(), -viewScrollResult.unusedScrollDeltaY - usedLocationDelta.y()); }
void AutoscrollController::animate(double) { if (!m_autoscrollLayoutObject || !m_autoscrollLayoutObject->frame()) { stopAutoscroll(); return; } EventHandler& eventHandler = m_autoscrollLayoutObject->frame()->eventHandler(); IntSize offset = m_autoscrollLayoutObject->calculateAutoscrollDirection( eventHandler.lastKnownMousePosition()); IntPoint selectionPoint = eventHandler.lastKnownMousePosition() + offset; switch (m_autoscrollType) { case AutoscrollForDragAndDrop: if (WTF::monotonicallyIncreasingTime() - m_dragAndDropAutoscrollStartTime > autoscrollDelay) m_autoscrollLayoutObject->autoscroll( m_dragAndDropAutoscrollReferencePosition); break; case AutoscrollForSelection: if (!eventHandler.mousePressed()) { stopAutoscroll(); return; } eventHandler.updateSelectionForMouseDrag(); m_autoscrollLayoutObject->autoscroll(selectionPoint); break; case NoAutoscroll: break; case AutoscrollForMiddleClickCanStop: case AutoscrollForMiddleClick: DCHECK(RuntimeEnabledFeatures::middleClickAutoscrollEnabled()); if (!middleClickAutoscrollInProgress()) { stopAutoscroll(); return; } if (FrameView* view = m_autoscrollLayoutObject->frame()->view()) updateMiddleClickAutoscrollState(view, eventHandler.lastKnownMousePosition()); FloatSize delta = calculateAutoscrollDelta(); if (delta.isZero()) break; ScrollResult result = m_autoscrollLayoutObject->scroll(ScrollByPixel, delta); LayoutObject* layoutObject = m_autoscrollLayoutObject; while (!m_didLatchForMiddleClickAutoscroll && !result.didScroll()) { if (layoutObject->node() && layoutObject->node()->isDocumentNode()) { Element* owner = toDocument(layoutObject->node())->localOwner(); layoutObject = owner ? owner->layoutObject() : nullptr; } else { layoutObject = layoutObject->parent(); } if (!layoutObject) { break; } if (layoutObject && layoutObject->isBox() && toLayoutBox(layoutObject)->canBeScrolledAndHasScrollableArea()) result = toLayoutBox(layoutObject)->scroll(ScrollByPixel, delta); } if (result.didScroll()) { m_didLatchForMiddleClickAutoscroll = true; m_autoscrollLayoutObject = toLayoutBox(layoutObject); } break; } if (m_autoscrollType != NoAutoscroll && m_autoscrollLayoutObject) m_page->chromeClient().scheduleAnimation( m_autoscrollLayoutObject->frame()->view()); }