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