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

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: Esprehn CR feedback 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 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();
2212 } 2207 }
2213
2214 return false;
2215 } 2208 }
2216 2209
2217 bool EventHandler::handleGestureTap(const PlatformGestureEvent& gestureEvent, co nst IntPoint& adjustedPoint) 2210 bool EventHandler::handleGestureTap(const GestureEventWithHitTestResults& target edEvent)
2218 { 2211 {
2212 const PlatformGestureEvent& gestureEvent = targetedEvent.event();
2213
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. 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.
2220 2215
2221 unsigned modifierFlags = 0; 2216 unsigned modifierFlags = 0;
2222 if (gestureEvent.altKey()) 2217 if (gestureEvent.altKey())
2223 modifierFlags |= PlatformEvent::AltKey; 2218 modifierFlags |= PlatformEvent::AltKey;
2224 if (gestureEvent.ctrlKey()) 2219 if (gestureEvent.ctrlKey())
2225 modifierFlags |= PlatformEvent::CtrlKey; 2220 modifierFlags |= PlatformEvent::CtrlKey;
2226 if (gestureEvent.metaKey()) 2221 if (gestureEvent.metaKey())
2227 modifierFlags |= PlatformEvent::MetaKey; 2222 modifierFlags |= PlatformEvent::MetaKey;
2228 if (gestureEvent.shiftKey()) 2223 if (gestureEvent.shiftKey())
2229 modifierFlags |= PlatformEvent::ShiftKey; 2224 modifierFlags |= PlatformEvent::ShiftKey;
2230 PlatformEvent::Modifiers modifiers = static_cast<PlatformEvent::Modifiers>(m odifierFlags); 2225 PlatformEvent::Modifiers modifiers = static_cast<PlatformEvent::Modifiers>(m odifierFlags);
2231 2226
2227 IntPoint adjustedPoint = gestureEvent.position();
2228
2232 PlatformMouseEvent fakeMouseMove(adjustedPoint, gestureEvent.globalPosition( ), 2229 PlatformMouseEvent fakeMouseMove(adjustedPoint, gestureEvent.globalPosition( ),
2233 NoButton, PlatformEvent::MouseMoved, /* clickCount */ 0, 2230 NoButton, PlatformEvent::MouseMoved, /* clickCount */ 0,
2234 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp()); 2231 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp());
2235 handleMouseMoveEvent(fakeMouseMove); 2232 handleMouseMoveEvent(fakeMouseMove);
2236 2233
2237 bool defaultPrevented = false; 2234 bool defaultPrevented = false;
2238 PlatformMouseEvent fakeMouseDown(adjustedPoint, gestureEvent.globalPosition( ), 2235 PlatformMouseEvent fakeMouseDown(adjustedPoint, gestureEvent.globalPosition( ),
2239 LeftButton, PlatformEvent::MousePressed, gestureEvent.tapCount(), 2236 LeftButton, PlatformEvent::MousePressed, gestureEvent.tapCount(),
2240 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp()); 2237 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp());
2241 defaultPrevented |= handleMousePressEvent(fakeMouseDown); 2238 defaultPrevented |= handleMousePressEvent(fakeMouseDown);
2242 2239
2243 PlatformMouseEvent fakeMouseUp(adjustedPoint, gestureEvent.globalPosition(), 2240 PlatformMouseEvent fakeMouseUp(adjustedPoint, gestureEvent.globalPosition(),
2244 LeftButton, PlatformEvent::MouseReleased, gestureEvent.tapCount(), 2241 LeftButton, PlatformEvent::MouseReleased, gestureEvent.tapCount(),
2245 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp()); 2242 modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp());
2246 defaultPrevented |= handleMouseReleaseEvent(fakeMouseUp); 2243 defaultPrevented |= handleMouseReleaseEvent(fakeMouseUp);
2247 2244
2248 return defaultPrevented; 2245 return defaultPrevented;
2249 } 2246 }
2250 2247
2251 bool EventHandler::handleGestureLongPress(const PlatformGestureEvent& gestureEve nt, const IntPoint& adjustedPoint) 2248 bool EventHandler::handleGestureLongPress(const GestureEventWithHitTestResults& targetedEvent)
2252 { 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
2253 m_longTapShouldInvokeContextMenu = false; 2257 m_longTapShouldInvokeContextMenu = false;
2254 if (m_frame->settings() && m_frame->settings()->touchDragDropEnabled() && m_ frame->view()) { 2258 if (m_frame->settings() && m_frame->settings()->touchDragDropEnabled() && m_ frame->view()) {
2255 PlatformMouseEvent mouseDownEvent(adjustedPoint, gestureEvent.globalPosi tion(), LeftButton, PlatformEvent::MousePressed, 1, 2259 PlatformMouseEvent mouseDownEvent(adjustedPoint, gestureEvent.globalPosi tion(), LeftButton, PlatformEvent::MousePressed, 1,
2256 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey (), gestureEvent.metaKey(), WTF::currentTime()); 2260 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey (), gestureEvent.metaKey(), WTF::currentTime());
2257 m_mouseDown = mouseDownEvent; 2261 m_mouseDown = mouseDownEvent;
2258 2262
2259 PlatformMouseEvent mouseDragEvent(adjustedPoint, gestureEvent.globalPosi tion(), LeftButton, PlatformEvent::MouseMoved, 1, 2263 PlatformMouseEvent mouseDragEvent(adjustedPoint, gestureEvent.globalPosi tion(), LeftButton, PlatformEvent::MouseMoved, 1,
2260 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey (), gestureEvent.metaKey(), WTF::currentTime()); 2264 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey (), gestureEvent.metaKey(), WTF::currentTime());
2261 HitTestRequest request(HitTestRequest::ReadOnly); 2265 HitTestRequest request(HitTestRequest::ReadOnly);
2262 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDragE vent); 2266 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDragE vent);
(...skipping 18 matching lines...) Expand all
2281 HitTestResult result = hitTestResultAtPoint(hitTestPoint); 2285 HitTestResult result = hitTestResultAtPoint(hitTestPoint);
2282 Node* innerNode = result.targetNode(); 2286 Node* innerNode = result.targetNode();
2283 if (!result.isLiveLink() && innerNode && (innerNode->isContentEditable() || innerNode->isTextNode())) { 2287 if (!result.isLiveLink() && innerNode && (innerNode->isContentEditable() || innerNode->isTextNode())) {
2284 selectClosestWordFromHitTestResult(result, DontAppendTrailingWhitesp ace); 2288 selectClosestWordFromHitTestResult(result, DontAppendTrailingWhitesp ace);
2285 if (m_frame->selection().isRange()) { 2289 if (m_frame->selection().isRange()) {
2286 focusDocumentView(); 2290 focusDocumentView();
2287 return true; 2291 return true;
2288 } 2292 }
2289 } 2293 }
2290 } 2294 }
2291 return sendContextMenuEventForGesture(gestureEvent); 2295 return sendContextMenuEventForGesture(targetedEvent);
2292 } 2296 }
2293 2297
2294 bool EventHandler::handleGestureLongTap(const PlatformGestureEvent& gestureEvent , const IntPoint& adjustedPoint) 2298 bool EventHandler::handleGestureLongTap(const GestureEventWithHitTestResults& ta rgetedEvent)
2295 { 2299 {
2296 #if !OS(ANDROID) 2300 #if !OS(ANDROID)
2297 if (m_longTapShouldInvokeContextMenu) { 2301 if (m_longTapShouldInvokeContextMenu) {
2298 m_longTapShouldInvokeContextMenu = false; 2302 m_longTapShouldInvokeContextMenu = false;
2299 return sendContextMenuEventForGesture(gestureEvent); 2303 return sendContextMenuEventForGesture(targetedEvent);
2300 } 2304 }
2301 #endif 2305 #endif
2302 return false; 2306 return false;
2303 } 2307 }
2304 2308
2305 bool EventHandler::handleScrollGestureOnResizer(Node* eventTarget, const Platfor mGestureEvent& gestureEvent) { 2309 bool EventHandler::handleScrollGestureOnResizer(Node* eventTarget, const Platfor mGestureEvent& gestureEvent) {
2306 if (gestureEvent.type() == PlatformEvent::GestureScrollBegin) { 2310 if (gestureEvent.type() == PlatformEvent::GestureScrollBegin) {
2307 RenderLayer* layer = eventTarget->renderer() ? eventTarget->renderer()-> enclosingLayer() : 0; 2311 RenderLayer* layer = eventTarget->renderer() ? eventTarget->renderer()-> enclosingLayer() : 0;
2308 IntPoint p = m_frame->view()->windowToContents(gestureEvent.position()); 2312 IntPoint p = m_frame->view()->windowToContents(gestureEvent.position());
2309 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
2322 if (m_resizeScrollableArea && m_resizeScrollableArea->inResizeMode()) { 2326 if (m_resizeScrollableArea && m_resizeScrollableArea->inResizeMode()) {
2323 m_resizeScrollableArea->setInResizeMode(false); 2327 m_resizeScrollableArea->setInResizeMode(false);
2324 m_resizeScrollableArea = 0; 2328 m_resizeScrollableArea = 0;
2325 return false; 2329 return false;
2326 } 2330 }
2327 } 2331 }
2328 2332
2329 return false; 2333 return false;
2330 } 2334 }
2331 2335
2332 bool EventHandler::handleGestureTwoFingerTap(const PlatformGestureEvent& gesture Event, const IntPoint& adjustedPoint) 2336 bool EventHandler::passScrollGestureEventToWidget(const PlatformGestureEvent& ge stureEvent, RenderObject* renderer)
2333 { 2337 {
2334 return sendContextMenuEventForGesture(gestureEvent); 2338 ASSERT(gestureEvent.isScrollEvent());
2335 }
2336 2339
2337 bool EventHandler::passGestureEventToWidget(const PlatformGestureEvent& gestureE vent, Widget* widget) 2340 if (!m_lastGestureScrollOverWidget)
2338 {
2339 if (!widget)
2340 return false; 2341 return false;
2341 2342
2343 if (!renderer || !renderer->isWidget())
2344 return false;
2345
2346 Widget* widget = toRenderWidget(renderer)->widget();
2347
2342 if (!widget->isFrameView()) 2348 if (!widget->isFrameView())
2343 return false; 2349 return false;
2344 2350
2345 return toFrameView(widget)->frame().eventHandler().handleGestureEvent(gestur eEvent); 2351 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 } 2352 }
2356 2353
2357 bool EventHandler::handleGestureScrollEnd(const PlatformGestureEvent& gestureEve nt) { 2354 bool EventHandler::handleGestureScrollEnd(const PlatformGestureEvent& gestureEve nt) {
2358 RefPtrWillBeRawPtr<Node> node = m_scrollGestureHandlingNode; 2355 RefPtrWillBeRawPtr<Node> node = m_scrollGestureHandlingNode;
2359 clearGestureScrollNodes(); 2356 clearGestureScrollNodes();
2360 2357
2361 if (node) 2358 if (node)
2362 passGestureEventToWidgetIfPossible(gestureEvent, node->renderer()); 2359 passScrollGestureEventToWidget(gestureEvent, node->renderer());
2363 2360
2364 return false; 2361 return false;
2365 } 2362 }
2366 2363
2367 bool EventHandler::handleGestureScrollBegin(const PlatformGestureEvent& gestureE vent) 2364 bool EventHandler::handleGestureScrollBegin(const PlatformGestureEvent& gestureE vent)
2368 { 2365 {
2369 Document* document = m_frame->document(); 2366 Document* document = m_frame->document();
2370 if (!document->renderView()) 2367 if (!document->renderView())
2371 return false; 2368 return false;
2372 2369
2373 FrameView* view = m_frame->view(); 2370 FrameView* view = m_frame->view();
2374 if (!view) 2371 if (!view)
2375 return false; 2372 return false;
2376 2373
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. 2374 // 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 2375 // Needed for <option> and <optgroup> elements so we can touch scroll <selec t>s
2388 while (m_scrollGestureHandlingNode && !m_scrollGestureHandlingNode->renderer ()) 2376 while (m_scrollGestureHandlingNode && !m_scrollGestureHandlingNode->renderer ())
2389 m_scrollGestureHandlingNode = m_scrollGestureHandlingNode->parentOrShado wHostNode(); 2377 m_scrollGestureHandlingNode = m_scrollGestureHandlingNode->parentOrShado wHostNode();
2390 2378
2391 if (!m_scrollGestureHandlingNode) 2379 if (!m_scrollGestureHandlingNode)
2392 return false; 2380 return false;
2393 2381
2394 passGestureEventToWidgetIfPossible(gestureEvent, m_scrollGestureHandlingNode ->renderer()); 2382 passScrollGestureEventToWidget(gestureEvent, m_scrollGestureHandlingNode->re nderer());
2395 2383
2396 return true; 2384 return true;
2397 } 2385 }
2398 2386
2399 bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gesture Event) 2387 bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gesture Event)
2400 { 2388 {
2401 FloatSize delta(gestureEvent.deltaX(), gestureEvent.deltaY()); 2389 FloatSize delta(gestureEvent.deltaX(), gestureEvent.deltaY());
2402 if (delta.isZero()) 2390 if (delta.isZero())
2403 return false; 2391 return false;
2404 2392
2405 const float scaleFactor = m_frame->pageZoomFactor(); 2393 const float scaleFactor = m_frame->pageZoomFactor();
2406 delta.scale(1 / scaleFactor, 1 / scaleFactor); 2394 delta.scale(1 / scaleFactor, 1 / scaleFactor);
2407 2395
2408 Node* node = m_scrollGestureHandlingNode.get(); 2396 Node* node = m_scrollGestureHandlingNode.get();
2409 if (!node) 2397 if (!node)
2410 return sendScrollEventToView(gestureEvent, delta); 2398 return sendScrollEventToView(gestureEvent, delta);
2411 2399
2412 // 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.
2413 RenderObject* renderer = node->renderer(); 2401 RenderObject* renderer = node->renderer();
2414 if (!renderer) 2402 if (!renderer)
2415 return false; 2403 return false;
2416 2404
2417 RefPtr<FrameView> protector(m_frame->view()); 2405 RefPtr<FrameView> protector(m_frame->view());
2418 2406
2419 Node* stopNode = 0; 2407 Node* stopNode = 0;
2420 bool scrollShouldNotPropagate = gestureEvent.type() == PlatformEvent::Gestur eScrollUpdateWithoutPropagation; 2408 bool scrollShouldNotPropagate = gestureEvent.type() == PlatformEvent::Gestur eScrollUpdateWithoutPropagation;
2421 2409
2422 // Try to send the event to the correct view. 2410 // Try to send the event to the correct view.
2423 if (passGestureEventToWidgetIfPossible(gestureEvent, renderer)) { 2411 if (passScrollGestureEventToWidget(gestureEvent, renderer)) {
2424 if(scrollShouldNotPropagate) 2412 if(scrollShouldNotPropagate)
2425 m_previousGestureScrolledNode = m_scrollGestureHandlingNode; 2413 m_previousGestureScrolledNode = m_scrollGestureHandlingNode;
2426 2414
2427 return true; 2415 return true;
2428 } 2416 }
2429 2417
2430 if (scrollShouldNotPropagate) 2418 if (scrollShouldNotPropagate)
2431 stopNode = m_previousGestureScrolledNode.get(); 2419 stopNode = m_previousGestureScrolledNode.get();
2432 2420
2433 // 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
2463 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey()); 2451 gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey());
2464 syntheticWheelEvent.setHasPreciseScrollingDeltas(true); 2452 syntheticWheelEvent.setHasPreciseScrollingDeltas(true);
2465 2453
2466 bool scrolledFrame = view->wheelEvent(syntheticWheelEvent); 2454 bool scrolledFrame = view->wheelEvent(syntheticWheelEvent);
2467 if (scrolledFrame) 2455 if (scrolledFrame)
2468 setFrameWasScrolledByUser(); 2456 setFrameWasScrolledByUser();
2469 2457
2470 return scrolledFrame; 2458 return scrolledFrame;
2471 } 2459 }
2472 2460
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() 2461 void EventHandler::clearGestureScrollNodes()
2483 { 2462 {
2484 m_scrollGestureHandlingNode = nullptr; 2463 m_scrollGestureHandlingNode = nullptr;
2485 m_previousGestureScrolledNode = nullptr; 2464 m_previousGestureScrolledNode = nullptr;
2486 } 2465 }
2487 2466
2488 bool EventHandler::isScrollbarHandlingGestures() const 2467 bool EventHandler::isScrollbarHandlingGestures() const
2489 { 2468 {
2490 return m_scrollbarHandlingScrollGesture.get(); 2469 return m_scrollbarHandlingScrollGesture.get();
2491 } 2470 }
2492 2471
2493 bool EventHandler::shouldApplyTouchAdjustment(const PlatformGestureEvent& event) const 2472 bool EventHandler::shouldApplyTouchAdjustment(const PlatformGestureEvent& event) const
2494 { 2473 {
2495 if (m_frame->settings() && !m_frame->settings()->touchAdjustmentEnabled()) 2474 if (m_frame->settings() && !m_frame->settings()->touchAdjustmentEnabled())
2496 return false; 2475 return false;
2497 return !event.area().isEmpty(); 2476 return !event.area().isEmpty();
2498 } 2477 }
2499 2478
2500 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)
2501 { 2480 {
2502 IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter); 2481 // FIXME: Unify this with the other best* functions which are very similar.
2503 HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::Re adOnly | HitTestRequest::Active, touchRadius); 2482
2483 TRACE_EVENT0("input", "EventHandler::bestClickableNodeForHitTestResult");
2484 ASSERT(result.isRectBasedTest());
2504 2485
2505 // 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
2506 // 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
2507 // scrollbars being untouchable. 2488 // scrollbars being untouchable.
2508 if (result.scrollbar()) 2489 if (result.scrollbar())
2509 return false; 2490 return false;
2510 2491
2511 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
2512 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes; 2495 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes;
2513 copyToVector(result.rectBasedTestResult(), nodes); 2496 copyToVector(result.rectBasedTestResult(), nodes);
2514 2497
2515 // 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
2516 // 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
2517 // 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
2518 // handle targetNode being a shadow DOM node. 2501 // handle targetNode being a shadow DOM node.
2519 2502
2520 // 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.
2521 // 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
2522 // 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.
2523 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));
2524 if (success && targetNode) 2507 if (success && targetNode)
2525 targetNode = targetNode->deprecatedShadowAncestorNode(); 2508 targetNode = targetNode->deprecatedShadowAncestorNode();
2526 return success; 2509 return success;
2527 } 2510 }
2528 2511
2529 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)
2530 { 2513 {
2531 IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter); 2514 ASSERT(result.isRectBasedTest());
2532 HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::Re adOnly | HitTestRequest::Active, touchRadius); 2515 IntPoint touchCenter = m_frame->view()->contentsToWindow(result.roundedPoint InMainFrame());
2533 2516 IntRect touchRect = m_frame->view()->contentsToWindow(result.hitTestLocation ().boundingBox());
2534 IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius);
2535 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes; 2517 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes;
2536 copyToVector(result.rectBasedTestResult(), nodes); 2518 copyToVector(result.rectBasedTestResult(), nodes);
2537 2519
2538 // 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.
2539 return findBestContextMenuCandidate(targetNode, targetPoint, touchCenter, to uchRect, WillBeHeapVector<RefPtrWillBeMember<Node> >(nodes)); 2521 return findBestContextMenuCandidate(targetNode, targetPoint, touchCenter, to uchRect, WillBeHeapVector<RefPtrWillBeMember<Node> >(nodes));
2540 } 2522 }
2541 2523
2542 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)
2543 { 2525 {
2544 IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter); 2526 IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter);
2545 HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::Re adOnly | HitTestRequest::Active, touchRadius); 2527 HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::Re adOnly | HitTestRequest::Active, touchRadius);
2546 2528
2547 IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius); 2529 IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius);
2548 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes; 2530 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes;
2549 copyToVector(result.rectBasedTestResult(), nodes); 2531 copyToVector(result.rectBasedTestResult(), nodes);
2550 2532
2551 // 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.
2552 return findBestZoomableArea(targetNode, targetArea, touchCenter, touchRect, WillBeHeapVector<RefPtrWillBeMember<Node> >(nodes)); 2534 return findBestZoomableArea(targetNode, targetArea, touchCenter, touchRect, WillBeHeapVector<RefPtrWillBeMember<Node> >(nodes));
2553 } 2535 }
2554 2536
2555 void EventHandler::adjustGesturePosition(const PlatformGestureEvent& gestureEven t, IntPoint& adjustedPoint) 2537 GestureEventWithHitTestResults EventHandler::targetGestureEvent(const PlatformGe stureEvent& gestureEvent, bool readOnly)
2556 { 2538 {
2557 if (!shouldApplyTouchAdjustment(gestureEvent)) 2539 ASSERT(m_frame == m_frame->localFrameRoot());
2540 // Scrolling events get hit tested per frame (like wheel events do).
2541 ASSERT(!gestureEvent.isScrollEvent());
2542
2543 HitTestRequest::HitTestRequestType hitType = getHitTypeForGestureType(gestur eEvent.type());
2544 double activeInterval = 0;
2545 bool shouldKeepActiveForMinInterval = false;
2546 if (readOnly) {
2547 hitType |= HitTestRequest::ReadOnly;
2548 } else if (gestureEvent.type() == PlatformEvent::GestureTap) {
2549 // If the Tap is received very shortly after ShowPress, we want to
2550 // delay clearing of the active state so that it's visible to the user
2551 // for at least a couple of frames.
2552 activeInterval = WTF::currentTime() - m_lastShowPressTimestamp;
2553 shouldKeepActiveForMinInterval = m_lastShowPressTimestamp && activeInter val < minimumActiveInterval;
2554 if (shouldKeepActiveForMinInterval)
2555 hitType |= HitTestRequest::ReadOnly;
2556 }
2557
2558 // Perform the rect-based hit-test. Note that we don't yet apply hover/activ e state here
2559 // because we need to resolve touch adjustment first so that we apply hover/ active it to
2560 // the final adjusted node.
2561 IntPoint hitTestPoint = m_frame->view()->windowToContents(gestureEvent.posit ion());
2562 IntSize touchRadius = gestureEvent.area();
2563 touchRadius.scale(1.f / 2);
2564 HitTestResult hitTestResult = hitTestResultAtPoint(hitTestPoint, hitType | H itTestRequest::ReadOnly, touchRadius);
2565
2566 // Adjust the location of the gesture to the most likely nearby node, as app ropriate for the
2567 // type of event.
2568 PlatformGestureEvent adjustedEvent = gestureEvent;
2569 applyTouchAdjustment(&adjustedEvent, &hitTestResult);
2570
2571 // Now apply hover/active state to the final target.
2572 // FIXME: This is supposed to send mouseenter/mouseleave events, but doesn't because we
2573 // aren't passing a PlatformMouseEvent.
2574 HitTestRequest request(hitType | HitTestRequest::AllowChildFrameContent);
2575 if (!request.readOnly())
2576 m_frame->document()->updateHoverActiveState(request, hitTestResult.inner Element());
2577
2578 if (shouldKeepActiveForMinInterval) {
2579 m_lastDeferredTapElement = hitTestResult.innerElement();
2580 m_activeIntervalTimer.startOneShot(minimumActiveInterval - activeInterva l, FROM_HERE);
2581 }
2582
2583 return GestureEventWithHitTestResults(adjustedEvent, hitTestResult);
2584 }
2585
2586 HitTestRequest::HitTestRequestType EventHandler::getHitTypeForGestureType(Platfo rmEvent::Type type)
2587 {
2588 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent | Hi tTestRequest::AllowFrameScrollbars;
2589 switch (type) {
2590 case PlatformEvent::GestureShowPress:
2591 case PlatformEvent::GestureTapUnconfirmed:
2592 return hitType | HitTestRequest::Active;
2593 case PlatformEvent::GestureTapDownCancel:
2594 // A TapDownCancel received when no element is active shouldn't really b e changing hover state.
2595 if (!m_frame->document()->activeHoverElement())
2596 hitType |= HitTestRequest::ReadOnly;
2597 return hitType | HitTestRequest::Release;
2598 case PlatformEvent::GestureTap:
2599 return hitType | HitTestRequest::Release;
2600 case PlatformEvent::GestureTapDown:
2601 case PlatformEvent::GestureLongPress:
2602 case PlatformEvent::GestureLongTap:
2603 case PlatformEvent::GestureTwoFingerTap:
2604 // FIXME: Shouldn't LongTap and TwoFingerTap clear the Active state?
2605 return hitType | HitTestRequest::Active | HitTestRequest::ReadOnly;
2606 default:
2607 ASSERT_NOT_REACHED();
2608 return hitType | HitTestRequest::Active | HitTestRequest::ReadOnly;
2609 }
2610 }
2611
2612 void EventHandler::applyTouchAdjustment(PlatformGestureEvent* gestureEvent, HitT estResult* hitTestResult)
2613 {
2614 if (!shouldApplyTouchAdjustment(*gestureEvent))
2558 return; 2615 return;
2559 2616
2560 Node* targetNode = 0; 2617 Node* adjustedNode = 0;
2561 switch (gestureEvent.type()) { 2618 IntPoint adjustedPoint = gestureEvent->position();
2619 IntSize radius = gestureEvent->area();
2620 radius.scale(1.f / 2);
2621 bool adjusted = false;
2622 switch (gestureEvent->type()) {
2562 case PlatformEvent::GestureTap: 2623 case PlatformEvent::GestureTap:
2563 case PlatformEvent::GestureTapUnconfirmed: 2624 case PlatformEvent::GestureTapUnconfirmed:
2564 case PlatformEvent::GestureTapDown: 2625 case PlatformEvent::GestureTapDown:
2565 case PlatformEvent::GestureShowPress: 2626 case PlatformEvent::GestureShowPress:
2566 bestClickableNodeForTouchPoint(gestureEvent.position(), IntSize(gestureE vent.area().width() / 2, gestureEvent.area().height() / 2), adjustedPoint, targe tNode); 2627 adjusted = bestClickableNodeForHitTestResult(*hitTestResult, adjustedPoi nt, adjustedNode);
2567 break; 2628 break;
2568 case PlatformEvent::GestureLongPress: 2629 case PlatformEvent::GestureLongPress:
2569 case PlatformEvent::GestureLongTap: 2630 case PlatformEvent::GestureLongTap:
2570 case PlatformEvent::GestureTwoFingerTap: 2631 case PlatformEvent::GestureTwoFingerTap:
2571 bestContextMenuNodeForTouchPoint(gestureEvent.position(), IntSize(gestur eEvent.area().width() / 2, gestureEvent.area().height() / 2), adjustedPoint, tar getNode); 2632 adjusted = bestContextMenuNodeForHitTestResult(*hitTestResult, adjustedP oint, adjustedNode);
2572 break; 2633 break;
2573 default: 2634 default:
2574 // FIXME: Implement handling for other types as needed.
2575 ASSERT_NOT_REACHED(); 2635 ASSERT_NOT_REACHED();
2576 } 2636 }
2637
2638 if (adjusted) {
2639 hitTestResult->resolveRectBasedTest(adjustedNode, m_frame->view()->windo wToContents(adjustedPoint));
2640 gestureEvent->applyTouchAdjustment(adjustedPoint);
2641 }
2577 } 2642 }
2578 2643
2579 bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event) 2644 bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
2580 { 2645 {
2581 Document* doc = m_frame->document(); 2646 Document* doc = m_frame->document();
2582 FrameView* v = m_frame->view(); 2647 FrameView* v = m_frame->view();
2583 if (!v) 2648 if (!v)
2584 return false; 2649 return false;
2585 2650
2586 // Clear mouse press state to avoid initiating a drag while context menu is up. 2651 // 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 2738 #else
2674 PlatformEvent::Type eventType = PlatformEvent::MousePressed; 2739 PlatformEvent::Type eventType = PlatformEvent::MousePressed;
2675 #endif 2740 #endif
2676 2741
2677 PlatformMouseEvent mouseEvent(position, globalPosition, RightButton, eventTy pe, 1, false, false, false, false, WTF::currentTime()); 2742 PlatformMouseEvent mouseEvent(position, globalPosition, RightButton, eventTy pe, 1, false, false, false, false, WTF::currentTime());
2678 2743
2679 handleMousePressEvent(mouseEvent); 2744 handleMousePressEvent(mouseEvent);
2680 return sendContextMenuEvent(mouseEvent); 2745 return sendContextMenuEvent(mouseEvent);
2681 } 2746 }
2682 2747
2683 bool EventHandler::sendContextMenuEventForGesture(const PlatformGestureEvent& ev ent) 2748 bool EventHandler::sendContextMenuEventForGesture(const GestureEventWithHitTestR esults& targetedEvent)
2684 { 2749 {
2685 #if OS(WIN) 2750 #if OS(WIN)
2686 PlatformEvent::Type eventType = PlatformEvent::MouseReleased; 2751 PlatformEvent::Type eventType = PlatformEvent::MouseReleased;
2687 #else 2752 #else
2688 PlatformEvent::Type eventType = PlatformEvent::MousePressed; 2753 PlatformEvent::Type eventType = PlatformEvent::MousePressed;
2689 #endif 2754 #endif
2690 2755
2691 IntPoint adjustedPoint = event.position(); 2756 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 2757 // To simulate right-click behavior, we send a right mouse down and then
2695 // context menu event. 2758 // context menu event.
2759 // FIXME: Send HitTestResults to avoid redundant hit tests.
2696 handleMousePressEvent(mouseEvent); 2760 handleMousePressEvent(mouseEvent);
2697 return sendContextMenuEvent(mouseEvent); 2761 return sendContextMenuEvent(mouseEvent);
2698 // We do not need to send a corresponding mouse release because in case of 2762 // 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. 2763 // right-click, the context menu takes capture and consumes all events.
2700 } 2764 }
2701 2765
2702 void EventHandler::scheduleHoverStateUpdate() 2766 void EventHandler::scheduleHoverStateUpdate()
2703 { 2767 {
2704 if (!m_hoverTimer.isActive()) 2768 if (!m_hoverTimer.isActive())
2705 m_hoverTimer.startOneShot(0, FROM_HERE); 2769 m_hoverTimer.startOneShot(0, FROM_HERE);
(...skipping 1050 matching lines...) Expand 10 before | Expand all | Expand 10 after
3756 unsigned EventHandler::accessKeyModifiers() 3820 unsigned EventHandler::accessKeyModifiers()
3757 { 3821 {
3758 #if OS(MACOSX) 3822 #if OS(MACOSX)
3759 return PlatformEvent::CtrlKey | PlatformEvent::AltKey; 3823 return PlatformEvent::CtrlKey | PlatformEvent::AltKey;
3760 #else 3824 #else
3761 return PlatformEvent::AltKey; 3825 return PlatformEvent::AltKey;
3762 #endif 3826 #endif
3763 } 3827 }
3764 3828
3765 } // namespace WebCore 3829 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698