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

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

Issue 850443002: Scroll Customization Prototype (Not for review, WIP) (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebase / cleanup / minor bug fixes Created 5 years, 10 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
« no previous file with comments | « Source/core/page/EventHandler.h ('k') | Source/core/page/scrolling/ScrollState.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/page/EventHandler.cpp
diff --git a/Source/core/page/EventHandler.cpp b/Source/core/page/EventHandler.cpp
index b8548bb6582db3a974f41d39422710f492c3ee7f..cd2f34027eed7121f923fb6735bf71868437409f 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,32 @@ static inline bool shouldRefetchEventTarget(const MouseEventWithHitTestResults&
return targetNode->isShadowRoot() && isHTMLInputElement(*toShadowRoot(targetNode)->host());
}
+void recomputeScrollChain(LocalFrame* const frame, Node* scrollGestureHandlingNode, WillBeHeapVector<RefPtrWillBeMember<Element>>& scrollChain)
+{
+ ASSERT(frame);
+ ASSERT(scrollGestureHandlingNode);
+ scrollChain.clear();
+ bool rootLayerScrolls = frame->settings() && frame->settings()->rootLayerScrolls();
+ LayoutBox* curBox = scrollGestureHandlingNode->renderer()->enclosingBox();
+
+ bool includesDocument = false;
+ while (curBox && (rootLayerScrolls || !curBox->isLayoutView())) {
+ Node* curNode = curBox->node();
+ curBox = curBox->containingBlock();
+
+ includesDocument = includesDocument || curNode == frame->document()->documentElement();
+
+ // FIXME: this should reject more elements.
+ if (!curNode || !curNode->isElementNode())
+ continue;
+ ASSERT(curNode->isElementNode());
+ scrollChain.prepend(toElement(curNode));
+ }
+
+ if (!includesDocument)
+ scrollChain.prepend(frame->document()->documentElement());
+}
+
EventHandler::EventHandler(LocalFrame* frame)
: m_frame(frame)
, m_mousePressed(false)
@@ -222,6 +249,7 @@ EventHandler::EventHandler(LocalFrame* frame)
, m_longTapShouldInvokeContextMenu(false)
, m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired)
, m_lastShowPressTimestamp(0)
+ , m_scrollLockedToElement(false)
{
}
@@ -250,6 +278,8 @@ DEFINE_TRACE(EventHandler)
visitor->trace(m_scrollGestureHandlingNode);
visitor->trace(m_previousGestureScrolledNode);
visitor->trace(m_lastDeferredTapElement);
+ visitor->trace(m_currentNativeScrollingElement);
+ visitor->trace(m_currentScrollChain);
#endif
}
@@ -943,11 +973,44 @@ bool EventHandler::scroll(ScrollDirection direction, ScrollGranularity granulari
return false;
}
+// FIXME: handle flipped direction (toPhysicalDirection) and granularity.
+bool 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 false;
+
+ if (!m_currentScrollChain.size() && m_scrollGestureHandlingNode.get())
+ recomputeScrollChain(m_frame, m_scrollGestureHandlingNode.get(), m_currentScrollChain);
+ scrollState->setScrollChain(m_currentScrollChain);
+
+ double deltaX = scrollState->deltaX();
+ double deltaY = scrollState->deltaY();
+ scrollState->distributeToScrollChainDescendant();
+ bool didScroll = deltaX != scrollState->deltaX() || deltaY != scrollState->deltaY();
+
+ if (didScroll) {
+ if (scrollState->fromUserInput())
+ setFrameWasScrolledByUser();
+ return true;
+ }
+
+ return false;
+}
+
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;
@@ -2062,6 +2125,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();
@@ -2454,9 +2519,19 @@ bool EventHandler::handleGestureScrollEnd(const PlatformGestureEvent& gestureEve
RefPtrWillBeRawPtr<Node> node = m_scrollGestureHandlingNode;
clearGestureScrollNodes();
- if (node)
- passScrollGestureEventToWidget(gestureEvent, node->renderer());
+ if (node) {
+ if (passScrollGestureEventToWidget(gestureEvent, node->renderer()))
+ return false;
+ if (RuntimeEnabledFeatures::scrollCustomizationEnabled()) {
+ ScrollState* scrollState = ScrollState::create(gestureEvent.deltaX(), gestureEvent.deltaY(),
+ 0, gestureEvent.velocityX(), gestureEvent.velocityY(), gestureEvent.inertial(), true, true);
+ customizedScroll(scrollState, node.get());
+ }
+ }
+ m_currentNativeScrollingElement = nullptr;
+ m_scrollLockedToElement = false;
+ m_currentScrollChain.clear();
return false;
}
@@ -2475,22 +2550,26 @@ 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;
+ }
passScrollGestureEventToWidget(gestureEvent, m_scrollGestureHandlingNode->renderer());
if (m_frame->isMainFrame())
m_frame->host()->topControls().scrollBegin();
- return true;
-}
+ if (!RuntimeEnabledFeatures::scrollCustomizationEnabled())
+ 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;
+ m_currentNativeScrollingElement = nullptr;
+ m_scrollLockedToElement = false;
+
+ recomputeScrollChain(m_frame, m_scrollGestureHandlingNode.get(), m_currentScrollChain);
+ return true;
}
bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gestureEvent)
@@ -2515,28 +2594,43 @@ bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gesture
if (passScrollGestureEventToWidget(gestureEvent, renderer)) {
if (gestureEvent.preventPropagation())
m_previousGestureScrolledNode = m_scrollGestureHandlingNode;
-
+ m_scrollLockedToElement = true;
return true;
}
-
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());
+ bool scrolled = false;
+ if (RuntimeEnabledFeatures::scrollCustomizationEnabled()) {
+ ScrollState* scrollState = ScrollState::create(gestureEvent.deltaX(), gestureEvent.deltaY(),
+ 0, gestureEvent.velocityX(), gestureEvent.velocityY(), gestureEvent.inertial(), false, true,
+ !gestureEvent.preventPropagation());
+ scrollState->setCurrentNativeScrollingElement(m_currentNativeScrollingElement.get());
+ scrollState->setScrollLockedToElement(m_scrollLockedToElement);
+ scrolled = customizedScroll(scrollState, node);
+ m_currentNativeScrollingElement = scrollState->currentNativeScrollingElement();
+ m_scrollLockedToElement = scrollState->scrollLockedToElement();
+ } else {
+ // 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 (gestureEvent.preventPropagation())
m_previousGestureScrolledNode = stopNode;
- if (horizontalScroll || verticalScroll) {
+ if (scrolled) {
setFrameWasScrolledByUser();
return true;
}
}
+
+ if (RuntimeEnabledFeatures::scrollCustomizationEnabled())
+ return false;
+
// If this is main frame, allow top controls to scroll first and update
// delta accordingly
bool consumed = false;
@@ -2554,16 +2648,7 @@ bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gesture
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->scrollByDelta(delta)) {
setFrameWasScrolledByUser();
return true;
}
@@ -3404,6 +3489,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;
« no previous file with comments | « Source/core/page/EventHandler.h ('k') | Source/core/page/scrolling/ScrollState.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698