OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |