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

Side by Side Diff: Source/core/page/EventHandler.cpp

Issue 338543003: Gesture event hit test refactoring and reduction (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Merge with trunk Created 6 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv ed. 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv ed.
3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) 3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) 4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies)
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 #include "core/events/DOMWindowEventQueue.h" 46 #include "core/events/DOMWindowEventQueue.h"
47 #include "core/events/EventPath.h" 47 #include "core/events/EventPath.h"
48 #include "core/events/KeyboardEvent.h" 48 #include "core/events/KeyboardEvent.h"
49 #include "core/events/MouseEvent.h" 49 #include "core/events/MouseEvent.h"
50 #include "core/events/TextEvent.h" 50 #include "core/events/TextEvent.h"
51 #include "core/events/TouchEvent.h" 51 #include "core/events/TouchEvent.h"
52 #include "core/events/WheelEvent.h" 52 #include "core/events/WheelEvent.h"
53 #include "core/fetch/ImageResource.h" 53 #include "core/fetch/ImageResource.h"
54 #include "core/frame/FrameView.h" 54 #include "core/frame/FrameView.h"
55 #include "core/frame/LocalFrame.h" 55 #include "core/frame/LocalFrame.h"
56 #include "core/frame/Settings.h"
56 #include "core/html/HTMLDialogElement.h" 57 #include "core/html/HTMLDialogElement.h"
57 #include "core/html/HTMLFrameElementBase.h" 58 #include "core/html/HTMLFrameElementBase.h"
58 #include "core/html/HTMLFrameSetElement.h" 59 #include "core/html/HTMLFrameSetElement.h"
59 #include "core/html/HTMLInputElement.h" 60 #include "core/html/HTMLInputElement.h"
61 #include "core/inspector/InspectorController.h"
60 #include "core/loader/FrameLoader.h" 62 #include "core/loader/FrameLoader.h"
61 #include "core/loader/FrameLoaderClient.h" 63 #include "core/loader/FrameLoaderClient.h"
62 #include "core/page/AutoscrollController.h" 64 #include "core/page/AutoscrollController.h"
63 #include "core/page/BackForwardClient.h" 65 #include "core/page/BackForwardClient.h"
64 #include "core/page/Chrome.h" 66 #include "core/page/Chrome.h"
65 #include "core/page/ChromeClient.h" 67 #include "core/page/ChromeClient.h"
66 #include "core/page/DragController.h" 68 #include "core/page/DragController.h"
67 #include "core/page/DragState.h" 69 #include "core/page/DragState.h"
68 #include "core/page/EditorClient.h" 70 #include "core/page/EditorClient.h"
71 #include "core/page/EventWithHitTestResults.h"
69 #include "core/page/FocusController.h" 72 #include "core/page/FocusController.h"
70 #include "core/page/FrameTree.h" 73 #include "core/page/FrameTree.h"
71 #include "core/inspector/InspectorController.h"
72 #include "core/page/MouseEventWithHitTestResults.h"
73 #include "core/page/Page.h" 74 #include "core/page/Page.h"
74 #include "core/frame/Settings.h"
75 #include "core/page/SpatialNavigation.h" 75 #include "core/page/SpatialNavigation.h"
76 #include "core/page/TouchAdjustment.h" 76 #include "core/page/TouchAdjustment.h"
77 #include "core/rendering/HitTestRequest.h" 77 #include "core/rendering/HitTestRequest.h"
78 #include "core/rendering/HitTestResult.h" 78 #include "core/rendering/HitTestResult.h"
79 #include "core/rendering/RenderFlowThread.h" 79 #include "core/rendering/RenderFlowThread.h"
80 #include "core/rendering/RenderLayer.h" 80 #include "core/rendering/RenderLayer.h"
81 #include "core/rendering/RenderTextControlSingleLine.h" 81 #include "core/rendering/RenderTextControlSingleLine.h"
82 #include "core/rendering/RenderView.h" 82 #include "core/rendering/RenderView.h"
83 #include "core/rendering/RenderWidget.h" 83 #include "core/rendering/RenderWidget.h"
84 #include "core/rendering/style/RenderStyle.h" 84 #include "core/rendering/style/RenderStyle.h"
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 , m_svgPan(false) 214 , m_svgPan(false)
215 , m_resizeScrollableArea(0) 215 , m_resizeScrollableArea(0)
216 , m_eventHandlerWillResetCapturingMouseEventsNode(0) 216 , m_eventHandlerWillResetCapturingMouseEventsNode(0)
217 , m_clickCount(0) 217 , m_clickCount(0)
218 , m_shouldOnlyFireDragOverEvent(false) 218 , m_shouldOnlyFireDragOverEvent(false)
219 , m_mousePositionIsUnknown(true) 219 , m_mousePositionIsUnknown(true)
220 , m_mouseDownTimestamp(0) 220 , m_mouseDownTimestamp(0)
221 , m_widgetIsLatched(false) 221 , m_widgetIsLatched(false)
222 , m_touchPressed(false) 222 , m_touchPressed(false)
223 , m_scrollGestureHandlingNode(nullptr) 223 , m_scrollGestureHandlingNode(nullptr)
224 , m_lastHitTestResultOverWidget(false) 224 , m_lastGestureScrollOverWidget(false)
225 , m_maxMouseMovedDuration(0) 225 , m_maxMouseMovedDuration(0)
226 , m_baseEventType(PlatformEvent::NoType)
227 , m_didStartDrag(false) 226 , m_didStartDrag(false)
228 , m_longTapShouldInvokeContextMenu(false) 227 , m_longTapShouldInvokeContextMenu(false)
229 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired) 228 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired)
230 , m_lastShowPressTimestamp(0) 229 , m_lastShowPressTimestamp(0)
231 { 230 {
232 } 231 }
233 232
234 EventHandler::~EventHandler() 233 EventHandler::~EventHandler()
235 { 234 {
236 ASSERT(!m_fakeMouseMoveEventTimer.isActive()); 235 ASSERT(!m_fakeMouseMoveEventTimer.isActive());
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 m_mousePressNode = nullptr; 287 m_mousePressNode = nullptr;
289 m_mousePressed = false; 288 m_mousePressed = false;
290 m_capturesDragging = false; 289 m_capturesDragging = false;
291 m_capturingMouseEventsNode = nullptr; 290 m_capturingMouseEventsNode = nullptr;
292 m_latchedWheelEventNode = nullptr; 291 m_latchedWheelEventNode = nullptr;
293 m_previousWheelScrolledNode = nullptr; 292 m_previousWheelScrolledNode = nullptr;
294 m_targetForTouchID.clear(); 293 m_targetForTouchID.clear();
295 m_touchSequenceDocument.clear(); 294 m_touchSequenceDocument.clear();
296 m_touchSequenceUserGestureToken.clear(); 295 m_touchSequenceUserGestureToken.clear();
297 m_scrollGestureHandlingNode = nullptr; 296 m_scrollGestureHandlingNode = nullptr;
298 m_lastHitTestResultOverWidget = false; 297 m_lastGestureScrollOverWidget = false;
299 m_previousGestureScrolledNode = nullptr; 298 m_previousGestureScrolledNode = nullptr;
300 m_scrollbarHandlingScrollGesture = nullptr; 299 m_scrollbarHandlingScrollGesture = nullptr;
301 m_maxMouseMovedDuration = 0; 300 m_maxMouseMovedDuration = 0;
302 m_baseEventType = PlatformEvent::NoType;
303 m_didStartDrag = false; 301 m_didStartDrag = false;
304 m_touchPressed = false; 302 m_touchPressed = false;
305 m_mouseDownMayStartSelect = false; 303 m_mouseDownMayStartSelect = false;
306 m_mouseDownMayStartDrag = false; 304 m_mouseDownMayStartDrag = false;
307 m_lastShowPressTimestamp = 0; 305 m_lastShowPressTimestamp = 0;
308 m_lastDeferredTapElement = nullptr; 306 m_lastDeferredTapElement = nullptr;
309 } 307 }
310 308
311 void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved) 309 void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved)
312 { 310 {
(...skipping 1741 matching lines...) Expand 10 before | Expand all | Expand 10 after
2054 ScrollableArea* sa = *it; 2052 ScrollableArea* sa = *it;
2055 ScrollAnimator* animator = sa->scrollAnimator(); 2053 ScrollAnimator* animator = sa->scrollAnimator();
2056 if (animator) 2054 if (animator)
2057 animator->cancelAnimations(); 2055 animator->cancelAnimations();
2058 } 2056 }
2059 return false; 2057 return false;
2060 } 2058 }
2061 2059
2062 bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent) 2060 bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent)
2063 { 2061 {
2064 IntPoint adjustedPoint = gestureEvent.position(); 2062 TRACE_EVENT0("input", "EventHandler::handleGestureEvent");
2065 RefPtr<LocalFrame> subframe = nullptr; 2063
2064 // Propagation to inner frames is handled below this function.
2065 ASSERT(m_frame == m_frame->localFrameRoot());
2066
2067 // Scrolling-related gesture events invoke EventHandler recursively for each frame down
2068 // the chain, doing a single-frame hit-test per frame. This matches handleWh eelEvent.
2069 // Perhaps we could simplify things by rewriting scroll handling to work inn er frame
2070 // out, and then unify with other gesture events.
2071 if (gestureEvent.isScrollEvent()) {
2072 return handleGestureScrollEvent(gestureEvent);
2073 }
esprehn 2014/06/27 08:33:58 no braces
Rick Byers 2014/06/27 15:38:23 Done.
2074
2075 // Non-scrolling related gesture events instead do a single cross-frame hit- test and
2076 // jump directly to the inner most frame. This matches handleMousePressEvent etc.
2077
2078 // Hit test across all frames and do touch adjustment as necessary for the e vent type.
2079 GestureEventWithHitTestResults targetedEvent = targetGestureEvent(gestureEve nt);
2080 ASSERT(!(targetedEvent.hitTestResult().isOverWidget()));
esprehn 2014/06/27 08:33:58 remove extra braces
Rick Byers 2014/06/27 15:38:24 Done.
2081
2082 // Route to the correct frame.
2083 if (LocalFrame* innerFrame = targetedEvent.hitTestResult().innerNodeFrame())
2084 return innerFrame->eventHandler().handleGestureEventInFrame(targetedEven t);
2085
2086 // No hit test result, handle in root instance. Perhaps we should just retur n false instead?
2087 return handleGestureEventInFrame(targetedEvent);
2088 }
2089
2090 bool EventHandler::handleGestureEventInFrame(const GestureEventWithHitTestResult s& targetedEvent)
2091 {
2092 ASSERT(!targetedEvent.event().isScrollEvent());
2093
2094 RefPtrWillBeRawPtr<Node> eventTarget = targetedEvent.hitTestResult().targetN ode();
2095 RefPtr<Scrollbar> scrollbar = targetedEvent.hitTestResult().scrollbar();
2096 const PlatformGestureEvent& gestureEvent = targetedEvent.event();
2097
2098 if (!scrollbar) {
2099 FrameView* view = m_frame->view();
2100 scrollbar = view ? view->scrollbarAtPoint(gestureEvent.position()) : 0;
2101 }
2102
2103 if (scrollbar) {
2104 bool eventSwallowed = scrollbar->gestureEvent(gestureEvent);
2105 if (gestureEvent.type() == PlatformEvent::GestureTapDown && eventSwallow ed) {
esprehn 2014/06/27 08:33:58 no braces
Rick Byers 2014/06/27 15:38:23 Done.
2106 m_scrollbarHandlingScrollGesture = scrollbar;
2107 }
2108 if (eventSwallowed)
2109 return true;
2110 }
2111
2112 if (eventTarget && eventTarget->dispatchGestureEvent(gestureEvent))
2113 return true;
2114
2066 switch (gestureEvent.type()) { 2115 switch (gestureEvent.type()) {
2067 case PlatformEvent::GestureScrollBegin:
2068 case PlatformEvent::GestureScrollUpdate:
2069 case PlatformEvent::GestureScrollUpdateWithoutPropagation:
2070 case PlatformEvent::GestureScrollEnd:
2071 case PlatformEvent::GestureFlingStart:
2072 // Handle directly in main frame
2073 break;
2074
2075 case PlatformEvent::GestureTap: 2116 case PlatformEvent::GestureTap:
2076 case PlatformEvent::GestureTapUnconfirmed: 2117 return handleGestureTap(targetedEvent);
2118 case PlatformEvent::GestureShowPress:
2119 return handleGestureShowPress();
2120 case PlatformEvent::GestureLongPress:
2121 return handleGestureLongPress(targetedEvent);
2122 case PlatformEvent::GestureLongTap:
2123 return handleGestureLongTap(targetedEvent);
2124 case PlatformEvent::GestureTwoFingerTap:
2125 return sendContextMenuEventForGesture(targetedEvent);
2077 case PlatformEvent::GestureTapDown: 2126 case PlatformEvent::GestureTapDown:
2078 case PlatformEvent::GestureShowPress:
2079 case PlatformEvent::GestureTapDownCancel:
2080 case PlatformEvent::GestureTwoFingerTap:
2081 case PlatformEvent::GestureLongPress:
2082 case PlatformEvent::GestureLongTap:
2083 case PlatformEvent::GesturePinchBegin: 2127 case PlatformEvent::GesturePinchBegin:
2084 case PlatformEvent::GesturePinchEnd: 2128 case PlatformEvent::GesturePinchEnd:
2085 case PlatformEvent::GesturePinchUpdate: 2129 case PlatformEvent::GesturePinchUpdate:
2086 adjustGesturePosition(gestureEvent, adjustedPoint); 2130 case PlatformEvent::GestureTapDownCancel:
2087 subframe = getSubFrameForGestureEvent(adjustedPoint, gestureEvent); 2131 case PlatformEvent::GestureTapUnconfirmed:
2088 if (subframe)
2089 return subframe->eventHandler().handleGestureEvent(gestureEvent);
2090 break; 2132 break;
2091
2092 default: 2133 default:
2093 ASSERT_NOT_REACHED(); 2134 ASSERT_NOT_REACHED();
2094 } 2135 }
2095 2136
2137 return false;
2138 }
2139
2140 bool EventHandler::handleGestureScrollEvent(const PlatformGestureEvent& gestureE vent)
2141 {
2096 RefPtrWillBeRawPtr<Node> eventTarget = nullptr; 2142 RefPtrWillBeRawPtr<Node> eventTarget = nullptr;
2097 RefPtr<Scrollbar> scrollbar; 2143 RefPtr<Scrollbar> scrollbar;
2098 if (gestureEvent.type() == PlatformEvent::GestureScrollEnd 2144 if (gestureEvent.type() != PlatformEvent::GestureScrollBegin) {
2099 || gestureEvent.type() == PlatformEvent::GestureScrollUpdate
2100 || gestureEvent.type() == PlatformEvent::GestureScrollUpdateWithoutPropa gation
2101 || gestureEvent.type() == PlatformEvent::GestureFlingStart) {
2102 scrollbar = m_scrollbarHandlingScrollGesture.get(); 2145 scrollbar = m_scrollbarHandlingScrollGesture.get();
2103 eventTarget = m_scrollGestureHandlingNode.get(); 2146 eventTarget = m_scrollGestureHandlingNode.get();
2104 } 2147 }
2105 2148
2106 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent; 2149 if (!eventTarget) {
2107 double activeInterval = 0; 2150 Document* document = m_frame->document();
2108 bool shouldKeepActiveForMinInterval = false; 2151 if (!document->renderView())
2109 if (gestureEvent.type() == PlatformEvent::GestureShowPress 2152 return false;
2110 || gestureEvent.type() == PlatformEvent::GestureTapUnconfirmed) {
2111 hitType |= HitTestRequest::Active;
2112 } else if (gestureEvent.type() == PlatformEvent::GestureTapDownCancel) {
2113 hitType |= HitTestRequest::Release;
2114 // A TapDownCancel received when no element is active shouldn't really b e changing hover state.
2115 if (!m_frame->document()->activeHoverElement())
2116 hitType |= HitTestRequest::ReadOnly;
2117 } else if (gestureEvent.type() == PlatformEvent::GestureTap) {
2118 hitType |= HitTestRequest::Release;
2119 // If the Tap is received very shortly after ShowPress, we want to
2120 // delay clearing of the active state so that it's visible to the user
2121 // for at least a couple of frames.
2122 activeInterval = WTF::currentTime() - m_lastShowPressTimestamp;
2123 shouldKeepActiveForMinInterval = m_lastShowPressTimestamp && activeInter val < minimumActiveInterval;
2124 if (shouldKeepActiveForMinInterval)
2125 hitType |= HitTestRequest::ReadOnly;
2126 }
2127 else
2128 hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly;
2129 2153
2130 if ((!scrollbar && !eventTarget) || !(hitType & HitTestRequest::ReadOnly)) { 2154 FrameView* view = m_frame->view();
2131 IntPoint hitTestPoint = m_frame->view()->windowToContents(adjustedPoint) ; 2155 if (!view)
esprehn 2014/06/27 08:33:58 You don't need this null check, if you have a Rend
Rick Byers 2014/06/27 15:38:23 Done.
2132 HitTestResult result = hitTestResultAtPoint(hitTestPoint, hitType | HitT estRequest::AllowFrameScrollbars); 2156 return false;
2133 2157
2134 if (shouldKeepActiveForMinInterval) { 2158 LayoutPoint viewPoint = view->windowToContents(gestureEvent.position());
2135 m_lastDeferredTapElement = result.innerElement(); 2159 HitTestRequest request(HitTestRequest::ReadOnly);
2136 m_activeIntervalTimer.startOneShot(minimumActiveInterval - activeInt erval, FROM_HERE); 2160 HitTestResult result(viewPoint);
2137 } 2161 document->renderView()->hitTest(request, result);
esprehn 2014/06/27 08:33:58 What updated the layout before this call?
Rick Byers 2014/06/27 15:38:24 Nothing, as far as I can see, but that was the cas
2138 2162
2139 eventTarget = result.targetNode(); 2163 eventTarget = result.innerNode();
2140 if (!scrollbar) { 2164
2141 FrameView* view = m_frame->view(); 2165 m_lastGestureScrollOverWidget = result.isOverWidget();
2142 scrollbar = view ? view->scrollbarAtPoint(gestureEvent.position()) : 0; 2166 m_scrollGestureHandlingNode = eventTarget;
2143 } 2167 m_previousGestureScrolledNode = nullptr;
2168
2169 if (!scrollbar)
2170 scrollbar = view->scrollbarAtPoint(gestureEvent.position());
2144 if (!scrollbar) 2171 if (!scrollbar)
2145 scrollbar = result.scrollbar(); 2172 scrollbar = result.scrollbar();
2146 } 2173 }
2147 2174
2148 if (scrollbar) { 2175 if (scrollbar) {
2149 bool eventSwallowed = scrollbar->gestureEvent(gestureEvent); 2176 bool eventSwallowed = scrollbar->gestureEvent(gestureEvent);
2150 if (gestureEvent.type() == PlatformEvent::GestureTapDown && eventSwallow ed) { 2177 if (gestureEvent.type() == PlatformEvent::GestureScrollEnd
2151 m_scrollbarHandlingScrollGesture = scrollbar;
2152 } else if (gestureEvent.type() == PlatformEvent::GestureScrollEnd
2153 || gestureEvent.type() == PlatformEvent::GestureFlingStart 2178 || gestureEvent.type() == PlatformEvent::GestureFlingStart
2154 || !eventSwallowed) { 2179 || !eventSwallowed) {
2155 m_scrollbarHandlingScrollGesture = nullptr; 2180 m_scrollbarHandlingScrollGesture = nullptr;
2156 } 2181 }
2157
2158 if (eventSwallowed) 2182 if (eventSwallowed)
2159 return true; 2183 return true;
2160 } 2184 }
2161 2185
2162 if (eventTarget) { 2186 if (eventTarget) {
2163 bool eventSwallowed = false; 2187 bool eventSwallowed = handleScrollGestureOnResizer(eventTarget.get(), ge stureEvent);
2164 if (handleScrollGestureOnResizer(eventTarget.get(), gestureEvent)) 2188 if (!eventSwallowed)
2165 eventSwallowed = true;
2166 else
2167 eventSwallowed = eventTarget->dispatchGestureEvent(gestureEvent); 2189 eventSwallowed = eventTarget->dispatchGestureEvent(gestureEvent);
2168 if (gestureEvent.type() == PlatformEvent::GestureScrollBegin || gestureE vent.type() == PlatformEvent::GestureScrollEnd) {
2169 if (eventSwallowed)
2170 m_scrollGestureHandlingNode = eventTarget;
2171 }
2172
2173 if (eventSwallowed) 2190 if (eventSwallowed)
2174 return true; 2191 return true;
2175 } 2192 }
2176 2193
2177 // FIXME: A more general scroll system (https://bugs.webkit.org/show_bug.cgi ?id=80596) will
2178 // eliminate the need for this.
2179 TemporaryChange<PlatformEvent::Type> baseEventType(m_baseEventType, gestureE vent.type());
2180
2181 switch (gestureEvent.type()) { 2194 switch (gestureEvent.type()) {
2182 case PlatformEvent::GestureScrollBegin: 2195 case PlatformEvent::GestureScrollBegin:
2183 return handleGestureScrollBegin(gestureEvent); 2196 return handleGestureScrollBegin(gestureEvent);
2184 case PlatformEvent::GestureScrollUpdate: 2197 case PlatformEvent::GestureScrollUpdate:
2185 case PlatformEvent::GestureScrollUpdateWithoutPropagation: 2198 case PlatformEvent::GestureScrollUpdateWithoutPropagation:
2186 return handleGestureScrollUpdate(gestureEvent); 2199 return handleGestureScrollUpdate(gestureEvent);
2187 case PlatformEvent::GestureScrollEnd: 2200 case PlatformEvent::GestureScrollEnd:
2188 return handleGestureScrollEnd(gestureEvent); 2201 return handleGestureScrollEnd(gestureEvent);
2189 case PlatformEvent::GestureTap:
2190 return handleGestureTap(gestureEvent, adjustedPoint);
2191 case PlatformEvent::GestureShowPress:
2192 return handleGestureShowPress();
2193 case PlatformEvent::GestureLongPress:
2194 return handleGestureLongPress(gestureEvent, adjustedPoint);
2195 case PlatformEvent::GestureLongTap:
2196 return handleGestureLongTap(gestureEvent, adjustedPoint);
2197 case PlatformEvent::GestureTwoFingerTap:
2198 return handleGestureTwoFingerTap(gestureEvent, adjustedPoint);
2199 case PlatformEvent::GestureTapDown:
2200 case PlatformEvent::GesturePinchBegin:
2201 case PlatformEvent::GesturePinchEnd:
2202 case PlatformEvent::GesturePinchUpdate:
2203 case PlatformEvent::GestureTapDownCancel:
2204 case PlatformEvent::GestureTapUnconfirmed:
2205 case PlatformEvent::GestureFlingStart: 2202 case PlatformEvent::GestureFlingStart:
2206 break; 2203 break;
2207 default: 2204 default:
2208 ASSERT_NOT_REACHED(); 2205 ASSERT_NOT_REACHED();
2209 } 2206 }
2210
2211 return false; 2207 return false;
2212 } 2208 }
2213 2209
2214 bool EventHandler::handleGestureTap(const PlatformGestureEvent& gestureEvent, co nst IntPoint& adjustedPoint) 2210 bool EventHandler::handleGestureTap(const GestureEventWithHitTestResults& target edEvent)
2215 { 2211 {
2212 const PlatformGestureEvent& gestureEvent = targetedEvent.event();
2213
2216 // FIXME: Refactor this code to not hit test multiple times. We use the adju sted position to ensure that the correct node is targeted by the later redundant hit tests. 2214 // FIXME: Refactor this code to not hit test multiple times. We use the adju sted position to ensure that the correct node is targeted by the later redundant hit tests.
2217 2215
2218 unsigned modifierFlags = 0; 2216 unsigned modifierFlags = 0;
2219 if (gestureEvent.altKey()) 2217 if (gestureEvent.altKey())
2220 modifierFlags |= PlatformEvent::AltKey; 2218 modifierFlags |= PlatformEvent::AltKey;
2221 if (gestureEvent.ctrlKey()) 2219 if (gestureEvent.ctrlKey())
2222 modifierFlags |= PlatformEvent::CtrlKey; 2220 modifierFlags |= PlatformEvent::CtrlKey;
2223 if (gestureEvent.metaKey()) 2221 if (gestureEvent.metaKey())
2224 modifierFlags |= PlatformEvent::MetaKey; 2222 modifierFlags |= PlatformEvent::MetaKey;
2225 if (gestureEvent.shiftKey()) 2223 if (gestureEvent.shiftKey())
2226 modifierFlags |= PlatformEvent::ShiftKey; 2224 modifierFlags |= PlatformEvent::ShiftKey;
2227 PlatformEvent::Modifiers modifiers = static_cast<PlatformEvent::Modifiers>(m odifierFlags); 2225 PlatformEvent::Modifiers modifiers = static_cast<PlatformEvent::Modifiers>(m odifierFlags);
2228 2226
2227 IntPoint adjustedPoint = gestureEvent.position();
2228
2229 PlatformMouseEvent fakeMouseMove(adjustedPoint, gestureEvent.globalPosition( ), 2229 PlatformMouseEvent fakeMouseMove(adjustedPoint, gestureEvent.globalPosition( ),
2230 NoButton, PlatformEvent::MouseMoved, /* clickCount */ 0, 2230 NoButton, PlatformEvent::MouseMoved, /* clickCount */ 0,
2231 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp()); 2231 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp());
2232 handleMouseMoveEvent(fakeMouseMove); 2232 handleMouseMoveEvent(fakeMouseMove);
2233 2233
2234 bool defaultPrevented = false; 2234 bool defaultPrevented = false;
2235 PlatformMouseEvent fakeMouseDown(adjustedPoint, gestureEvent.globalPosition( ), 2235 PlatformMouseEvent fakeMouseDown(adjustedPoint, gestureEvent.globalPosition( ),
2236 LeftButton, PlatformEvent::MousePressed, gestureEvent.tapCount(), 2236 LeftButton, PlatformEvent::MousePressed, gestureEvent.tapCount(),
2237 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp()); 2237 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp());
2238 defaultPrevented |= handleMousePressEvent(fakeMouseDown); 2238 defaultPrevented |= handleMousePressEvent(fakeMouseDown);
2239 2239
2240 PlatformMouseEvent fakeMouseUp(adjustedPoint, gestureEvent.globalPosition(), 2240 PlatformMouseEvent fakeMouseUp(adjustedPoint, gestureEvent.globalPosition(),
2241 LeftButton, PlatformEvent::MouseReleased, gestureEvent.tapCount(), 2241 LeftButton, PlatformEvent::MouseReleased, gestureEvent.tapCount(),
2242 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp()); 2242 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp());
2243 defaultPrevented |= handleMouseReleaseEvent(fakeMouseUp); 2243 defaultPrevented |= handleMouseReleaseEvent(fakeMouseUp);
2244 2244
2245 return defaultPrevented; 2245 return defaultPrevented;
2246 } 2246 }
2247 2247
2248 bool EventHandler::handleGestureLongPress(const PlatformGestureEvent& gestureEve nt, const IntPoint& adjustedPoint) 2248 bool EventHandler::handleGestureLongPress(const GestureEventWithHitTestResults& targetedEvent)
2249 { 2249 {
2250 const PlatformGestureEvent& gestureEvent = targetedEvent.event();
2251 IntPoint adjustedPoint = gestureEvent.position();
2252
2253 // FIXME: Ideally we should try to remove the extra mouse-specific hit-tests here (re-using the
2254 // supplied HitTestResult), but that will require some overhaul of the touch drag-and-drop code
2255 // and LongPress is such a special scenario that it's unlikely to matter muc h in practice.
2256
2250 m_longTapShouldInvokeContextMenu = false; 2257 m_longTapShouldInvokeContextMenu = false;
2251 if (m_frame->settings() && m_frame->settings()->touchDragDropEnabled() && m_ frame->view()) { 2258 if (m_frame->settings() && m_frame->settings()->touchDragDropEnabled() && m_ frame->view()) {
2252 PlatformMouseEvent mouseDownEvent(adjustedPoint, gestureEvent.globalPosi tion(), LeftButton, PlatformEvent::MousePressed, 1, 2259 PlatformMouseEvent mouseDownEvent(adjustedPoint, gestureEvent.globalPosi tion(), LeftButton, PlatformEvent::MousePressed, 1,
2253 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey (), gestureEvent.metaKey(), WTF::currentTime()); 2260 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey (), gestureEvent.metaKey(), WTF::currentTime());
2254 m_mouseDown = mouseDownEvent; 2261 m_mouseDown = mouseDownEvent;
2255 2262
2256 PlatformMouseEvent mouseDragEvent(adjustedPoint, gestureEvent.globalPosi tion(), LeftButton, PlatformEvent::MouseMoved, 1, 2263 PlatformMouseEvent mouseDragEvent(adjustedPoint, gestureEvent.globalPosi tion(), LeftButton, PlatformEvent::MouseMoved, 1,
2257 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey (), gestureEvent.metaKey(), WTF::currentTime()); 2264 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey (), gestureEvent.metaKey(), WTF::currentTime());
2258 HitTestRequest request(HitTestRequest::ReadOnly); 2265 HitTestRequest request(HitTestRequest::ReadOnly);
2259 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDragE vent); 2266 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDragE vent);
(...skipping 18 matching lines...) Expand all
2278 HitTestResult result = hitTestResultAtPoint(hitTestPoint); 2285 HitTestResult result = hitTestResultAtPoint(hitTestPoint);
2279 Node* innerNode = result.targetNode(); 2286 Node* innerNode = result.targetNode();
2280 if (!result.isLiveLink() && innerNode && (innerNode->isContentEditable() || innerNode->isTextNode())) { 2287 if (!result.isLiveLink() && innerNode && (innerNode->isContentEditable() || innerNode->isTextNode())) {
2281 selectClosestWordFromHitTestResult(result, DontAppendTrailingWhitesp ace); 2288 selectClosestWordFromHitTestResult(result, DontAppendTrailingWhitesp ace);
2282 if (m_frame->selection().isRange()) { 2289 if (m_frame->selection().isRange()) {
2283 focusDocumentView(); 2290 focusDocumentView();
2284 return true; 2291 return true;
2285 } 2292 }
2286 } 2293 }
2287 } 2294 }
2288 return sendContextMenuEventForGesture(gestureEvent); 2295 return sendContextMenuEventForGesture(targetedEvent);
2289 } 2296 }
2290 2297
2291 bool EventHandler::handleGestureLongTap(const PlatformGestureEvent& gestureEvent , const IntPoint& adjustedPoint) 2298 bool EventHandler::handleGestureLongTap(const GestureEventWithHitTestResults& ta rgetedEvent)
2292 { 2299 {
2293 #if !OS(ANDROID) 2300 #if !OS(ANDROID)
2294 if (m_longTapShouldInvokeContextMenu) { 2301 if (m_longTapShouldInvokeContextMenu) {
2295 m_longTapShouldInvokeContextMenu = false; 2302 m_longTapShouldInvokeContextMenu = false;
2296 return sendContextMenuEventForGesture(gestureEvent); 2303 return sendContextMenuEventForGesture(targetedEvent);
2297 } 2304 }
2298 #endif 2305 #endif
2299 return false; 2306 return false;
2300 } 2307 }
2301 2308
2302 bool EventHandler::handleScrollGestureOnResizer(Node* eventTarget, const Platfor mGestureEvent& gestureEvent) { 2309 bool EventHandler::handleScrollGestureOnResizer(Node* eventTarget, const Platfor mGestureEvent& gestureEvent) {
2303 if (gestureEvent.type() == PlatformEvent::GestureScrollBegin) { 2310 if (gestureEvent.type() == PlatformEvent::GestureScrollBegin) {
2304 RenderLayer* layer = eventTarget->renderer() ? eventTarget->renderer()-> enclosingLayer() : 0; 2311 RenderLayer* layer = eventTarget->renderer() ? eventTarget->renderer()-> enclosingLayer() : 0;
2305 IntPoint p = m_frame->view()->windowToContents(gestureEvent.position()); 2312 IntPoint p = m_frame->view()->windowToContents(gestureEvent.position());
2306 if (layer && layer->scrollableArea() && layer->scrollableArea()->isPoint InResizeControl(p, ResizerForTouch)) { 2313 if (layer && layer->scrollableArea() && layer->scrollableArea()->isPoint InResizeControl(p, ResizerForTouch)) {
(...skipping 12 matching lines...) Expand all
2319 if (m_resizeScrollableArea && m_resizeScrollableArea->inResizeMode()) { 2326 if (m_resizeScrollableArea && m_resizeScrollableArea->inResizeMode()) {
2320 m_resizeScrollableArea->setInResizeMode(false); 2327 m_resizeScrollableArea->setInResizeMode(false);
2321 m_resizeScrollableArea = 0; 2328 m_resizeScrollableArea = 0;
2322 return false; 2329 return false;
2323 } 2330 }
2324 } 2331 }
2325 2332
2326 return false; 2333 return false;
2327 } 2334 }
2328 2335
2329 bool EventHandler::handleGestureTwoFingerTap(const PlatformGestureEvent& gesture Event, const IntPoint& adjustedPoint) 2336 bool EventHandler::passScrollGestureEventToWidget(const PlatformGestureEvent& ge stureEvent, RenderObject* renderer)
2330 { 2337 {
2331 return sendContextMenuEventForGesture(gestureEvent); 2338 ASSERT(gestureEvent.isScrollEvent());
2332 }
2333 2339
2334 bool EventHandler::passGestureEventToWidget(const PlatformGestureEvent& gestureE vent, Widget* widget) 2340 if (!m_lastGestureScrollOverWidget)
2335 {
2336 if (!widget)
2337 return false; 2341 return false;
2338 2342
2343 if (!renderer || !renderer->isWidget())
2344 return false;
2345
2346 Widget* widget = toRenderWidget(renderer)->widget();
2347
2339 if (!widget->isFrameView()) 2348 if (!widget->isFrameView())
2340 return false; 2349 return false;
2341 2350
2342 return toFrameView(widget)->frame().eventHandler().handleGestureEvent(gestur eEvent); 2351 return toFrameView(widget)->frame().eventHandler().handleGestureScrollEvent( gestureEvent);
2343 }
2344
2345 bool EventHandler::passGestureEventToWidgetIfPossible(const PlatformGestureEvent & gestureEvent, RenderObject* renderer)
2346 {
2347 if (m_lastHitTestResultOverWidget && renderer && renderer->isWidget()) {
2348 Widget* widget = toRenderWidget(renderer)->widget();
2349 return widget && passGestureEventToWidget(gestureEvent, widget);
2350 }
2351 return false;
2352 } 2352 }
2353 2353
2354 bool EventHandler::handleGestureScrollEnd(const PlatformGestureEvent& gestureEve nt) { 2354 bool EventHandler::handleGestureScrollEnd(const PlatformGestureEvent& gestureEve nt) {
2355 RefPtrWillBeRawPtr<Node> node = m_scrollGestureHandlingNode; 2355 RefPtrWillBeRawPtr<Node> node = m_scrollGestureHandlingNode;
2356 clearGestureScrollNodes(); 2356 clearGestureScrollNodes();
2357 2357
2358 if (node) 2358 if (node)
2359 passGestureEventToWidgetIfPossible(gestureEvent, node->renderer()); 2359 passScrollGestureEventToWidget(gestureEvent, node->renderer());
2360 2360
2361 return false; 2361 return false;
2362 } 2362 }
2363 2363
2364 bool EventHandler::handleGestureScrollBegin(const PlatformGestureEvent& gestureE vent) 2364 bool EventHandler::handleGestureScrollBegin(const PlatformGestureEvent& gestureE vent)
2365 { 2365 {
2366 Document* document = m_frame->document(); 2366 Document* document = m_frame->document();
2367 if (!document->renderView()) 2367 if (!document->renderView())
2368 return false; 2368 return false;
2369 2369
2370 FrameView* view = m_frame->view(); 2370 FrameView* view = m_frame->view();
2371 if (!view) 2371 if (!view)
2372 return false; 2372 return false;
2373 2373
2374 LayoutPoint viewPoint = view->windowToContents(gestureEvent.position());
2375 HitTestRequest request(HitTestRequest::ReadOnly);
2376 HitTestResult result(viewPoint);
2377 document->renderView()->hitTest(request, result);
2378
2379 m_lastHitTestResultOverWidget = result.isOverWidget();
2380 m_scrollGestureHandlingNode = result.innerNode();
2381 m_previousGestureScrolledNode = nullptr;
2382
2383 // If there's no renderer on the node, send the event to the nearest ancesto r with a renderer. 2374 // If there's no renderer on the node, send the event to the nearest ancesto r with a renderer.
2384 // Needed for <option> and <optgroup> elements so we can touch scroll <selec t>s 2375 // Needed for <option> and <optgroup> elements so we can touch scroll <selec t>s
2385 while (m_scrollGestureHandlingNode && !m_scrollGestureHandlingNode->renderer ()) 2376 while (m_scrollGestureHandlingNode && !m_scrollGestureHandlingNode->renderer ())
2386 m_scrollGestureHandlingNode = m_scrollGestureHandlingNode->parentOrShado wHostNode(); 2377 m_scrollGestureHandlingNode = m_scrollGestureHandlingNode->parentOrShado wHostNode();
2387 2378
2388 if (!m_scrollGestureHandlingNode) 2379 if (!m_scrollGestureHandlingNode)
2389 return false; 2380 return false;
2390 2381
2391 passGestureEventToWidgetIfPossible(gestureEvent, m_scrollGestureHandlingNode ->renderer()); 2382 passScrollGestureEventToWidget(gestureEvent, m_scrollGestureHandlingNode->re nderer());
2392 2383
2393 return true; 2384 return true;
2394 } 2385 }
2395 2386
2396 bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gesture Event) 2387 bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gesture Event)
2397 { 2388 {
2398 FloatSize delta(gestureEvent.deltaX(), gestureEvent.deltaY()); 2389 FloatSize delta(gestureEvent.deltaX(), gestureEvent.deltaY());
2399 if (delta.isZero()) 2390 if (delta.isZero())
2400 return false; 2391 return false;
2401 2392
2402 const float scaleFactor = m_frame->pageZoomFactor(); 2393 const float scaleFactor = m_frame->pageZoomFactor();
2403 delta.scale(1 / scaleFactor, 1 / scaleFactor); 2394 delta.scale(1 / scaleFactor, 1 / scaleFactor);
2404 2395
2405 Node* node = m_scrollGestureHandlingNode.get(); 2396 Node* node = m_scrollGestureHandlingNode.get();
2406 if (!node) 2397 if (!node)
2407 return sendScrollEventToView(gestureEvent, delta); 2398 return sendScrollEventToView(gestureEvent, delta);
2408 2399
2409 // Ignore this event if the targeted node does not have a valid renderer. 2400 // Ignore this event if the targeted node does not have a valid renderer.
2410 RenderObject* renderer = node->renderer(); 2401 RenderObject* renderer = node->renderer();
2411 if (!renderer) 2402 if (!renderer)
2412 return false; 2403 return false;
2413 2404
2414 RefPtr<FrameView> protector(m_frame->view()); 2405 RefPtr<FrameView> protector(m_frame->view());
2415 2406
2416 Node* stopNode = 0; 2407 Node* stopNode = 0;
2417 bool scrollShouldNotPropagate = gestureEvent.type() == PlatformEvent::Gestur eScrollUpdateWithoutPropagation; 2408 bool scrollShouldNotPropagate = gestureEvent.type() == PlatformEvent::Gestur eScrollUpdateWithoutPropagation;
2418 2409
2419 // Try to send the event to the correct view. 2410 // Try to send the event to the correct view.
2420 if (passGestureEventToWidgetIfPossible(gestureEvent, renderer)) { 2411 if (passScrollGestureEventToWidget(gestureEvent, renderer)) {
2421 if(scrollShouldNotPropagate) 2412 if(scrollShouldNotPropagate)
2422 m_previousGestureScrolledNode = m_scrollGestureHandlingNode; 2413 m_previousGestureScrolledNode = m_scrollGestureHandlingNode;
2423 2414
2424 return true; 2415 return true;
2425 } 2416 }
2426 2417
2427 if (scrollShouldNotPropagate) 2418 if (scrollShouldNotPropagate)
2428 stopNode = m_previousGestureScrolledNode.get(); 2419 stopNode = m_previousGestureScrolledNode.get();
2429 2420
2430 // First try to scroll the closest scrollable RenderBox ancestor of |node|. 2421 // First try to scroll the closest scrollable RenderBox ancestor of |node|.
(...skipping 29 matching lines...) Expand all
2460 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey()); 2451 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey());
2461 syntheticWheelEvent.setHasPreciseScrollingDeltas(true); 2452 syntheticWheelEvent.setHasPreciseScrollingDeltas(true);
2462 2453
2463 bool scrolledFrame = view->wheelEvent(syntheticWheelEvent); 2454 bool scrolledFrame = view->wheelEvent(syntheticWheelEvent);
2464 if (scrolledFrame) 2455 if (scrolledFrame)
2465 setFrameWasScrolledByUser(); 2456 setFrameWasScrolledByUser();
2466 2457
2467 return scrolledFrame; 2458 return scrolledFrame;
2468 } 2459 }
2469 2460
2470 LocalFrame* EventHandler::getSubFrameForGestureEvent(const IntPoint& touchAdjust edPoint, const PlatformGestureEvent& gestureEvent)
2471 {
2472 PlatformMouseEvent mouseDown(touchAdjustedPoint, gestureEvent.globalPosition (), LeftButton, PlatformEvent::MousePressed, 1,
2473 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), gestureEvent.timestamp());
2474 HitTestRequest request(HitTestRequest::ReadOnly);
2475 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDown);
2476 return subframeForHitTestResult(mev);
2477 }
2478
2479 void EventHandler::clearGestureScrollNodes() 2461 void EventHandler::clearGestureScrollNodes()
2480 { 2462 {
2481 m_scrollGestureHandlingNode = nullptr; 2463 m_scrollGestureHandlingNode = nullptr;
2482 m_previousGestureScrolledNode = nullptr; 2464 m_previousGestureScrolledNode = nullptr;
2483 } 2465 }
2484 2466
2485 bool EventHandler::isScrollbarHandlingGestures() const 2467 bool EventHandler::isScrollbarHandlingGestures() const
2486 { 2468 {
2487 return m_scrollbarHandlingScrollGesture.get(); 2469 return m_scrollbarHandlingScrollGesture.get();
2488 } 2470 }
2489 2471
2490 bool EventHandler::shouldApplyTouchAdjustment(const PlatformGestureEvent& event) const 2472 bool EventHandler::shouldApplyTouchAdjustment(const PlatformGestureEvent& event) const
2491 { 2473 {
2492 if (m_frame->settings() && !m_frame->settings()->touchAdjustmentEnabled()) 2474 if (m_frame->settings() && !m_frame->settings()->touchAdjustmentEnabled())
2493 return false; 2475 return false;
2494 return !event.area().isEmpty(); 2476 return !event.area().isEmpty();
2495 } 2477 }
2496 2478
2497 bool EventHandler::bestClickableNodeForTouchPoint(const IntPoint& touchCenter, c onst IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode) 2479 bool EventHandler::bestClickableNodeForHitTestResult(const HitTestResult& result , IntPoint& targetPoint, Node*& targetNode)
2498 { 2480 {
2499 IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter); 2481 // FIXME: Unify this with the other best* functions which are very similar.
2500 HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::Re adOnly | HitTestRequest::Active, touchRadius); 2482
2483 TRACE_EVENT0("input", "EventHandler::bestClickableNodeForHitTestResult");
2484 ASSERT(result.isRectBasedTest());
2501 2485
2502 // If the touch is over a scrollbar, don't adjust the touch point since touc h adjustment only takes into account 2486 // If the touch is over a scrollbar, don't adjust the touch point since touc h adjustment only takes into account
2503 // DOM nodes so a touch over a scrollbar will be adjusted towards nearby nod es. This leads to things like textarea 2487 // DOM nodes so a touch over a scrollbar will be adjusted towards nearby nod es. This leads to things like textarea
2504 // scrollbars being untouchable. 2488 // scrollbars being untouchable.
2505 if (result.scrollbar()) 2489 if (result.scrollbar())
2506 return false; 2490 return false;
2507 2491
2508 IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius); 2492 IntPoint touchCenter = m_frame->view()->contentsToWindow(result.roundedPoint InMainFrame());
2493 IntRect touchRect = m_frame->view()->contentsToWindow(result.hitTestLocation ().boundingBox());
2494
2509 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes; 2495 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes;
2510 copyToVector(result.rectBasedTestResult(), nodes); 2496 copyToVector(result.rectBasedTestResult(), nodes);
2511 2497
2512 // FIXME: Should be able to handle targetNode being a shadow DOM node to avo id performing uncessary hit tests 2498 // FIXME: Should be able to handle targetNode being a shadow DOM node to avo id performing uncessary hit tests
2513 // in the case where further processing on the node is required. Returning t he shadow ancestor prevents a 2499 // in the case where further processing on the node is required. Returning t he shadow ancestor prevents a
2514 // regression in touchadjustment/html-label.html. Some refinement is require d to testing/internals to 2500 // regression in touchadjustment/html-label.html. Some refinement is require d to testing/internals to
2515 // handle targetNode being a shadow DOM node. 2501 // handle targetNode being a shadow DOM node.
2516 2502
2517 // FIXME: the explicit Vector conversion copies into a temporary and is wast eful. 2503 // FIXME: the explicit Vector conversion copies into a temporary and is wast eful.
2518 // FIXME: targetNode and success are only used by Internals functions. We sh ould 2504 // FIXME: targetNode and success are only used by Internals functions. We sh ould
2519 // instead have dedicated test methods so we only do this work in tests. 2505 // instead have dedicated test methods so we only do this work in tests.
2520 bool success = findBestClickableCandidate(targetNode, targetPoint, touchCent er, touchRect, WillBeHeapVector<RefPtrWillBeMember<Node> > (nodes)); 2506 bool success = findBestClickableCandidate(targetNode, targetPoint, touchCent er, touchRect, WillBeHeapVector<RefPtrWillBeMember<Node> > (nodes));
2521 if (success && targetNode) 2507 if (success && targetNode)
2522 targetNode = targetNode->deprecatedShadowAncestorNode(); 2508 targetNode = targetNode->deprecatedShadowAncestorNode();
2523 return success; 2509 return success;
2524 } 2510 }
2525 2511
2526 bool EventHandler::bestContextMenuNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode) 2512 bool EventHandler::bestContextMenuNodeForHitTestResult(const HitTestResult& resu lt, IntPoint& targetPoint, Node*& targetNode)
2527 { 2513 {
2528 IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter); 2514 ASSERT(result.isRectBasedTest());
2529 HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::Re adOnly | HitTestRequest::Active, touchRadius); 2515 IntPoint touchCenter = m_frame->view()->contentsToWindow(result.roundedPoint InMainFrame());
2530 2516 IntRect touchRect = m_frame->view()->contentsToWindow(result.hitTestLocation ().boundingBox());
2531 IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius);
2532 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes; 2517 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes;
2533 copyToVector(result.rectBasedTestResult(), nodes); 2518 copyToVector(result.rectBasedTestResult(), nodes);
2534 2519
2535 // FIXME: the explicit Vector conversion copies into a temporary and is wast eful. 2520 // FIXME: the explicit Vector conversion copies into a temporary and is wast eful.
2536 return findBestContextMenuCandidate(targetNode, targetPoint, touchCenter, to uchRect, WillBeHeapVector<RefPtrWillBeMember<Node> >(nodes)); 2521 return findBestContextMenuCandidate(targetNode, targetPoint, touchCenter, to uchRect, WillBeHeapVector<RefPtrWillBeMember<Node> >(nodes));
2537 } 2522 }
2538 2523
2539 bool EventHandler::bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, co nst IntSize& touchRadius, IntRect& targetArea, Node*& targetNode) 2524 bool EventHandler::bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, co nst IntSize& touchRadius, IntRect& targetArea, Node*& targetNode)
2540 { 2525 {
2541 IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter); 2526 IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter);
2542 HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::Re adOnly | HitTestRequest::Active, touchRadius); 2527 HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::Re adOnly | HitTestRequest::Active, touchRadius);
2543 2528
2544 IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius); 2529 IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius);
2545 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes; 2530 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes;
2546 copyToVector(result.rectBasedTestResult(), nodes); 2531 copyToVector(result.rectBasedTestResult(), nodes);
2547 2532
2548 // FIXME: the explicit Vector conversion copies into a temporary and is wast eful. 2533 // FIXME: the explicit Vector conversion copies into a temporary and is wast eful.
2549 return findBestZoomableArea(targetNode, targetArea, touchCenter, touchRect, WillBeHeapVector<RefPtrWillBeMember<Node> >(nodes)); 2534 return findBestZoomableArea(targetNode, targetArea, touchCenter, touchRect, WillBeHeapVector<RefPtrWillBeMember<Node> >(nodes));
2550 } 2535 }
2551 2536
2552 void EventHandler::adjustGesturePosition(const PlatformGestureEvent& gestureEven t, IntPoint& adjustedPoint) 2537 GestureEventWithHitTestResults EventHandler::targetGestureEvent(const PlatformGe stureEvent& gestureEvent, bool readOnly)
2553 { 2538 {
2554 if (!shouldApplyTouchAdjustment(gestureEvent)) 2539 ASSERT(m_frame == m_frame->localFrameRoot());
2555 return; 2540 // Scrolling events get hit tested per frame (like wheel events do).
2541 ASSERT(!gestureEvent.isScrollEvent());
2556 2542
2557 Node* targetNode = 0; 2543 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent | Hi tTestRequest::AllowFrameScrollbars;
2558 switch (gestureEvent.type()) { 2544 double activeInterval = 0;
2559 case PlatformEvent::GestureTap: 2545 bool shouldKeepActiveForMinInterval = false;
2560 case PlatformEvent::GestureTapUnconfirmed: 2546 if (readOnly) {
2561 case PlatformEvent::GestureTapDown: 2547 hitType |= HitTestRequest::ReadOnly;
2562 case PlatformEvent::GestureShowPress: 2548 } else if (gestureEvent.type() == PlatformEvent::GestureShowPress
2563 bestClickableNodeForTouchPoint(gestureEvent.position(), IntSize(gestureE vent.area().width() / 2, gestureEvent.area().height() / 2), adjustedPoint, targe tNode); 2549 || gestureEvent.type() == PlatformEvent::GestureTapUnconfirmed) {
2564 break; 2550 hitType |= HitTestRequest::Active;
2565 case PlatformEvent::GestureLongPress: 2551 } else if (gestureEvent.type() == PlatformEvent::GestureTapDownCancel) {
2566 case PlatformEvent::GestureLongTap: 2552 hitType |= HitTestRequest::Release;
2567 case PlatformEvent::GestureTwoFingerTap: 2553 // A TapDownCancel received when no element is active shouldn't really b e changing hover state.
2568 bestContextMenuNodeForTouchPoint(gestureEvent.position(), IntSize(gestur eEvent.area().width() / 2, gestureEvent.area().height() / 2), adjustedPoint, tar getNode); 2554 if (!m_frame->document()->activeHoverElement())
2569 break; 2555 hitType |= HitTestRequest::ReadOnly;
2570 default: 2556 } else if (gestureEvent.type() == PlatformEvent::GestureTap) {
2571 // FIXME: Implement handling for other types as needed. 2557 hitType |= HitTestRequest::Release;
2572 ASSERT_NOT_REACHED(); 2558 // If the Tap is received very shortly after ShowPress, we want to
2559 // delay clearing of the active state so that it's visible to the user
2560 // for at least a couple of frames.
2561 activeInterval = WTF::currentTime() - m_lastShowPressTimestamp;
2562 shouldKeepActiveForMinInterval = m_lastShowPressTimestamp && activeInter val < minimumActiveInterval;
2563 if (shouldKeepActiveForMinInterval)
2564 hitType |= HitTestRequest::ReadOnly;
2565 } else {
2566 hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly;
2573 } 2567 }
2568
2569 // Perform the rect-based hit-test. Note that we don't yet apply hover/activ e state here
2570 // because we need to resolve touch adjustment first so that we apply hover/ active it to
2571 // the final adjusted node.
2572 IntPoint hitTestPoint = m_frame->view()->windowToContents(gestureEvent.posit ion());
2573 IntSize touchRadius = gestureEvent.area();
2574 touchRadius.scale(1.f / 2);
2575 HitTestResult hitTestResult = hitTestResultAtPoint(hitTestPoint, hitType | H itTestRequest::ReadOnly, touchRadius);
2576
2577 // Adjust the location of the gesture to the most likely nearby node, as app ropriate for the
2578 // type of event.
2579 PlatformGestureEvent adjustedEvent = gestureEvent;
2580 if (shouldApplyTouchAdjustment(gestureEvent)) {
esprehn 2014/06/27 08:33:58 We should consider breaking this stuff up into sma
Rick Byers 2014/06/27 15:38:23 Done. Added getHitTypeForGestureType and applyTou
2581 Node* adjustedNode = 0;
2582 IntPoint adjustedPoint = gestureEvent.position();
2583 IntSize radius = gestureEvent.area();
2584 radius.scale(1.f / 2);
2585 bool adjusted = false;
2586 switch (gestureEvent.type()) {
2587 case PlatformEvent::GestureTap:
2588 case PlatformEvent::GestureTapUnconfirmed:
2589 case PlatformEvent::GestureTapDown:
2590 case PlatformEvent::GestureShowPress:
2591 adjusted = bestClickableNodeForHitTestResult(hitTestResult, adjusted Point, adjustedNode);
esprehn 2014/06/27 08:33:58 If this was a helper you could just do return bes
Rick Byers 2014/06/27 15:38:24 I've got a plan to unify the best*ForHitTestResult
2592 break;
2593 case PlatformEvent::GestureLongPress:
2594 case PlatformEvent::GestureLongTap:
2595 case PlatformEvent::GestureTwoFingerTap:
2596 adjusted = bestContextMenuNodeForHitTestResult(hitTestResult, adjust edPoint, adjustedNode);
2597 break;
2598 default:
2599 // FIXME: Implement handling for other types as needed.
2600 ASSERT_NOT_REACHED();
2601 }
2602
2603 if (adjusted) {
esprehn 2014/06/27 08:33:58 If it was in a helper you could just write: if (a
Rick Byers 2014/06/27 15:38:24 Again I think I can make this even simpler, but it
2604 hitTestResult.resolveRectBasedTest(adjustedNode, m_frame->view()->wi ndowToContents(adjustedPoint));
2605 adjustedEvent.applyTouchAdjustment(adjustedPoint);
2606 }
2607 }
2608
2609 // Now apply hover/active state to the final target.
2610 // FIXME: This is supposed to send mouseenter/mouseleave events, but doesn't because we
2611 // aren't passing a PlatformMouseEvent.
2612 HitTestRequest request(hitType | HitTestRequest::AllowChildFrameContent);
2613 if (!request.readOnly())
2614 m_frame->document()->updateHoverActiveState(request, hitTestResult.inner Element());
2615
2616 if (shouldKeepActiveForMinInterval) {
2617 m_lastDeferredTapElement = hitTestResult.innerElement();
2618 m_activeIntervalTimer.startOneShot(minimumActiveInterval - activeInterva l, FROM_HERE);
2619 }
2620
2621 return GestureEventWithHitTestResults(adjustedEvent, hitTestResult);
2574 } 2622 }
2575 2623
2576 bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event) 2624 bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
2577 { 2625 {
2578 Document* doc = m_frame->document(); 2626 Document* doc = m_frame->document();
2579 FrameView* v = m_frame->view(); 2627 FrameView* v = m_frame->view();
2580 if (!v) 2628 if (!v)
2581 return false; 2629 return false;
2582 2630
2583 // Clear mouse press state to avoid initiating a drag while context menu is up. 2631 // Clear mouse press state to avoid initiating a drag while context menu is up.
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
2670 #else 2718 #else
2671 PlatformEvent::Type eventType = PlatformEvent::MousePressed; 2719 PlatformEvent::Type eventType = PlatformEvent::MousePressed;
2672 #endif 2720 #endif
2673 2721
2674 PlatformMouseEvent mouseEvent(position, globalPosition, RightButton, eventTy pe, 1, false, false, false, false, WTF::currentTime()); 2722 PlatformMouseEvent mouseEvent(position, globalPosition, RightButton, eventTy pe, 1, false, false, false, false, WTF::currentTime());
2675 2723
2676 handleMousePressEvent(mouseEvent); 2724 handleMousePressEvent(mouseEvent);
2677 return sendContextMenuEvent(mouseEvent); 2725 return sendContextMenuEvent(mouseEvent);
2678 } 2726 }
2679 2727
2680 bool EventHandler::sendContextMenuEventForGesture(const PlatformGestureEvent& ev ent) 2728 bool EventHandler::sendContextMenuEventForGesture(const GestureEventWithHitTestR esults& targetedEvent)
2681 { 2729 {
2682 #if OS(WIN) 2730 #if OS(WIN)
2683 PlatformEvent::Type eventType = PlatformEvent::MouseReleased; 2731 PlatformEvent::Type eventType = PlatformEvent::MouseReleased;
2684 #else 2732 #else
2685 PlatformEvent::Type eventType = PlatformEvent::MousePressed; 2733 PlatformEvent::Type eventType = PlatformEvent::MousePressed;
2686 #endif 2734 #endif
2687 2735
2688 IntPoint adjustedPoint = event.position(); 2736 PlatformMouseEvent mouseEvent(targetedEvent.event().position(), targetedEven t.event().globalPosition(), RightButton, eventType, 1, false, false, false, fals e, WTF::currentTime());
2689 adjustGesturePosition(event, adjustedPoint);
2690 PlatformMouseEvent mouseEvent(adjustedPoint, event.globalPosition(), RightBu tton, eventType, 1, false, false, false, false, WTF::currentTime());
2691 // To simulate right-click behavior, we send a right mouse down and then 2737 // To simulate right-click behavior, we send a right mouse down and then
2692 // context menu event. 2738 // context menu event.
2739 // FIXME: Send HitTestResults to avoid redundant hit tests.
2693 handleMousePressEvent(mouseEvent); 2740 handleMousePressEvent(mouseEvent);
2694 return sendContextMenuEvent(mouseEvent); 2741 return sendContextMenuEvent(mouseEvent);
2695 // We do not need to send a corresponding mouse release because in case of 2742 // We do not need to send a corresponding mouse release because in case of
2696 // right-click, the context menu takes capture and consumes all events. 2743 // right-click, the context menu takes capture and consumes all events.
2697 } 2744 }
2698 2745
2699 void EventHandler::scheduleHoverStateUpdate() 2746 void EventHandler::scheduleHoverStateUpdate()
2700 { 2747 {
2701 if (!m_hoverTimer.isActive()) 2748 if (!m_hoverTimer.isActive())
2702 m_hoverTimer.startOneShot(0, FROM_HERE); 2749 m_hoverTimer.startOneShot(0, FROM_HERE);
(...skipping 1048 matching lines...) Expand 10 before | Expand all | Expand 10 after
3751 unsigned EventHandler::accessKeyModifiers() 3798 unsigned EventHandler::accessKeyModifiers()
3752 { 3799 {
3753 #if OS(MACOSX) 3800 #if OS(MACOSX)
3754 return PlatformEvent::CtrlKey | PlatformEvent::AltKey; 3801 return PlatformEvent::CtrlKey | PlatformEvent::AltKey;
3755 #else 3802 #else
3756 return PlatformEvent::AltKey; 3803 return PlatformEvent::AltKey;
3757 #endif 3804 #endif
3758 } 3805 }
3759 3806
3760 } // namespace WebCore 3807 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698