Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(732)

Unified Diff: Source/core/page/EventHandler.cpp

Issue 988823003: Use scroll customization primitives for touch scrolling (behind REF). (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/core/page/EventHandler.cpp
diff --git a/Source/core/page/EventHandler.cpp b/Source/core/page/EventHandler.cpp
index 7a28dc96a1595b2563160f4a90c81bb79951cbe9..ccb1aee635886cc043da7133f32c362e14fcdebc 100644
--- a/Source/core/page/EventHandler.cpp
+++ b/Source/core/page/EventHandler.cpp
@@ -80,6 +80,7 @@
#include "core/page/Page.h"
#include "core/page/SpatialNavigation.h"
#include "core/page/TouchAdjustment.h"
+#include "core/page/scrolling/ScrollState.h"
#include "core/svg/SVGDocumentExtensions.h"
#include "platform/PlatformGestureEvent.h"
#include "platform/PlatformKeyboardEvent.h"
@@ -195,6 +196,29 @@ static inline bool shouldRefetchEventTarget(const MouseEventWithHitTestResults&
return targetNode->isShadowRoot() && isHTMLInputElement(*toShadowRoot(targetNode)->host());
}
+void recomputeScrollChain(const LocalFrame& frame, const Node& scrollGestureHandlingNode,
+ WillBeHeapDeque<RefPtrWillBeMember<Element>>& scrollChain)
+{
+ scrollChain.clear();
+ bool rootLayerScrolls = frame.settings() && frame.settings()->rootLayerScrolls();
+ LayoutBox* curBox = scrollGestureHandlingNode.renderer()->enclosingBox();
+ bool addedDocumentElement = false;
+
+ while (curBox && (rootLayerScrolls || !curBox->isLayoutView())) {
+ Node* curNode = curBox->node();
+ curBox = curBox->containingBlock();
+ // FIXME: this should reject more elements.
+ if (!curNode || !curNode->isElementNode())
+ continue;
+ scrollChain.prepend(toElement(curNode));
+ if (curNode == frame.document()->documentElement())
+ addedDocumentElement = true;
+ }
+
+ if (!addedDocumentElement)
+ scrollChain.prepend(frame.document()->documentElement());
+}
+
EventHandler::EventHandler(LocalFrame* frame)
: m_frame(frame)
, m_mousePressed(false)
@@ -222,6 +246,7 @@ EventHandler::EventHandler(LocalFrame* frame)
, m_longTapShouldInvokeContextMenu(false)
, m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired)
, m_lastShowPressTimestamp(0)
+ , m_deltaConsumedForScrollSequence(false)
{
}
@@ -250,6 +275,7 @@ DEFINE_TRACE(EventHandler)
visitor->trace(m_scrollGestureHandlingNode);
visitor->trace(m_previousGestureScrolledNode);
visitor->trace(m_lastDeferredTapElement);
+ visitor->trace(m_currentScrollChain);
#endif
}
@@ -944,11 +970,31 @@ bool EventHandler::scroll(ScrollDirection direction, ScrollGranularity granulari
return false;
}
+void EventHandler::customizedScroll(ScrollState* scrollState, Node* startNode)
+{
+ Node* node = startNode;
+
+ if (!node)
+ node = m_frame->document()->focusedElement();
+
+ if (!node)
+ node = m_mousePressNode.get();
+
+ if (!node || !node->renderer())
+ return;
+
+ if (m_currentScrollChain.isEmpty() && m_scrollGestureHandlingNode.get())
+ recomputeScrollChain(*m_frame, *m_scrollGestureHandlingNode.get(), m_currentScrollChain);
+ scrollState->setScrollChain(m_currentScrollChain);
+ scrollState->distributeToScrollChainDescendant();
+}
+
bool EventHandler::bubblingScroll(ScrollDirection direction, ScrollGranularity granularity, Node* startingNode)
{
// The layout needs to be up to date to determine if we can scroll. We may be
// here because of an onLoad event, in which case the final layout hasn't been performed yet.
m_frame->document()->updateLayoutIgnorePendingStylesheets();
+ // FIXME: enable scroll customization in this case.
if (scroll(direction, granularity, startingNode))
return true;
LocalFrame* frame = m_frame;
@@ -2059,6 +2105,8 @@ void EventHandler::defaultWheelEventHandler(Node* startNode, WheelEvent* wheelEv
// Break up into two scrolls if we need to. Diagonal movement on
// a MacBook pro is an example of a 2-dimensional mouse wheel event (where both deltaX and deltaY can be set).
+
+ // FIXME: enable scroll customization in this case.
if (scroll(ScrollRight, granularity, startNode, &stopNode, wheelEvent->deltaX(), roundedIntPoint(wheelEvent->absoluteLocation())))
wheelEvent->setDefaultHandled();
@@ -2195,7 +2243,6 @@ bool EventHandler::handleGestureScrollEvent(const PlatformGestureEvent& gestureE
m_lastGestureScrollOverWidget = result.isOverWidget();
m_scrollGestureHandlingNode = eventTarget;
- m_previousGestureScrolledNode = nullptr;
if (!scrollbar)
scrollbar = result.scrollbar();
@@ -2448,11 +2495,19 @@ bool EventHandler::passScrollGestureEventToWidget(const PlatformGestureEvent& ge
bool EventHandler::handleGestureScrollEnd(const PlatformGestureEvent& gestureEvent) {
RefPtrWillBeRawPtr<Node> node = m_scrollGestureHandlingNode;
- clearGestureScrollNodes();
- if (node)
- passScrollGestureEventToWidget(gestureEvent, node->renderer());
+ if (node) {
+ if (passScrollGestureEventToWidget(gestureEvent, node->renderer()))
+ return false;
+ if (RuntimeEnabledFeatures::scrollCustomizationEnabled()) {
+ RefPtrWillBeRawPtr<ScrollState> scrollState = ScrollState::create(
+ 0, 0, 0, 0, 0, gestureEvent.inertial(), false, true, true);
+ customizedScroll(scrollState.get(), node.get());
+ }
+ }
+ clearGestureScrollNodes();
+ m_currentScrollChain.clear();
return false;
}
@@ -2471,24 +2526,30 @@ bool EventHandler::handleGestureScrollBegin(const PlatformGestureEvent& gestureE
while (m_scrollGestureHandlingNode && !m_scrollGestureHandlingNode->renderer())
m_scrollGestureHandlingNode = m_scrollGestureHandlingNode->parentOrShadowHostNode();
- if (!m_scrollGestureHandlingNode)
- return false;
+ if (!m_scrollGestureHandlingNode) {
+ if (RuntimeEnabledFeatures::scrollCustomizationEnabled())
+ m_scrollGestureHandlingNode = m_frame->document()->documentElement();
+ else
+ return false;
+ }
+ ASSERT(m_scrollGestureHandlingNode);
passScrollGestureEventToWidget(gestureEvent, m_scrollGestureHandlingNode->renderer());
+ if (!RuntimeEnabledFeatures::scrollCustomizationEnabled()) {
+ if (m_frame->isMainFrame())
+ m_frame->host()->topControls().scrollBegin();
+ return true;
+ }
- if (m_frame->isMainFrame())
- m_frame->host()->topControls().scrollBegin();
+ m_deltaConsumedForScrollSequence = false;
+ m_currentScrollChain.clear();
+ RefPtrWillBeRawPtr<ScrollState> scrollState = ScrollState::create(
+ 0, 0, 0, 0, 0, false, true, false, true);
+ customizedScroll(scrollState.get(), m_scrollGestureHandlingNode.get());
return true;
}
-static bool scrollAreaOnBothAxes(const FloatSize& delta, ScrollableArea& view)
-{
- bool scrolledHorizontal = view.scroll(ScrollLeft, ScrollByPrecisePixel, delta.width());
- bool scrolledVertical = view.scroll(ScrollUp, ScrollByPrecisePixel, delta.height());
- return scrolledHorizontal || scrolledVertical;
-}
-
bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gestureEvent)
{
ASSERT(gestureEvent.type() == PlatformEvent::GestureScrollUpdate);
@@ -2511,60 +2572,53 @@ bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gesture
if (passScrollGestureEventToWidget(gestureEvent, renderer)) {
if (gestureEvent.preventPropagation())
m_previousGestureScrolledNode = m_scrollGestureHandlingNode;
-
+ m_deltaConsumedForScrollSequence = true;
return true;
}
+ bool scrolled = false;
+ if (RuntimeEnabledFeatures::scrollCustomizationEnabled()) {
+ RefPtrWillBeRawPtr<ScrollState> scrollState = ScrollState::create(
+ gestureEvent.deltaX(), gestureEvent.deltaY(),
+ 0, gestureEvent.velocityX(), gestureEvent.velocityY(),
+ gestureEvent.inertial(), false, false, true,
+ !gestureEvent.preventPropagation(), m_deltaConsumedForScrollSequence);
+ // FIXME - check if its an element.
tdresser 2015/03/06 20:38:11 This needs to be done.
tdresser 2015/03/09 17:02:56 Done.
+ scrollState->setCurrentNativeScrollingElement(toElement(m_previousGestureScrolledNode.get()));
+ customizedScroll(scrollState.get(), node);
+ m_previousGestureScrolledNode = scrollState->currentNativeScrollingElement();
+ m_deltaConsumedForScrollSequence = scrollState->deltaConsumedForScrollSequence();
+
+ scrolled = scrollState->deltaX() != gestureEvent.deltaX()
+ || scrollState->deltaY() != gestureEvent.deltaY();
+ } else {
+ if (gestureEvent.preventPropagation())
+ stopNode = m_previousGestureScrolledNode.get();
- if (gestureEvent.preventPropagation())
- stopNode = m_previousGestureScrolledNode.get();
-
- // First try to scroll the closest scrollable LayoutBox ancestor of |node|.
- ScrollGranularity granularity = ScrollByPixel;
- bool horizontalScroll = scroll(ScrollLeft, granularity, node, &stopNode, delta.width());
- bool verticalScroll = scroll(ScrollUp, granularity, node, &stopNode, delta.height());
-
- if (gestureEvent.preventPropagation())
- m_previousGestureScrolledNode = stopNode;
+ // First try to scroll the closest scrollable LayoutBox ancestor of |node|.
+ ScrollGranularity granularity = ScrollByPixel;
+ scrolled = scroll(ScrollLeft, granularity, node, &stopNode, delta.width())
+ | scroll(ScrollUp, granularity, node, &stopNode, delta.height());
- if (horizontalScroll || verticalScroll) {
+ if (gestureEvent.preventPropagation())
+ m_previousGestureScrolledNode = stopNode;
+ }
+ if (scrolled) {
setFrameWasScrolledByUser();
return true;
}
}
- // If this is main frame, allow top controls to scroll first and update
- // delta accordingly
- bool consumed = false;
- if (m_frame->isMainFrame() && shouldTopControlsConsumeScroll(delta)) {
- FloatSize excessDelta = m_frame->host()->topControls().scrollBy(delta);
- consumed = excessDelta != delta;
- delta = excessDelta;
-
- if (delta.isZero())
- return consumed;
- }
+ if (RuntimeEnabledFeatures::scrollCustomizationEnabled())
+ return false;
// Try to scroll the frame view.
- FrameView* view = m_frame->view();
- if (!view)
- return consumed;
-
- if (scrollAreaOnBothAxes(delta, *view)) {
- setFrameWasScrolledByUser();
- return true;
- }
-
- // If this is the main frame and it didn't scroll, propagate up to the pinch viewport.
- if (!m_frame->settings()->pinchVirtualViewportEnabled() || !m_frame->isMainFrame())
- return consumed;
-
- if (scrollAreaOnBothAxes(delta, m_frame->host()->pinchViewport())) {
+ if (m_frame->applyScrollDelta(delta, false)) {
setFrameWasScrolledByUser();
return true;
}
- return consumed;
+ return false;
}
void EventHandler::clearGestureScrollNodes()
@@ -3394,6 +3448,7 @@ void EventHandler::defaultSpaceEventHandler(KeyboardEvent* event)
return;
ScrollDirection direction = event->shiftKey() ? ScrollBlockDirectionBackward : ScrollBlockDirectionForward;
+ // FIXME: enable scroll customization in this case.
if (scroll(direction, ScrollByPage)) {
event->setDefaultHandled();
return;
@@ -3911,18 +3966,4 @@ unsigned EventHandler::accessKeyModifiers()
#endif
}
-bool EventHandler::shouldTopControlsConsumeScroll(FloatSize scrollDelta) const
-{
- // Always consume if it's in the direction to show the top controls.
- if (scrollDelta.height() > 0)
- return true;
-
- // If it's in the direction to hide the top controls, only consume when the frame can also scroll.
- if (m_frame->view()->scrollPosition().y() < m_frame->view()->maximumScrollPosition().y())
- return true;
-
- return false;
-}
-
-
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698