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

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: Fix release build 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
« no previous file with comments | « Source/core/page/EventHandler.h ('k') | Source/core/page/EventWithHitTestResults.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1744 matching lines...) Expand 10 before | Expand all | Expand 10 after
2057 ScrollableArea* sa = *it; 2055 ScrollableArea* sa = *it;
2058 ScrollAnimator* animator = sa->scrollAnimator(); 2056 ScrollAnimator* animator = sa->scrollAnimator();
2059 if (animator) 2057 if (animator)
2060 animator->cancelAnimations(); 2058 animator->cancelAnimations();
2061 } 2059 }
2062 return false; 2060 return false;
2063 } 2061 }
2064 2062
2065 bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent) 2063 bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent)
2066 { 2064 {
2067 IntPoint adjustedPoint = gestureEvent.position(); 2065 TRACE_EVENT0("input", "EventHandler::handleGestureEvent");
2068 RefPtr<LocalFrame> subframe = nullptr; 2066
2067 // Propagation to inner frames is handled below this function.
2068 ASSERT(m_frame == m_frame->localFrameRoot());
2069
2070 // Scrolling-related gesture events invoke EventHandler recursively for each frame down
2071 // the chain, doing a single-frame hit-test per frame. This matches handleWh eelEvent.
2072 // Perhaps we could simplify things by rewriting scroll handling to work inn er frame
2073 // out, and then unify with other gesture events.
2074 if (gestureEvent.isScrollEvent())
2075 return handleGestureScrollEvent(gestureEvent);
2076
2077 // Non-scrolling related gesture events instead do a single cross-frame hit- test and
2078 // jump directly to the inner most frame. This matches handleMousePressEvent etc.
2079
2080 // Hit test across all frames and do touch adjustment as necessary for the e vent type.
2081 GestureEventWithHitTestResults targetedEvent = targetGestureEvent(gestureEve nt);
2082 ASSERT(!targetedEvent.hitTestResult().isOverWidget());
2083
2084 // Route to the correct frame.
2085 if (LocalFrame* innerFrame = targetedEvent.hitTestResult().innerNodeFrame())
2086 return innerFrame->eventHandler().handleGestureEventInFrame(targetedEven t);
2087
2088 // No hit test result, handle in root instance. Perhaps we should just retur n false instead?
2089 return handleGestureEventInFrame(targetedEvent);
2090 }
2091
2092 bool EventHandler::handleGestureEventInFrame(const GestureEventWithHitTestResult s& targetedEvent)
2093 {
2094 ASSERT(!targetedEvent.event().isScrollEvent());
2095
2096 RefPtrWillBeRawPtr<Node> eventTarget = targetedEvent.hitTestResult().targetN ode();
2097 RefPtr<Scrollbar> scrollbar = targetedEvent.hitTestResult().scrollbar();
2098 const PlatformGestureEvent& gestureEvent = targetedEvent.event();
2099
2100 if (!scrollbar) {
2101 FrameView* view = m_frame->view();
2102 scrollbar = view ? view->scrollbarAtPoint(gestureEvent.position()) : 0;
2103 }
2104
2105 if (scrollbar) {
2106 bool eventSwallowed = scrollbar->gestureEvent(gestureEvent);
2107 if (gestureEvent.type() == PlatformEvent::GestureTapDown && eventSwallow ed)
2108 m_scrollbarHandlingScrollGesture = scrollbar;
2109 if (eventSwallowed)
2110 return true;
2111 }
2112
2113 if (eventTarget && eventTarget->dispatchGestureEvent(gestureEvent))
2114 return true;
2115
2069 switch (gestureEvent.type()) { 2116 switch (gestureEvent.type()) {
2070 case PlatformEvent::GestureScrollBegin:
2071 case PlatformEvent::GestureScrollUpdate:
2072 case PlatformEvent::GestureScrollUpdateWithoutPropagation:
2073 case PlatformEvent::GestureScrollEnd:
2074 case PlatformEvent::GestureFlingStart:
2075 // Handle directly in main frame
2076 break;
2077
2078 case PlatformEvent::GestureTap: 2117 case PlatformEvent::GestureTap:
2079 case PlatformEvent::GestureTapUnconfirmed: 2118 return handleGestureTap(targetedEvent);
2119 case PlatformEvent::GestureShowPress:
2120 return handleGestureShowPress();
2121 case PlatformEvent::GestureLongPress:
2122 return handleGestureLongPress(targetedEvent);
2123 case PlatformEvent::GestureLongTap:
2124 return handleGestureLongTap(targetedEvent);
2125 case PlatformEvent::GestureTwoFingerTap:
2126 return sendContextMenuEventForGesture(targetedEvent);
2080 case PlatformEvent::GestureTapDown: 2127 case PlatformEvent::GestureTapDown:
2081 case PlatformEvent::GestureShowPress:
2082 case PlatformEvent::GestureTapDownCancel:
2083 case PlatformEvent::GestureTwoFingerTap:
2084 case PlatformEvent::GestureLongPress:
2085 case PlatformEvent::GestureLongTap:
2086 case PlatformEvent::GesturePinchBegin: 2128 case PlatformEvent::GesturePinchBegin:
2087 case PlatformEvent::GesturePinchEnd: 2129 case PlatformEvent::GesturePinchEnd:
2088 case PlatformEvent::GesturePinchUpdate: 2130 case PlatformEvent::GesturePinchUpdate:
2089 adjustGesturePosition(gestureEvent, adjustedPoint); 2131 case PlatformEvent::GestureTapDownCancel:
2090 subframe = getSubFrameForGestureEvent(adjustedPoint, gestureEvent); 2132 case PlatformEvent::GestureTapUnconfirmed:
2091 if (subframe)
2092 return subframe->eventHandler().handleGestureEvent(gestureEvent);
2093 break; 2133 break;
2094
2095 default: 2134 default:
2096 ASSERT_NOT_REACHED(); 2135 ASSERT_NOT_REACHED();
2097 } 2136 }
2098 2137
2138 return false;
2139 }
2140
2141 bool EventHandler::handleGestureScrollEvent(const PlatformGestureEvent& gestureE vent)
2142 {
2099 RefPtrWillBeRawPtr<Node> eventTarget = nullptr; 2143 RefPtrWillBeRawPtr<Node> eventTarget = nullptr;
2100 RefPtr<Scrollbar> scrollbar; 2144 RefPtr<Scrollbar> scrollbar;
2101 if (gestureEvent.type() == PlatformEvent::GestureScrollEnd 2145 if (gestureEvent.type() != PlatformEvent::GestureScrollBegin) {
2102 || gestureEvent.type() == PlatformEvent::GestureScrollUpdate
2103 || gestureEvent.type() == PlatformEvent::GestureScrollUpdateWithoutPropa gation
2104 || gestureEvent.type() == PlatformEvent::GestureFlingStart) {
2105 scrollbar = m_scrollbarHandlingScrollGesture.get(); 2146 scrollbar = m_scrollbarHandlingScrollGesture.get();
2106 eventTarget = m_scrollGestureHandlingNode.get(); 2147 eventTarget = m_scrollGestureHandlingNode.get();
2107 } 2148 }
2108 2149
2109 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent; 2150 if (!eventTarget) {
2110 double activeInterval = 0; 2151 Document* document = m_frame->document();
2111 bool shouldKeepActiveForMinInterval = false; 2152 if (!document->renderView())
2112 if (gestureEvent.type() == PlatformEvent::GestureShowPress 2153 return false;
2113 || gestureEvent.type() == PlatformEvent::GestureTapUnconfirmed) {
2114 hitType |= HitTestRequest::Active;
2115 } else if (gestureEvent.type() == PlatformEvent::GestureTapDownCancel) {
2116 hitType |= HitTestRequest::Release;
2117 // A TapDownCancel received when no element is active shouldn't really b e changing hover state.
2118 if (!m_frame->document()->activeHoverElement())
2119 hitType |= HitTestRequest::ReadOnly;
2120 } else if (gestureEvent.type() == PlatformEvent::GestureTap) {
2121 hitType |= HitTestRequest::Release;
2122 // If the Tap is received very shortly after ShowPress, we want to
2123 // delay clearing of the active state so that it's visible to the user
2124 // for at least a couple of frames.
2125 activeInterval = WTF::currentTime() - m_lastShowPressTimestamp;
2126 shouldKeepActiveForMinInterval = m_lastShowPressTimestamp && activeInter val < minimumActiveInterval;
2127 if (shouldKeepActiveForMinInterval)
2128 hitType |= HitTestRequest::ReadOnly;
2129 }
2130 else
2131 hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly;
2132 2154
2133 if ((!scrollbar && !eventTarget) || !(hitType & HitTestRequest::ReadOnly)) { 2155 FrameView* view = m_frame->view();
2134 IntPoint hitTestPoint = m_frame->view()->windowToContents(adjustedPoint) ; 2156 LayoutPoint viewPoint = view->windowToContents(gestureEvent.position());
2135 HitTestResult result = hitTestResultAtPoint(hitTestPoint, hitType | HitT estRequest::AllowFrameScrollbars); 2157 HitTestRequest request(HitTestRequest::ReadOnly);
2158 HitTestResult result(viewPoint);
2159 document->renderView()->hitTest(request, result);
2136 2160
2137 if (shouldKeepActiveForMinInterval) { 2161 eventTarget = result.innerNode();
2138 m_lastDeferredTapElement = result.innerElement();
2139 m_activeIntervalTimer.startOneShot(minimumActiveInterval - activeInt erval, FROM_HERE);
2140 }
2141 2162
2142 eventTarget = result.targetNode(); 2163 m_lastGestureScrollOverWidget = result.isOverWidget();
2143 if (!scrollbar) { 2164 m_scrollGestureHandlingNode = eventTarget;
2144 FrameView* view = m_frame->view(); 2165 m_previousGestureScrolledNode = nullptr;
2145 scrollbar = view ? view->scrollbarAtPoint(gestureEvent.position()) : 0; 2166
2146 } 2167 if (!scrollbar)
2168 scrollbar = view->scrollbarAtPoint(gestureEvent.position());
2147 if (!scrollbar) 2169 if (!scrollbar)
2148 scrollbar = result.scrollbar(); 2170 scrollbar = result.scrollbar();
2149 } 2171 }
2150 2172
2151 if (scrollbar) { 2173 if (scrollbar) {
2152 bool eventSwallowed = scrollbar->gestureEvent(gestureEvent); 2174 bool eventSwallowed = scrollbar->gestureEvent(gestureEvent);
2153 if (gestureEvent.type() == PlatformEvent::GestureTapDown && eventSwallow ed) { 2175 if (gestureEvent.type() == PlatformEvent::GestureScrollEnd
2154 m_scrollbarHandlingScrollGesture = scrollbar;
2155 } else if (gestureEvent.type() == PlatformEvent::GestureScrollEnd
2156 || gestureEvent.type() == PlatformEvent::GestureFlingStart 2176 || gestureEvent.type() == PlatformEvent::GestureFlingStart
2157 || !eventSwallowed) { 2177 || !eventSwallowed) {
2158 m_scrollbarHandlingScrollGesture = nullptr; 2178 m_scrollbarHandlingScrollGesture = nullptr;
2159 } 2179 }
2160
2161 if (eventSwallowed) 2180 if (eventSwallowed)
2162 return true; 2181 return true;
2163 } 2182 }
2164 2183
2165 if (eventTarget) { 2184 if (eventTarget) {
2166 bool eventSwallowed = false; 2185 bool eventSwallowed = handleScrollGestureOnResizer(eventTarget.get(), ge stureEvent);
2167 if (handleScrollGestureOnResizer(eventTarget.get(), gestureEvent)) 2186 if (!eventSwallowed)
2168 eventSwallowed = true;
2169 else
2170 eventSwallowed = eventTarget->dispatchGestureEvent(gestureEvent); 2187 eventSwallowed = eventTarget->dispatchGestureEvent(gestureEvent);
2171 if (gestureEvent.type() == PlatformEvent::GestureScrollBegin || gestureE vent.type() == PlatformEvent::GestureScrollEnd) {
2172 if (eventSwallowed)
2173 m_scrollGestureHandlingNode = eventTarget;
2174 }
2175
2176 if (eventSwallowed) 2188 if (eventSwallowed)
2177 return true; 2189 return true;
2178 } 2190 }
2179 2191
2180 // FIXME: A more general scroll system (https://bugs.webkit.org/show_bug.cgi ?id=80596) will
2181 // eliminate the need for this.
2182 TemporaryChange<PlatformEvent::Type> baseEventType(m_baseEventType, gestureE vent.type());
2183
2184 switch (gestureEvent.type()) { 2192 switch (gestureEvent.type()) {
2185 case PlatformEvent::GestureScrollBegin: 2193 case PlatformEvent::GestureScrollBegin:
2186 return handleGestureScrollBegin(gestureEvent); 2194 return handleGestureScrollBegin(gestureEvent);
2187 case PlatformEvent::GestureScrollUpdate: 2195 case PlatformEvent::GestureScrollUpdate:
2188 case PlatformEvent::GestureScrollUpdateWithoutPropagation: 2196 case PlatformEvent::GestureScrollUpdateWithoutPropagation:
2189 return handleGestureScrollUpdate(gestureEvent); 2197 return handleGestureScrollUpdate(gestureEvent);
2190 case PlatformEvent::GestureScrollEnd: 2198 case PlatformEvent::GestureScrollEnd:
2191 return handleGestureScrollEnd(gestureEvent); 2199 return handleGestureScrollEnd(gestureEvent);
2192 case PlatformEvent::GestureTap: 2200 case PlatformEvent::GestureFlingStart:
2193 return handleGestureTap(gestureEvent, adjustedPoint);
2194 case PlatformEvent::GestureShowPress:
2195 return handleGestureShowPress();
2196 case PlatformEvent::GestureLongPress:
2197 return handleGestureLongPress(gestureEvent, adjustedPoint);
2198 case PlatformEvent::GestureLongTap:
2199 return handleGestureLongTap(gestureEvent, adjustedPoint);
2200 case PlatformEvent::GestureTwoFingerTap:
2201 return handleGestureTwoFingerTap(gestureEvent, adjustedPoint);
2202 case PlatformEvent::GestureTapDown:
2203 case PlatformEvent::GesturePinchBegin: 2201 case PlatformEvent::GesturePinchBegin:
2204 case PlatformEvent::GesturePinchEnd: 2202 case PlatformEvent::GesturePinchEnd:
2205 case PlatformEvent::GesturePinchUpdate: 2203 case PlatformEvent::GesturePinchUpdate:
2206 case PlatformEvent::GestureTapDownCancel: 2204 return false;
2207 case PlatformEvent::GestureTapUnconfirmed:
2208 case PlatformEvent::GestureFlingStart:
2209 break;
2210 default: 2205 default:
2211 ASSERT_NOT_REACHED(); 2206 ASSERT_NOT_REACHED();
2207 return false;
2212 } 2208 }
2213
2214 return false;
2215 } 2209 }
2216 2210
2217 bool EventHandler::handleGestureTap(const PlatformGestureEvent& gestureEvent, co nst IntPoint& adjustedPoint) 2211 bool EventHandler::handleGestureTap(const GestureEventWithHitTestResults& target edEvent)
2218 { 2212 {
2213 const PlatformGestureEvent& gestureEvent = targetedEvent.event();
2214
2219 // 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. 2215 // 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.
2220 2216
2221 unsigned modifierFlags = 0; 2217 unsigned modifierFlags = 0;
2222 if (gestureEvent.altKey()) 2218 if (gestureEvent.altKey())
2223 modifierFlags |= PlatformEvent::AltKey; 2219 modifierFlags |= PlatformEvent::AltKey;
2224 if (gestureEvent.ctrlKey()) 2220 if (gestureEvent.ctrlKey())
2225 modifierFlags |= PlatformEvent::CtrlKey; 2221 modifierFlags |= PlatformEvent::CtrlKey;
2226 if (gestureEvent.metaKey()) 2222 if (gestureEvent.metaKey())
2227 modifierFlags |= PlatformEvent::MetaKey; 2223 modifierFlags |= PlatformEvent::MetaKey;
2228 if (gestureEvent.shiftKey()) 2224 if (gestureEvent.shiftKey())
2229 modifierFlags |= PlatformEvent::ShiftKey; 2225 modifierFlags |= PlatformEvent::ShiftKey;
2230 PlatformEvent::Modifiers modifiers = static_cast<PlatformEvent::Modifiers>(m odifierFlags); 2226 PlatformEvent::Modifiers modifiers = static_cast<PlatformEvent::Modifiers>(m odifierFlags);
2231 2227
2228 IntPoint adjustedPoint = gestureEvent.position();
2229
2232 PlatformMouseEvent fakeMouseMove(adjustedPoint, gestureEvent.globalPosition( ), 2230 PlatformMouseEvent fakeMouseMove(adjustedPoint, gestureEvent.globalPosition( ),
2233 NoButton, PlatformEvent::MouseMoved, /* clickCount */ 0, 2231 NoButton, PlatformEvent::MouseMoved, /* clickCount */ 0,
2234 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp()); 2232 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp());
2235 handleMouseMoveEvent(fakeMouseMove); 2233 handleMouseMoveEvent(fakeMouseMove);
2236 2234
2237 bool defaultPrevented = false; 2235 bool defaultPrevented = false;
2238 PlatformMouseEvent fakeMouseDown(adjustedPoint, gestureEvent.globalPosition( ), 2236 PlatformMouseEvent fakeMouseDown(adjustedPoint, gestureEvent.globalPosition( ),
2239 LeftButton, PlatformEvent::MousePressed, gestureEvent.tapCount(), 2237 LeftButton, PlatformEvent::MousePressed, gestureEvent.tapCount(),
2240 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp()); 2238 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp());
2241 defaultPrevented |= handleMousePressEvent(fakeMouseDown); 2239 defaultPrevented |= handleMousePressEvent(fakeMouseDown);
2242 2240
2243 PlatformMouseEvent fakeMouseUp(adjustedPoint, gestureEvent.globalPosition(), 2241 PlatformMouseEvent fakeMouseUp(adjustedPoint, gestureEvent.globalPosition(),
2244 LeftButton, PlatformEvent::MouseReleased, gestureEvent.tapCount(), 2242 LeftButton, PlatformEvent::MouseReleased, gestureEvent.tapCount(),
2245 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp()); 2243 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp());
2246 defaultPrevented |= handleMouseReleaseEvent(fakeMouseUp); 2244 defaultPrevented |= handleMouseReleaseEvent(fakeMouseUp);
2247 2245
2248 return defaultPrevented; 2246 return defaultPrevented;
2249 } 2247 }
2250 2248
2251 bool EventHandler::handleGestureLongPress(const PlatformGestureEvent& gestureEve nt, const IntPoint& adjustedPoint) 2249 bool EventHandler::handleGestureLongPress(const GestureEventWithHitTestResults& targetedEvent)
2252 { 2250 {
2251 const PlatformGestureEvent& gestureEvent = targetedEvent.event();
2252 IntPoint adjustedPoint = gestureEvent.position();
2253
2254 // FIXME: Ideally we should try to remove the extra mouse-specific hit-tests here (re-using the
2255 // supplied HitTestResult), but that will require some overhaul of the touch drag-and-drop code
2256 // and LongPress is such a special scenario that it's unlikely to matter muc h in practice.
2257
2253 m_longTapShouldInvokeContextMenu = false; 2258 m_longTapShouldInvokeContextMenu = false;
2254 if (m_frame->settings() && m_frame->settings()->touchDragDropEnabled() && m_ frame->view()) { 2259 if (m_frame->settings() && m_frame->settings()->touchDragDropEnabled() && m_ frame->view()) {
2255 PlatformMouseEvent mouseDownEvent(adjustedPoint, gestureEvent.globalPosi tion(), LeftButton, PlatformEvent::MousePressed, 1, 2260 PlatformMouseEvent mouseDownEvent(adjustedPoint, gestureEvent.globalPosi tion(), LeftButton, PlatformEvent::MousePressed, 1,
2256 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey (), gestureEvent.metaKey(), WTF::currentTime()); 2261 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey (), gestureEvent.metaKey(), WTF::currentTime());
2257 m_mouseDown = mouseDownEvent; 2262 m_mouseDown = mouseDownEvent;
2258 2263
2259 PlatformMouseEvent mouseDragEvent(adjustedPoint, gestureEvent.globalPosi tion(), LeftButton, PlatformEvent::MouseMoved, 1, 2264 PlatformMouseEvent mouseDragEvent(adjustedPoint, gestureEvent.globalPosi tion(), LeftButton, PlatformEvent::MouseMoved, 1,
2260 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey (), gestureEvent.metaKey(), WTF::currentTime()); 2265 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey (), gestureEvent.metaKey(), WTF::currentTime());
2261 HitTestRequest request(HitTestRequest::ReadOnly); 2266 HitTestRequest request(HitTestRequest::ReadOnly);
2262 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDragE vent); 2267 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDragE vent);
(...skipping 18 matching lines...) Expand all
2281 HitTestResult result = hitTestResultAtPoint(hitTestPoint); 2286 HitTestResult result = hitTestResultAtPoint(hitTestPoint);
2282 Node* innerNode = result.targetNode(); 2287 Node* innerNode = result.targetNode();
2283 if (!result.isLiveLink() && innerNode && (innerNode->isContentEditable() || innerNode->isTextNode())) { 2288 if (!result.isLiveLink() && innerNode && (innerNode->isContentEditable() || innerNode->isTextNode())) {
2284 selectClosestWordFromHitTestResult(result, DontAppendTrailingWhitesp ace); 2289 selectClosestWordFromHitTestResult(result, DontAppendTrailingWhitesp ace);
2285 if (m_frame->selection().isRange()) { 2290 if (m_frame->selection().isRange()) {
2286 focusDocumentView(); 2291 focusDocumentView();
2287 return true; 2292 return true;
2288 } 2293 }
2289 } 2294 }
2290 } 2295 }
2291 return sendContextMenuEventForGesture(gestureEvent); 2296 return sendContextMenuEventForGesture(targetedEvent);
2292 } 2297 }
2293 2298
2294 bool EventHandler::handleGestureLongTap(const PlatformGestureEvent& gestureEvent , const IntPoint& adjustedPoint) 2299 bool EventHandler::handleGestureLongTap(const GestureEventWithHitTestResults& ta rgetedEvent)
2295 { 2300 {
2296 #if !OS(ANDROID) 2301 #if !OS(ANDROID)
2297 if (m_longTapShouldInvokeContextMenu) { 2302 if (m_longTapShouldInvokeContextMenu) {
2298 m_longTapShouldInvokeContextMenu = false; 2303 m_longTapShouldInvokeContextMenu = false;
2299 return sendContextMenuEventForGesture(gestureEvent); 2304 return sendContextMenuEventForGesture(targetedEvent);
2300 } 2305 }
2301 #endif 2306 #endif
2302 return false; 2307 return false;
2303 } 2308 }
2304 2309
2305 bool EventHandler::handleScrollGestureOnResizer(Node* eventTarget, const Platfor mGestureEvent& gestureEvent) { 2310 bool EventHandler::handleScrollGestureOnResizer(Node* eventTarget, const Platfor mGestureEvent& gestureEvent) {
2306 if (gestureEvent.type() == PlatformEvent::GestureScrollBegin) { 2311 if (gestureEvent.type() == PlatformEvent::GestureScrollBegin) {
2307 RenderLayer* layer = eventTarget->renderer() ? eventTarget->renderer()-> enclosingLayer() : 0; 2312 RenderLayer* layer = eventTarget->renderer() ? eventTarget->renderer()-> enclosingLayer() : 0;
2308 IntPoint p = m_frame->view()->windowToContents(gestureEvent.position()); 2313 IntPoint p = m_frame->view()->windowToContents(gestureEvent.position());
2309 if (layer && layer->scrollableArea() && layer->scrollableArea()->isPoint InResizeControl(p, ResizerForTouch)) { 2314 if (layer && layer->scrollableArea() && layer->scrollableArea()->isPoint InResizeControl(p, ResizerForTouch)) {
(...skipping 12 matching lines...) Expand all
2322 if (m_resizeScrollableArea && m_resizeScrollableArea->inResizeMode()) { 2327 if (m_resizeScrollableArea && m_resizeScrollableArea->inResizeMode()) {
2323 m_resizeScrollableArea->setInResizeMode(false); 2328 m_resizeScrollableArea->setInResizeMode(false);
2324 m_resizeScrollableArea = 0; 2329 m_resizeScrollableArea = 0;
2325 return false; 2330 return false;
2326 } 2331 }
2327 } 2332 }
2328 2333
2329 return false; 2334 return false;
2330 } 2335 }
2331 2336
2332 bool EventHandler::handleGestureTwoFingerTap(const PlatformGestureEvent& gesture Event, const IntPoint& adjustedPoint) 2337 bool EventHandler::passScrollGestureEventToWidget(const PlatformGestureEvent& ge stureEvent, RenderObject* renderer)
2333 { 2338 {
2334 return sendContextMenuEventForGesture(gestureEvent); 2339 ASSERT(gestureEvent.isScrollEvent());
2335 }
2336 2340
2337 bool EventHandler::passGestureEventToWidget(const PlatformGestureEvent& gestureE vent, Widget* widget) 2341 if (!m_lastGestureScrollOverWidget)
2338 {
2339 if (!widget)
2340 return false; 2342 return false;
2341 2343
2344 if (!renderer || !renderer->isWidget())
2345 return false;
2346
2347 Widget* widget = toRenderWidget(renderer)->widget();
2348
2342 if (!widget->isFrameView()) 2349 if (!widget->isFrameView())
2343 return false; 2350 return false;
2344 2351
2345 return toFrameView(widget)->frame().eventHandler().handleGestureEvent(gestur eEvent); 2352 return toFrameView(widget)->frame().eventHandler().handleGestureScrollEvent( gestureEvent);
2346 }
2347
2348 bool EventHandler::passGestureEventToWidgetIfPossible(const PlatformGestureEvent & gestureEvent, RenderObject* renderer)
2349 {
2350 if (m_lastHitTestResultOverWidget && renderer && renderer->isWidget()) {
2351 Widget* widget = toRenderWidget(renderer)->widget();
2352 return widget && passGestureEventToWidget(gestureEvent, widget);
2353 }
2354 return false;
2355 } 2353 }
2356 2354
2357 bool EventHandler::handleGestureScrollEnd(const PlatformGestureEvent& gestureEve nt) { 2355 bool EventHandler::handleGestureScrollEnd(const PlatformGestureEvent& gestureEve nt) {
2358 RefPtrWillBeRawPtr<Node> node = m_scrollGestureHandlingNode; 2356 RefPtrWillBeRawPtr<Node> node = m_scrollGestureHandlingNode;
2359 clearGestureScrollNodes(); 2357 clearGestureScrollNodes();
2360 2358
2361 if (node) 2359 if (node)
2362 passGestureEventToWidgetIfPossible(gestureEvent, node->renderer()); 2360 passScrollGestureEventToWidget(gestureEvent, node->renderer());
2363 2361
2364 return false; 2362 return false;
2365 } 2363 }
2366 2364
2367 bool EventHandler::handleGestureScrollBegin(const PlatformGestureEvent& gestureE vent) 2365 bool EventHandler::handleGestureScrollBegin(const PlatformGestureEvent& gestureE vent)
2368 { 2366 {
2369 Document* document = m_frame->document(); 2367 Document* document = m_frame->document();
2370 if (!document->renderView()) 2368 if (!document->renderView())
2371 return false; 2369 return false;
2372 2370
2373 FrameView* view = m_frame->view(); 2371 FrameView* view = m_frame->view();
2374 if (!view) 2372 if (!view)
2375 return false; 2373 return false;
2376 2374
2377 LayoutPoint viewPoint = view->windowToContents(gestureEvent.position());
2378 HitTestRequest request(HitTestRequest::ReadOnly);
2379 HitTestResult result(viewPoint);
2380 document->renderView()->hitTest(request, result);
2381
2382 m_lastHitTestResultOverWidget = result.isOverWidget();
2383 m_scrollGestureHandlingNode = result.innerNode();
2384 m_previousGestureScrolledNode = nullptr;
2385
2386 // If there's no renderer on the node, send the event to the nearest ancesto r with a renderer. 2375 // If there's no renderer on the node, send the event to the nearest ancesto r with a renderer.
2387 // Needed for <option> and <optgroup> elements so we can touch scroll <selec t>s 2376 // Needed for <option> and <optgroup> elements so we can touch scroll <selec t>s
2388 while (m_scrollGestureHandlingNode && !m_scrollGestureHandlingNode->renderer ()) 2377 while (m_scrollGestureHandlingNode && !m_scrollGestureHandlingNode->renderer ())
2389 m_scrollGestureHandlingNode = m_scrollGestureHandlingNode->parentOrShado wHostNode(); 2378 m_scrollGestureHandlingNode = m_scrollGestureHandlingNode->parentOrShado wHostNode();
2390 2379
2391 if (!m_scrollGestureHandlingNode) 2380 if (!m_scrollGestureHandlingNode)
2392 return false; 2381 return false;
2393 2382
2394 passGestureEventToWidgetIfPossible(gestureEvent, m_scrollGestureHandlingNode ->renderer()); 2383 passScrollGestureEventToWidget(gestureEvent, m_scrollGestureHandlingNode->re nderer());
2395 2384
2396 return true; 2385 return true;
2397 } 2386 }
2398 2387
2399 bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gesture Event) 2388 bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gesture Event)
2400 { 2389 {
2401 FloatSize delta(gestureEvent.deltaX(), gestureEvent.deltaY()); 2390 FloatSize delta(gestureEvent.deltaX(), gestureEvent.deltaY());
2402 if (delta.isZero()) 2391 if (delta.isZero())
2403 return false; 2392 return false;
2404 2393
2405 const float scaleFactor = m_frame->pageZoomFactor(); 2394 const float scaleFactor = m_frame->pageZoomFactor();
2406 delta.scale(1 / scaleFactor, 1 / scaleFactor); 2395 delta.scale(1 / scaleFactor, 1 / scaleFactor);
2407 2396
2408 Node* node = m_scrollGestureHandlingNode.get(); 2397 Node* node = m_scrollGestureHandlingNode.get();
2409 if (!node) 2398 if (!node)
2410 return sendScrollEventToView(gestureEvent, delta); 2399 return sendScrollEventToView(gestureEvent, delta);
2411 2400
2412 // Ignore this event if the targeted node does not have a valid renderer. 2401 // Ignore this event if the targeted node does not have a valid renderer.
2413 RenderObject* renderer = node->renderer(); 2402 RenderObject* renderer = node->renderer();
2414 if (!renderer) 2403 if (!renderer)
2415 return false; 2404 return false;
2416 2405
2417 RefPtr<FrameView> protector(m_frame->view()); 2406 RefPtr<FrameView> protector(m_frame->view());
2418 2407
2419 Node* stopNode = 0; 2408 Node* stopNode = 0;
2420 bool scrollShouldNotPropagate = gestureEvent.type() == PlatformEvent::Gestur eScrollUpdateWithoutPropagation; 2409 bool scrollShouldNotPropagate = gestureEvent.type() == PlatformEvent::Gestur eScrollUpdateWithoutPropagation;
2421 2410
2422 // Try to send the event to the correct view. 2411 // Try to send the event to the correct view.
2423 if (passGestureEventToWidgetIfPossible(gestureEvent, renderer)) { 2412 if (passScrollGestureEventToWidget(gestureEvent, renderer)) {
2424 if(scrollShouldNotPropagate) 2413 if(scrollShouldNotPropagate)
2425 m_previousGestureScrolledNode = m_scrollGestureHandlingNode; 2414 m_previousGestureScrolledNode = m_scrollGestureHandlingNode;
2426 2415
2427 return true; 2416 return true;
2428 } 2417 }
2429 2418
2430 if (scrollShouldNotPropagate) 2419 if (scrollShouldNotPropagate)
2431 stopNode = m_previousGestureScrolledNode.get(); 2420 stopNode = m_previousGestureScrolledNode.get();
2432 2421
2433 // First try to scroll the closest scrollable RenderBox ancestor of |node|. 2422 // First try to scroll the closest scrollable RenderBox ancestor of |node|.
(...skipping 29 matching lines...) Expand all
2463 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey()); 2452 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey());
2464 syntheticWheelEvent.setHasPreciseScrollingDeltas(true); 2453 syntheticWheelEvent.setHasPreciseScrollingDeltas(true);
2465 2454
2466 bool scrolledFrame = view->wheelEvent(syntheticWheelEvent); 2455 bool scrolledFrame = view->wheelEvent(syntheticWheelEvent);
2467 if (scrolledFrame) 2456 if (scrolledFrame)
2468 setFrameWasScrolledByUser(); 2457 setFrameWasScrolledByUser();
2469 2458
2470 return scrolledFrame; 2459 return scrolledFrame;
2471 } 2460 }
2472 2461
2473 LocalFrame* EventHandler::getSubFrameForGestureEvent(const IntPoint& touchAdjust edPoint, const PlatformGestureEvent& gestureEvent)
2474 {
2475 PlatformMouseEvent mouseDown(touchAdjustedPoint, gestureEvent.globalPosition (), LeftButton, PlatformEvent::MousePressed, 1,
2476 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), gestureEvent.timestamp());
2477 HitTestRequest request(HitTestRequest::ReadOnly);
2478 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDown);
2479 return subframeForHitTestResult(mev);
2480 }
2481
2482 void EventHandler::clearGestureScrollNodes() 2462 void EventHandler::clearGestureScrollNodes()
2483 { 2463 {
2484 m_scrollGestureHandlingNode = nullptr; 2464 m_scrollGestureHandlingNode = nullptr;
2485 m_previousGestureScrolledNode = nullptr; 2465 m_previousGestureScrolledNode = nullptr;
2486 } 2466 }
2487 2467
2488 bool EventHandler::isScrollbarHandlingGestures() const 2468 bool EventHandler::isScrollbarHandlingGestures() const
2489 { 2469 {
2490 return m_scrollbarHandlingScrollGesture.get(); 2470 return m_scrollbarHandlingScrollGesture.get();
2491 } 2471 }
2492 2472
2493 bool EventHandler::shouldApplyTouchAdjustment(const PlatformGestureEvent& event) const 2473 bool EventHandler::shouldApplyTouchAdjustment(const PlatformGestureEvent& event) const
2494 { 2474 {
2495 if (m_frame->settings() && !m_frame->settings()->touchAdjustmentEnabled()) 2475 if (m_frame->settings() && !m_frame->settings()->touchAdjustmentEnabled())
2496 return false; 2476 return false;
2497 return !event.area().isEmpty(); 2477 return !event.area().isEmpty();
2498 } 2478 }
2499 2479
2500 bool EventHandler::bestClickableNodeForTouchPoint(const IntPoint& touchCenter, c onst IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode) 2480 bool EventHandler::bestClickableNodeForHitTestResult(const HitTestResult& result , IntPoint& targetPoint, Node*& targetNode)
2501 { 2481 {
2502 IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter); 2482 // FIXME: Unify this with the other best* functions which are very similar.
2503 HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::Re adOnly | HitTestRequest::Active, touchRadius); 2483
2484 TRACE_EVENT0("input", "EventHandler::bestClickableNodeForHitTestResult");
2485 ASSERT(result.isRectBasedTest());
2504 2486
2505 // If the touch is over a scrollbar, don't adjust the touch point since touc h adjustment only takes into account 2487 // If the touch is over a scrollbar, don't adjust the touch point since touc h adjustment only takes into account
2506 // DOM nodes so a touch over a scrollbar will be adjusted towards nearby nod es. This leads to things like textarea 2488 // DOM nodes so a touch over a scrollbar will be adjusted towards nearby nod es. This leads to things like textarea
2507 // scrollbars being untouchable. 2489 // scrollbars being untouchable.
2508 if (result.scrollbar()) 2490 if (result.scrollbar())
2509 return false; 2491 return false;
2510 2492
2511 IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius); 2493 IntPoint touchCenter = m_frame->view()->contentsToWindow(result.roundedPoint InMainFrame());
2494 IntRect touchRect = m_frame->view()->contentsToWindow(result.hitTestLocation ().boundingBox());
2495
2512 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes; 2496 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes;
2513 copyToVector(result.rectBasedTestResult(), nodes); 2497 copyToVector(result.rectBasedTestResult(), nodes);
2514 2498
2515 // FIXME: Should be able to handle targetNode being a shadow DOM node to avo id performing uncessary hit tests 2499 // FIXME: Should be able to handle targetNode being a shadow DOM node to avo id performing uncessary hit tests
2516 // in the case where further processing on the node is required. Returning t he shadow ancestor prevents a 2500 // in the case where further processing on the node is required. Returning t he shadow ancestor prevents a
2517 // regression in touchadjustment/html-label.html. Some refinement is require d to testing/internals to 2501 // regression in touchadjustment/html-label.html. Some refinement is require d to testing/internals to
2518 // handle targetNode being a shadow DOM node. 2502 // handle targetNode being a shadow DOM node.
2519 2503
2520 // FIXME: the explicit Vector conversion copies into a temporary and is wast eful. 2504 // FIXME: the explicit Vector conversion copies into a temporary and is wast eful.
2521 // FIXME: targetNode and success are only used by Internals functions. We sh ould 2505 // FIXME: targetNode and success are only used by Internals functions. We sh ould
2522 // instead have dedicated test methods so we only do this work in tests. 2506 // instead have dedicated test methods so we only do this work in tests.
2523 bool success = findBestClickableCandidate(targetNode, targetPoint, touchCent er, touchRect, WillBeHeapVector<RefPtrWillBeMember<Node> > (nodes)); 2507 bool success = findBestClickableCandidate(targetNode, targetPoint, touchCent er, touchRect, WillBeHeapVector<RefPtrWillBeMember<Node> > (nodes));
2524 if (success && targetNode) 2508 if (success && targetNode)
2525 targetNode = targetNode->deprecatedShadowAncestorNode(); 2509 targetNode = targetNode->deprecatedShadowAncestorNode();
2526 return success; 2510 return success;
2527 } 2511 }
2528 2512
2529 bool EventHandler::bestContextMenuNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode) 2513 bool EventHandler::bestContextMenuNodeForHitTestResult(const HitTestResult& resu lt, IntPoint& targetPoint, Node*& targetNode)
2530 { 2514 {
2531 IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter); 2515 ASSERT(result.isRectBasedTest());
2532 HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::Re adOnly | HitTestRequest::Active, touchRadius); 2516 IntPoint touchCenter = m_frame->view()->contentsToWindow(result.roundedPoint InMainFrame());
2533 2517 IntRect touchRect = m_frame->view()->contentsToWindow(result.hitTestLocation ().boundingBox());
2534 IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius);
2535 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes; 2518 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes;
2536 copyToVector(result.rectBasedTestResult(), nodes); 2519 copyToVector(result.rectBasedTestResult(), nodes);
2537 2520
2538 // FIXME: the explicit Vector conversion copies into a temporary and is wast eful. 2521 // FIXME: the explicit Vector conversion copies into a temporary and is wast eful.
2539 return findBestContextMenuCandidate(targetNode, targetPoint, touchCenter, to uchRect, WillBeHeapVector<RefPtrWillBeMember<Node> >(nodes)); 2522 return findBestContextMenuCandidate(targetNode, targetPoint, touchCenter, to uchRect, WillBeHeapVector<RefPtrWillBeMember<Node> >(nodes));
2540 } 2523 }
2541 2524
2542 bool EventHandler::bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, co nst IntSize& touchRadius, IntRect& targetArea, Node*& targetNode) 2525 bool EventHandler::bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, co nst IntSize& touchRadius, IntRect& targetArea, Node*& targetNode)
2543 { 2526 {
2544 IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter); 2527 IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter);
2545 HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::Re adOnly | HitTestRequest::Active, touchRadius); 2528 HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::Re adOnly | HitTestRequest::Active, touchRadius);
2546 2529
2547 IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius); 2530 IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius);
2548 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes; 2531 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes;
2549 copyToVector(result.rectBasedTestResult(), nodes); 2532 copyToVector(result.rectBasedTestResult(), nodes);
2550 2533
2551 // FIXME: the explicit Vector conversion copies into a temporary and is wast eful. 2534 // FIXME: the explicit Vector conversion copies into a temporary and is wast eful.
2552 return findBestZoomableArea(targetNode, targetArea, touchCenter, touchRect, WillBeHeapVector<RefPtrWillBeMember<Node> >(nodes)); 2535 return findBestZoomableArea(targetNode, targetArea, touchCenter, touchRect, WillBeHeapVector<RefPtrWillBeMember<Node> >(nodes));
2553 } 2536 }
2554 2537
2555 void EventHandler::adjustGesturePosition(const PlatformGestureEvent& gestureEven t, IntPoint& adjustedPoint) 2538 GestureEventWithHitTestResults EventHandler::targetGestureEvent(const PlatformGe stureEvent& gestureEvent, bool readOnly)
2556 { 2539 {
2557 if (!shouldApplyTouchAdjustment(gestureEvent)) 2540 ASSERT(m_frame == m_frame->localFrameRoot());
2541 // Scrolling events get hit tested per frame (like wheel events do).
2542 ASSERT(!gestureEvent.isScrollEvent());
2543
2544 HitTestRequest::HitTestRequestType hitType = getHitTypeForGestureType(gestur eEvent.type());
2545 double activeInterval = 0;
2546 bool shouldKeepActiveForMinInterval = false;
2547 if (readOnly) {
2548 hitType |= HitTestRequest::ReadOnly;
2549 } else if (gestureEvent.type() == PlatformEvent::GestureTap) {
2550 // If the Tap is received very shortly after ShowPress, we want to
2551 // delay clearing of the active state so that it's visible to the user
2552 // for at least a couple of frames.
2553 activeInterval = WTF::currentTime() - m_lastShowPressTimestamp;
2554 shouldKeepActiveForMinInterval = m_lastShowPressTimestamp && activeInter val < minimumActiveInterval;
2555 if (shouldKeepActiveForMinInterval)
2556 hitType |= HitTestRequest::ReadOnly;
2557 }
2558
2559 // Perform the rect-based hit-test. Note that we don't yet apply hover/activ e state here
2560 // because we need to resolve touch adjustment first so that we apply hover/ active it to
2561 // the final adjusted node.
2562 IntPoint hitTestPoint = m_frame->view()->windowToContents(gestureEvent.posit ion());
2563 IntSize touchRadius = gestureEvent.area();
2564 touchRadius.scale(1.f / 2);
2565 HitTestResult hitTestResult = hitTestResultAtPoint(hitTestPoint, hitType | H itTestRequest::ReadOnly, touchRadius);
2566
2567 // Adjust the location of the gesture to the most likely nearby node, as app ropriate for the
2568 // type of event.
2569 PlatformGestureEvent adjustedEvent = gestureEvent;
2570 applyTouchAdjustment(&adjustedEvent, &hitTestResult);
2571
2572 // Now apply hover/active state to the final target.
2573 // FIXME: This is supposed to send mouseenter/mouseleave events, but doesn't because we
2574 // aren't passing a PlatformMouseEvent.
2575 HitTestRequest request(hitType | HitTestRequest::AllowChildFrameContent);
2576 if (!request.readOnly())
2577 m_frame->document()->updateHoverActiveState(request, hitTestResult.inner Element());
2578
2579 if (shouldKeepActiveForMinInterval) {
2580 m_lastDeferredTapElement = hitTestResult.innerElement();
2581 m_activeIntervalTimer.startOneShot(minimumActiveInterval - activeInterva l, FROM_HERE);
2582 }
2583
2584 return GestureEventWithHitTestResults(adjustedEvent, hitTestResult);
2585 }
2586
2587 HitTestRequest::HitTestRequestType EventHandler::getHitTypeForGestureType(Platfo rmEvent::Type type)
2588 {
2589 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent | Hi tTestRequest::AllowFrameScrollbars;
2590 switch (type) {
2591 case PlatformEvent::GestureShowPress:
2592 case PlatformEvent::GestureTapUnconfirmed:
2593 return hitType | HitTestRequest::Active;
2594 case PlatformEvent::GestureTapDownCancel:
2595 // A TapDownCancel received when no element is active shouldn't really b e changing hover state.
2596 if (!m_frame->document()->activeHoverElement())
2597 hitType |= HitTestRequest::ReadOnly;
2598 return hitType | HitTestRequest::Release;
2599 case PlatformEvent::GestureTap:
2600 return hitType | HitTestRequest::Release;
2601 case PlatformEvent::GestureTapDown:
2602 case PlatformEvent::GestureLongPress:
2603 case PlatformEvent::GestureLongTap:
2604 case PlatformEvent::GestureTwoFingerTap:
2605 // FIXME: Shouldn't LongTap and TwoFingerTap clear the Active state?
2606 return hitType | HitTestRequest::Active | HitTestRequest::ReadOnly;
2607 default:
2608 ASSERT_NOT_REACHED();
2609 return hitType | HitTestRequest::Active | HitTestRequest::ReadOnly;
2610 }
2611 }
2612
2613 void EventHandler::applyTouchAdjustment(PlatformGestureEvent* gestureEvent, HitT estResult* hitTestResult)
2614 {
2615 if (!shouldApplyTouchAdjustment(*gestureEvent))
2558 return; 2616 return;
2559 2617
2560 Node* targetNode = 0; 2618 Node* adjustedNode = 0;
2561 switch (gestureEvent.type()) { 2619 IntPoint adjustedPoint = gestureEvent->position();
2620 IntSize radius = gestureEvent->area();
2621 radius.scale(1.f / 2);
2622 bool adjusted = false;
2623 switch (gestureEvent->type()) {
2562 case PlatformEvent::GestureTap: 2624 case PlatformEvent::GestureTap:
2563 case PlatformEvent::GestureTapUnconfirmed: 2625 case PlatformEvent::GestureTapUnconfirmed:
2564 case PlatformEvent::GestureTapDown: 2626 case PlatformEvent::GestureTapDown:
2565 case PlatformEvent::GestureShowPress: 2627 case PlatformEvent::GestureShowPress:
2566 bestClickableNodeForTouchPoint(gestureEvent.position(), IntSize(gestureE vent.area().width() / 2, gestureEvent.area().height() / 2), adjustedPoint, targe tNode); 2628 adjusted = bestClickableNodeForHitTestResult(*hitTestResult, adjustedPoi nt, adjustedNode);
2567 break; 2629 break;
2568 case PlatformEvent::GestureLongPress: 2630 case PlatformEvent::GestureLongPress:
2569 case PlatformEvent::GestureLongTap: 2631 case PlatformEvent::GestureLongTap:
2570 case PlatformEvent::GestureTwoFingerTap: 2632 case PlatformEvent::GestureTwoFingerTap:
2571 bestContextMenuNodeForTouchPoint(gestureEvent.position(), IntSize(gestur eEvent.area().width() / 2, gestureEvent.area().height() / 2), adjustedPoint, tar getNode); 2633 adjusted = bestContextMenuNodeForHitTestResult(*hitTestResult, adjustedP oint, adjustedNode);
2572 break; 2634 break;
2573 default: 2635 default:
2574 // FIXME: Implement handling for other types as needed.
2575 ASSERT_NOT_REACHED(); 2636 ASSERT_NOT_REACHED();
2576 } 2637 }
2638
2639 if (adjusted) {
2640 hitTestResult->resolveRectBasedTest(adjustedNode, m_frame->view()->windo wToContents(adjustedPoint));
2641 gestureEvent->applyTouchAdjustment(adjustedPoint);
2642 }
2577 } 2643 }
2578 2644
2579 bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event) 2645 bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
2580 { 2646 {
2581 Document* doc = m_frame->document(); 2647 Document* doc = m_frame->document();
2582 FrameView* v = m_frame->view(); 2648 FrameView* v = m_frame->view();
2583 if (!v) 2649 if (!v)
2584 return false; 2650 return false;
2585 2651
2586 // Clear mouse press state to avoid initiating a drag while context menu is up. 2652 // 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
2673 #else 2739 #else
2674 PlatformEvent::Type eventType = PlatformEvent::MousePressed; 2740 PlatformEvent::Type eventType = PlatformEvent::MousePressed;
2675 #endif 2741 #endif
2676 2742
2677 PlatformMouseEvent mouseEvent(position, globalPosition, RightButton, eventTy pe, 1, false, false, false, false, WTF::currentTime()); 2743 PlatformMouseEvent mouseEvent(position, globalPosition, RightButton, eventTy pe, 1, false, false, false, false, WTF::currentTime());
2678 2744
2679 handleMousePressEvent(mouseEvent); 2745 handleMousePressEvent(mouseEvent);
2680 return sendContextMenuEvent(mouseEvent); 2746 return sendContextMenuEvent(mouseEvent);
2681 } 2747 }
2682 2748
2683 bool EventHandler::sendContextMenuEventForGesture(const PlatformGestureEvent& ev ent) 2749 bool EventHandler::sendContextMenuEventForGesture(const GestureEventWithHitTestR esults& targetedEvent)
2684 { 2750 {
2685 #if OS(WIN) 2751 #if OS(WIN)
2686 PlatformEvent::Type eventType = PlatformEvent::MouseReleased; 2752 PlatformEvent::Type eventType = PlatformEvent::MouseReleased;
2687 #else 2753 #else
2688 PlatformEvent::Type eventType = PlatformEvent::MousePressed; 2754 PlatformEvent::Type eventType = PlatformEvent::MousePressed;
2689 #endif 2755 #endif
2690 2756
2691 IntPoint adjustedPoint = event.position(); 2757 PlatformMouseEvent mouseEvent(targetedEvent.event().position(), targetedEven t.event().globalPosition(), RightButton, eventType, 1, false, false, false, fals e, WTF::currentTime());
2692 adjustGesturePosition(event, adjustedPoint);
2693 PlatformMouseEvent mouseEvent(adjustedPoint, event.globalPosition(), RightBu tton, eventType, 1, false, false, false, false, WTF::currentTime());
2694 // To simulate right-click behavior, we send a right mouse down and then 2758 // To simulate right-click behavior, we send a right mouse down and then
2695 // context menu event. 2759 // context menu event.
2760 // FIXME: Send HitTestResults to avoid redundant hit tests.
2696 handleMousePressEvent(mouseEvent); 2761 handleMousePressEvent(mouseEvent);
2697 return sendContextMenuEvent(mouseEvent); 2762 return sendContextMenuEvent(mouseEvent);
2698 // We do not need to send a corresponding mouse release because in case of 2763 // We do not need to send a corresponding mouse release because in case of
2699 // right-click, the context menu takes capture and consumes all events. 2764 // right-click, the context menu takes capture and consumes all events.
2700 } 2765 }
2701 2766
2702 void EventHandler::scheduleHoverStateUpdate() 2767 void EventHandler::scheduleHoverStateUpdate()
2703 { 2768 {
2704 if (!m_hoverTimer.isActive()) 2769 if (!m_hoverTimer.isActive())
2705 m_hoverTimer.startOneShot(0, FROM_HERE); 2770 m_hoverTimer.startOneShot(0, FROM_HERE);
(...skipping 1050 matching lines...) Expand 10 before | Expand all | Expand 10 after
3756 unsigned EventHandler::accessKeyModifiers() 3821 unsigned EventHandler::accessKeyModifiers()
3757 { 3822 {
3758 #if OS(MACOSX) 3823 #if OS(MACOSX)
3759 return PlatformEvent::CtrlKey | PlatformEvent::AltKey; 3824 return PlatformEvent::CtrlKey | PlatformEvent::AltKey;
3760 #else 3825 #else
3761 return PlatformEvent::AltKey; 3826 return PlatformEvent::AltKey;
3762 #endif 3827 #endif
3763 } 3828 }
3764 3829
3765 } // namespace WebCore 3830 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/page/EventHandler.h ('k') | Source/core/page/EventWithHitTestResults.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698