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

Unified Diff: third_party/WebKit/Source/core/input/EventHandler.cpp

Issue 2137113002: Create GestureManager class and move related logic (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix the nits Created 4 years, 5 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: third_party/WebKit/Source/core/input/EventHandler.cpp
diff --git a/third_party/WebKit/Source/core/input/EventHandler.cpp b/third_party/WebKit/Source/core/input/EventHandler.cpp
index 8c2790eee6eed70c0a7c97cedfb7a49c002fa6dd..93a00803e5ff3f0b9a4c7a456a20ee03e33a042c 100644
--- a/third_party/WebKit/Source/core/input/EventHandler.cpp
+++ b/third_party/WebKit/Source/core/input/EventHandler.cpp
@@ -194,10 +194,8 @@ EventHandler::EventHandler(LocalFrame* frame)
, m_pointerEventManager(frame)
, m_scrollManager(frame)
, m_keyboardEventManager(frame, &m_scrollManager)
- , m_longTapShouldInvokeContextMenu(false)
+ , m_gestureManager(frame, &m_scrollManager, &m_pointerEventManager, m_selectionController)
, m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired)
- , m_lastShowPressTimestamp(0)
- , m_suppressMouseEventsFromGestures(false)
{
}
@@ -222,6 +220,7 @@ DEFINE_TRACE(EventHandler)
visitor->trace(m_pointerEventManager);
visitor->trace(m_scrollManager);
visitor->trace(m_keyboardEventManager);
+ visitor->trace(m_gestureManager);
}
DragState& EventHandler::dragState()
@@ -254,18 +253,16 @@ void EventHandler::clear()
m_capturingMouseEventsNode = nullptr;
m_pointerEventManager.clear();
m_scrollManager.clear();
+ m_gestureManager.clear();
m_mouseDownMayStartDrag = false;
- m_lastShowPressTimestamp = 0;
m_lastDeferredTapElement = nullptr;
m_eventHandlerWillResetCapturingMouseEventsNode = false;
m_mouseDownMayStartAutoscroll = false;
m_svgPan = false;
m_mouseDownPos = IntPoint();
m_mouseDownTimestamp = 0;
- m_longTapShouldInvokeContextMenu = false;
m_dragStartPos = LayoutPoint();
m_mouseDown = PlatformMouseEvent();
- m_suppressMouseEventsFromGestures = false;
}
WebInputEventResult EventHandler::mergeEventResult(
@@ -1086,7 +1083,7 @@ void EventHandler::invalidateClick()
m_clickNode = nullptr;
}
-static ContainerNode* parentForClickEvent(const Node& node)
+ContainerNode* EventHandler::parentForClickEvent(const Node& node)
{
// IE doesn't dispatch click events for mousedown/mouseup events across form
// controls.
@@ -1510,6 +1507,11 @@ WebInputEventResult EventHandler::updatePointerTargetAndDispatchEvents(const Ato
lastNodeUnderMouse);
}
+void EventHandler::setClickNode(Node* node)
+{
+ m_clickNode = node;
+}
+
WebInputEventResult EventHandler::handleMouseFocus(const MouseEventWithHitTestResults& targetedEvent, InputDeviceCapabilities* sourceCapabilities)
{
// If clicking on a frame scrollbar, do not mess up with content focus.
@@ -1647,26 +1649,6 @@ WebInputEventResult EventHandler::handleWheelEvent(const PlatformWheelEvent& eve
return WebInputEventResult::NotHandled;
}
-WebInputEventResult EventHandler::handleGestureShowPress()
-{
- m_lastShowPressTimestamp = WTF::monotonicallyIncreasingTime();
-
- FrameView* view = m_frame->view();
- if (!view)
- return WebInputEventResult::NotHandled;
- if (ScrollAnimatorBase* scrollAnimator = view->existingScrollAnimator())
- scrollAnimator->cancelAnimation();
- const FrameView::ScrollableAreaSet* areas = view->scrollableAreas();
- if (!areas)
- return WebInputEventResult::NotHandled;
- for (const ScrollableArea* scrollableArea : *areas) {
- ScrollAnimatorBase* animator = scrollableArea->existingScrollAnimator();
- if (animator)
- animator->cancelAnimation();
- }
- return WebInputEventResult::NotHandled;
-}
-
WebInputEventResult EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent)
{
// Propagation to inner frames is handled below this function.
@@ -1704,54 +1686,12 @@ WebInputEventResult EventHandler::handleGestureEvent(const GestureEventWithHitTe
return innerFrame->eventHandler().handleGestureEventInFrame(targetedEvent);
// No hit test result, handle in root instance. Perhaps we should just return false instead?
- return handleGestureEventInFrame(targetedEvent);
+ return m_gestureManager.handleGestureEventInFrame(targetedEvent);
}
WebInputEventResult EventHandler::handleGestureEventInFrame(const GestureEventWithHitTestResults& targetedEvent)
{
- ASSERT(!targetedEvent.event().isScrollEvent());
-
- Node* eventTarget = targetedEvent.hitTestResult().innerNode();
- const PlatformGestureEvent& gestureEvent = targetedEvent.event();
-
- if (m_scrollManager.canHandleGestureEvent(targetedEvent))
- return WebInputEventResult::HandledSuppressed;
-
- if (eventTarget) {
- GestureEvent* gestureDomEvent = GestureEvent::create(eventTarget->document().domWindow(), gestureEvent);
- if (gestureDomEvent) {
- DispatchEventResult gestureDomEventResult = eventTarget->dispatchEvent(gestureDomEvent);
- if (gestureDomEventResult != DispatchEventResult::NotCanceled) {
- ASSERT(gestureDomEventResult != DispatchEventResult::CanceledByEventHandler);
- return toWebInputEventResult(gestureDomEventResult);
- }
- }
- }
-
- switch (gestureEvent.type()) {
- case PlatformEvent::GestureTapDown:
- return handleGestureTapDown(targetedEvent);
- case PlatformEvent::GestureTap:
- return handleGestureTap(targetedEvent);
- case PlatformEvent::GestureShowPress:
- return handleGestureShowPress();
- case PlatformEvent::GestureLongPress:
- return handleGestureLongPress(targetedEvent);
- case PlatformEvent::GestureLongTap:
- return handleGestureLongTap(targetedEvent);
- case PlatformEvent::GestureTwoFingerTap:
- return sendContextMenuEventForGesture(targetedEvent);
- case PlatformEvent::GesturePinchBegin:
- case PlatformEvent::GesturePinchEnd:
- case PlatformEvent::GesturePinchUpdate:
- case PlatformEvent::GestureTapDownCancel:
- case PlatformEvent::GestureTapUnconfirmed:
- break;
- default:
- ASSERT_NOT_REACHED();
- }
-
- return WebInputEventResult::NotHandled;
+ return m_gestureManager.handleGestureEventInFrame(targetedEvent);
}
WebInputEventResult EventHandler::handleGestureScrollEvent(const PlatformGestureEvent& gestureEvent)
@@ -1761,188 +1701,6 @@ WebInputEventResult EventHandler::handleGestureScrollEvent(const PlatformGesture
return m_scrollManager.handleGestureScrollEvent(gestureEvent);
}
-WebInputEventResult EventHandler::handleGestureTapDown(const GestureEventWithHitTestResults& targetedEvent)
-{
- m_suppressMouseEventsFromGestures =
- m_pointerEventManager.primaryPointerdownCanceled(targetedEvent.event().uniqueTouchEventId());
- return WebInputEventResult::NotHandled;
-}
-
-WebInputEventResult EventHandler::handleGestureTap(const GestureEventWithHitTestResults& targetedEvent)
-{
- FrameView* frameView(m_frame->view());
- const PlatformGestureEvent& gestureEvent = targetedEvent.event();
- HitTestRequest::HitTestRequestType hitType = getHitTypeForGestureType(gestureEvent.type());
- uint64_t preDispatchDomTreeVersion = m_frame->document()->domTreeVersion();
- uint64_t preDispatchStyleVersion = m_frame->document()->styleVersion();
-
- UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
-
- HitTestResult currentHitTest = targetedEvent.hitTestResult();
-
- // We use the adjusted position so the application isn't surprised to see a event with
- // co-ordinates outside the target's bounds.
- IntPoint adjustedPoint = frameView->rootFrameToContents(gestureEvent.position());
-
- const unsigned modifiers = gestureEvent.getModifiers();
-
- if (!m_suppressMouseEventsFromGestures) {
- PlatformMouseEvent fakeMouseMove(gestureEvent.position(), gestureEvent.globalPosition(),
- NoButton, PlatformEvent::MouseMoved, /* clickCount */ 0,
- static_cast<PlatformEvent::Modifiers>(modifiers),
- PlatformMouseEvent::FromTouch, gestureEvent.timestamp(), WebPointerProperties::PointerType::Mouse);
- dispatchMouseEvent(EventTypeNames::mousemove, currentHitTest.innerNode(), 0, fakeMouseMove);
- }
-
- // Do a new hit-test in case the mousemove event changed the DOM.
- // Note that if the original hit test wasn't over an element (eg. was over a scrollbar) we
- // don't want to re-hit-test because it may be in the wrong frame (and there's no way the page
- // could have seen the event anyway).
- // Also note that the position of the frame may have changed, so we need to recompute the content
- // co-ordinates (updating layout/style as hitTestResultAtPoint normally would).
- // FIXME: Use a hit-test cache to avoid unnecessary hit tests. http://crbug.com/398920
- if (currentHitTest.innerNode()) {
- LocalFrame* mainFrame = m_frame->localFrameRoot();
- if (mainFrame && mainFrame->view())
- mainFrame->view()->updateLifecycleToCompositingCleanPlusScrolling();
- adjustedPoint = frameView->rootFrameToContents(gestureEvent.position());
- currentHitTest = hitTestResultInFrame(m_frame, adjustedPoint, hitType);
- }
- m_clickNode = currentHitTest.innerNode();
-
- // Capture data for showUnhandledTapUIIfNeeded.
- Node* tappedNode = m_clickNode;
- IntPoint tappedPosition = gestureEvent.position();
-
- if (m_clickNode && m_clickNode->isTextNode())
- m_clickNode = FlatTreeTraversal::parent(*m_clickNode);
-
- PlatformMouseEvent fakeMouseDown(gestureEvent.position(), gestureEvent.globalPosition(),
- LeftButton, PlatformEvent::MousePressed, gestureEvent.tapCount(),
- static_cast<PlatformEvent::Modifiers>(modifiers | PlatformEvent::LeftButtonDown),
- PlatformMouseEvent::FromTouch, gestureEvent.timestamp(), WebPointerProperties::PointerType::Mouse);
-
- // TODO(mustaq): We suppress MEs plus all it's side effects. What would that
- // mean for for TEs? What's the right balance here? crbug.com/617255
- WebInputEventResult mouseDownEventResult = WebInputEventResult::HandledSuppressed;
- if (!m_suppressMouseEventsFromGestures) {
- mouseDownEventResult = dispatchMouseEvent(EventTypeNames::mousedown, currentHitTest.innerNode(), gestureEvent.tapCount(), fakeMouseDown);
- selectionController().initializeSelectionState();
- if (mouseDownEventResult == WebInputEventResult::NotHandled)
- mouseDownEventResult = handleMouseFocus(MouseEventWithHitTestResults(fakeMouseDown, currentHitTest), InputDeviceCapabilities::firesTouchEventsSourceCapabilities());
- if (mouseDownEventResult == WebInputEventResult::NotHandled)
- mouseDownEventResult = handleMousePressEvent(MouseEventWithHitTestResults(fakeMouseDown, currentHitTest));
- }
-
- if (currentHitTest.innerNode()) {
- ASSERT(gestureEvent.type() == PlatformEvent::GestureTap);
- HitTestResult result = currentHitTest;
- result.setToShadowHostIfInUserAgentShadowRoot();
- m_frame->chromeClient().onMouseDown(result.innerNode());
- }
-
- // FIXME: Use a hit-test cache to avoid unnecessary hit tests. http://crbug.com/398920
- if (currentHitTest.innerNode()) {
- LocalFrame* mainFrame = m_frame->localFrameRoot();
- if (mainFrame && mainFrame->view())
- mainFrame->view()->updateAllLifecyclePhases();
- adjustedPoint = frameView->rootFrameToContents(gestureEvent.position());
- currentHitTest = hitTestResultInFrame(m_frame, adjustedPoint, hitType);
- }
-
- PlatformMouseEvent fakeMouseUp(gestureEvent.position(), gestureEvent.globalPosition(),
- LeftButton, PlatformEvent::MouseReleased, gestureEvent.tapCount(),
- static_cast<PlatformEvent::Modifiers>(modifiers),
- PlatformMouseEvent::FromTouch, gestureEvent.timestamp(), WebPointerProperties::PointerType::Mouse);
- WebInputEventResult mouseUpEventResult = m_suppressMouseEventsFromGestures
- ? WebInputEventResult::HandledSuppressed
- : dispatchMouseEvent(EventTypeNames::mouseup, currentHitTest.innerNode(), gestureEvent.tapCount(), fakeMouseUp);
-
- WebInputEventResult clickEventResult = WebInputEventResult::NotHandled;
- if (m_clickNode) {
- if (currentHitTest.innerNode()) {
- // Updates distribution because a mouseup (or mousedown) event listener can make the
- // tree dirty at dispatchMouseEvent() invocation above.
- // Unless distribution is updated, commonAncestor would hit ASSERT.
- // Both m_clickNode and currentHitTest.innerNode()) don't need to be updated
- // because commonAncestor() will exit early if their documents are different.
- m_clickNode->updateDistribution();
- Node* clickTargetNode = currentHitTest.innerNode()->commonAncestor(*m_clickNode, parentForClickEvent);
- clickEventResult = dispatchMouseEvent(EventTypeNames::click, clickTargetNode, gestureEvent.tapCount(), fakeMouseUp);
- }
- m_clickNode = nullptr;
- }
-
- if (mouseUpEventResult == WebInputEventResult::NotHandled)
- mouseUpEventResult = handleMouseReleaseEvent(MouseEventWithHitTestResults(fakeMouseUp, currentHitTest));
- clearDragHeuristicState();
-
- WebInputEventResult eventResult = mergeEventResult(mergeEventResult(mouseDownEventResult, mouseUpEventResult), clickEventResult);
- if (eventResult == WebInputEventResult::NotHandled && tappedNode && m_frame->page()) {
- bool domTreeChanged = preDispatchDomTreeVersion != m_frame->document()->domTreeVersion();
- bool styleChanged = preDispatchStyleVersion != m_frame->document()->styleVersion();
-
- IntPoint tappedPositionInViewport = frameHost()->visualViewport().rootFrameToViewport(tappedPosition);
- m_frame->chromeClient().showUnhandledTapUIIfNeeded(tappedPositionInViewport, tappedNode, domTreeChanged || styleChanged);
- }
- return eventResult;
-}
-
-WebInputEventResult EventHandler::handleGestureLongPress(const GestureEventWithHitTestResults& targetedEvent)
-{
- const PlatformGestureEvent& gestureEvent = targetedEvent.event();
- IntPoint adjustedPoint = gestureEvent.position();
-
- unsigned modifiers = gestureEvent.getModifiers();
-
- // FIXME: Ideally we should try to remove the extra mouse-specific hit-tests here (re-using the
- // supplied HitTestResult), but that will require some overhaul of the touch drag-and-drop code
- // and LongPress is such a special scenario that it's unlikely to matter much in practice.
-
- m_longTapShouldInvokeContextMenu = false;
- if (m_frame->settings() && m_frame->settings()->touchDragDropEnabled() && m_frame->view()) {
- // TODO(mustaq): Suppressing long-tap MouseEvents could break
- // drag-drop. Will do separately because of the risk. crbug.com/606938.
- PlatformMouseEvent mouseDownEvent(adjustedPoint, gestureEvent.globalPosition(), LeftButton, PlatformEvent::MousePressed, 1,
- static_cast<PlatformEvent::Modifiers>(modifiers | PlatformEvent::LeftButtonDown),
- PlatformMouseEvent::FromTouch, WTF::monotonicallyIncreasingTime(), WebPointerProperties::PointerType::Mouse);
- m_mouseDown = mouseDownEvent;
-
- PlatformMouseEvent mouseDragEvent(adjustedPoint, gestureEvent.globalPosition(), LeftButton, PlatformEvent::MouseMoved, 1,
- static_cast<PlatformEvent::Modifiers>(modifiers | PlatformEvent::LeftButtonDown),
- PlatformMouseEvent::FromTouch, WTF::monotonicallyIncreasingTime(), WebPointerProperties::PointerType::Mouse);
- HitTestRequest request(HitTestRequest::ReadOnly);
- MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDragEvent);
- m_mouseDownMayStartDrag = true;
- dragState().m_dragSrc = nullptr;
- m_mouseDownPos = m_frame->view()->rootFrameToContents(mouseDragEvent.position());
- if (handleDrag(mev, DragInitiator::Touch)) {
- m_longTapShouldInvokeContextMenu = true;
- return WebInputEventResult::HandledSystem;
- }
- }
-
- IntPoint hitTestPoint = m_frame->view()->rootFrameToContents(gestureEvent.position());
- HitTestResult result = hitTestResultAtPoint(hitTestPoint);
- if (selectionController().handleGestureLongPress(gestureEvent, result)) {
- focusDocumentView();
- return WebInputEventResult::HandledSystem;
- }
-
- return sendContextMenuEventForGesture(targetedEvent);
-}
-
-WebInputEventResult EventHandler::handleGestureLongTap(const GestureEventWithHitTestResults& targetedEvent)
-{
-#if !OS(ANDROID)
- if (m_longTapShouldInvokeContextMenu) {
- m_longTapShouldInvokeContextMenu = false;
- return sendContextMenuEventForGesture(targetedEvent);
- }
-#endif
- return WebInputEventResult::NotHandled;
-}
-
WebInputEventResult EventHandler::handleGestureScrollEnd(const PlatformGestureEvent& gestureEvent)
{
return m_scrollManager.handleGestureScrollEnd(gestureEvent);
@@ -2148,7 +1906,7 @@ GestureEventWithHitTestResults EventHandler::targetGestureEvent(const PlatformGe
// Scrolling events get hit tested per frame (like wheel events do).
ASSERT(!gestureEvent.isScrollEvent());
- HitTestRequest::HitTestRequestType hitType = getHitTypeForGestureType(gestureEvent.type());
+ HitTestRequest::HitTestRequestType hitType = m_gestureManager.getHitTypeForGestureType(gestureEvent.type());
double activeInterval = 0;
bool shouldKeepActiveForMinInterval = false;
if (readOnly) {
@@ -2157,8 +1915,8 @@ GestureEventWithHitTestResults EventHandler::targetGestureEvent(const PlatformGe
// If the Tap is received very shortly after ShowPress, we want to
// delay clearing of the active state so that it's visible to the user
// for at least a couple of frames.
- activeInterval = WTF::monotonicallyIncreasingTime() - m_lastShowPressTimestamp;
- shouldKeepActiveForMinInterval = m_lastShowPressTimestamp && activeInterval < minimumActiveInterval;
+ activeInterval = WTF::monotonicallyIncreasingTime() - m_gestureManager.getLastShowPressTimestamp();
+ shouldKeepActiveForMinInterval = m_gestureManager.getLastShowPressTimestamp() && activeInterval < minimumActiveInterval;
if (shouldKeepActiveForMinInterval)
hitType |= HitTestRequest::ReadOnly;
}
@@ -2216,32 +1974,6 @@ GestureEventWithHitTestResults EventHandler::hitTestResultForGestureEvent(const
return GestureEventWithHitTestResults(adjustedEvent, hitTestResult);
}
-HitTestRequest::HitTestRequestType EventHandler::getHitTypeForGestureType(PlatformEvent::EventType type)
-{
- HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent;
- switch (type) {
- case PlatformEvent::GestureShowPress:
- case PlatformEvent::GestureTapUnconfirmed:
- return hitType | HitTestRequest::Active;
- case PlatformEvent::GestureTapDownCancel:
- // A TapDownCancel received when no element is active shouldn't really be changing hover state.
- if (!m_frame->document()->activeHoverElement())
- hitType |= HitTestRequest::ReadOnly;
- return hitType | HitTestRequest::Release;
- case PlatformEvent::GestureTap:
- return hitType | HitTestRequest::Release;
- case PlatformEvent::GestureTapDown:
- case PlatformEvent::GestureLongPress:
- case PlatformEvent::GestureLongTap:
- case PlatformEvent::GestureTwoFingerTap:
- // FIXME: Shouldn't LongTap and TwoFingerTap clear the Active state?
- return hitType | HitTestRequest::Active | HitTestRequest::ReadOnly;
- default:
- ASSERT_NOT_REACHED();
- return hitType | HitTestRequest::Active | HitTestRequest::ReadOnly;
- }
-}
-
void EventHandler::applyTouchAdjustment(PlatformGestureEvent* gestureEvent, HitTestResult* hitTestResult)
{
if (!shouldApplyTouchAdjustment(*gestureEvent))
@@ -2616,6 +2348,33 @@ WebInputEventResult EventHandler::dispatchDragSrcEvent(const AtomicString& event
return dispatchDragEvent(eventType, dragState().m_dragSrc.get(), event, dragState().m_dragDataTransfer.get());
}
+bool EventHandler::handleDragDropIfPossible(const GestureEventWithHitTestResults& targetedEvent)
+{
+ if (m_frame->settings() && m_frame->settings()->touchDragDropEnabled() && m_frame->view()) {
+ const PlatformGestureEvent& gestureEvent = targetedEvent.event();
+ IntPoint adjustedPoint = gestureEvent.position();
+ unsigned modifiers = gestureEvent.getModifiers();
+
+ // TODO(mustaq): Suppressing long-tap MouseEvents could break
+ // drag-drop. Will do separately because of the risk. crbug.com/606938.
+ PlatformMouseEvent mouseDownEvent(adjustedPoint, gestureEvent.globalPosition(), LeftButton, PlatformEvent::MousePressed, 1,
+ static_cast<PlatformEvent::Modifiers>(modifiers | PlatformEvent::LeftButtonDown),
+ PlatformMouseEvent::FromTouch, WTF::monotonicallyIncreasingTime(), WebPointerProperties::PointerType::Mouse);
+ m_mouseDown = mouseDownEvent;
+
+ PlatformMouseEvent mouseDragEvent(adjustedPoint, gestureEvent.globalPosition(), LeftButton, PlatformEvent::MouseMoved, 1,
+ static_cast<PlatformEvent::Modifiers>(modifiers | PlatformEvent::LeftButtonDown),
+ PlatformMouseEvent::FromTouch, WTF::monotonicallyIncreasingTime(), WebPointerProperties::PointerType::Mouse);
+ HitTestRequest request(HitTestRequest::ReadOnly);
+ MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDragEvent);
+ m_mouseDownMayStartDrag = true;
+ dragState().m_dragSrc = nullptr;
+ m_mouseDownPos = m_frame->view()->rootFrameToContents(mouseDragEvent.position());
+ return handleDrag(mev, DragInitiator::Touch);
+ }
+ return false;
+}
+
bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, DragInitiator initiator)
{
ASSERT(event.event().type() == PlatformEvent::MouseMoved);
« no previous file with comments | « third_party/WebKit/Source/core/input/EventHandler.h ('k') | third_party/WebKit/Source/core/input/GestureManager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698