| 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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 , m_clickCount(0) | 170 , m_clickCount(0) |
| 171 , m_shouldOnlyFireDragOverEvent(false) | 171 , m_shouldOnlyFireDragOverEvent(false) |
| 172 , m_mousePositionIsUnknown(true) | 172 , m_mousePositionIsUnknown(true) |
| 173 , m_mouseDownTimestamp(0) | 173 , m_mouseDownTimestamp(0) |
| 174 , m_widgetIsLatched(false) | 174 , m_widgetIsLatched(false) |
| 175 , m_touchPressed(false) | 175 , m_touchPressed(false) |
| 176 , m_scrollGestureHandlingNode(nullptr) | 176 , m_scrollGestureHandlingNode(nullptr) |
| 177 , m_lastGestureScrollOverWidget(false) | 177 , m_lastGestureScrollOverWidget(false) |
| 178 , m_maxMouseMovedDuration(0) | 178 , m_maxMouseMovedDuration(0) |
| 179 , m_didStartDrag(false) | 179 , m_didStartDrag(false) |
| 180 , m_longTapShouldInvokeContextMenu(false) | |
| 181 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired) | 180 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired) |
| 182 , m_lastShowPressTimestamp(0) | 181 , m_lastShowPressTimestamp(0) |
| 183 { | 182 { |
| 184 } | 183 } |
| 185 | 184 |
| 186 EventHandler::~EventHandler() | 185 EventHandler::~EventHandler() |
| 187 { | 186 { |
| 188 ASSERT(!m_fakeMouseMoveEventTimer.isActive()); | 187 ASSERT(!m_fakeMouseMoveEventTimer.isActive()); |
| 189 } | 188 } |
| 190 | 189 |
| (...skipping 1120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1311 ASSERT(!mouseEvent.fromTouch()); | 1310 ASSERT(!mouseEvent.fromTouch()); |
| 1312 | 1311 |
| 1313 HitTestRequest::HitTestRequestType hitType = HitTestRequest::Release; | 1312 HitTestRequest::HitTestRequestType hitType = HitTestRequest::Release; |
| 1314 HitTestRequest request(hitType); | 1313 HitTestRequest request(hitType); |
| 1315 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent); | 1314 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent); |
| 1316 if (m_eventHandlerWillResetCapturingMouseEventsNode) | 1315 if (m_eventHandlerWillResetCapturingMouseEventsNode) |
| 1317 m_capturingMouseEventsNode = nullptr; | 1316 m_capturingMouseEventsNode = nullptr; |
| 1318 | 1317 |
| 1319 bool swallowMouseUpEvent = !dispatchMouseEvent(EventTypeNames::mouseup, mev.
targetNode(), m_clickCount, mouseEvent, false); | 1318 bool swallowMouseUpEvent = !dispatchMouseEvent(EventTypeNames::mouseup, mev.
targetNode(), m_clickCount, mouseEvent, false); |
| 1320 | 1319 |
| 1321 bool contextMenuEvent = mouseEvent.button() == RightButton; | |
| 1322 #if OS(MACOSX) | |
| 1323 // FIXME: The Mac port achieves the same behavior by checking whether the co
ntext menu is currently open in WebPage::mouseEvent(). Consider merging the impl
ementations. | |
| 1324 if (mouseEvent.button() == LeftButton && mouseEvent.modifiers() & PlatformEv
ent::CtrlKey) | |
| 1325 contextMenuEvent = true; | |
| 1326 #endif | |
| 1327 | |
| 1328 bool swallowClickEvent = false; | 1320 bool swallowClickEvent = false; |
| 1329 if (m_clickCount > 0 && !contextMenuEvent && mev.targetNode() && m_clickNode
) { | 1321 if (m_clickCount > 0 && mev.targetNode() && m_clickNode) { |
| 1330 if (Node* clickTargetNode = mev.targetNode()->commonAncestor(*m_clickNod
e, parentForClickEvent)) | 1322 if (Node* clickTargetNode = mev.targetNode()->commonAncestor(*m_clickNod
e, parentForClickEvent)) |
| 1331 swallowClickEvent = !dispatchMouseEvent(EventTypeNames::click, click
TargetNode, m_clickCount, mouseEvent, true); | 1323 swallowClickEvent = !dispatchMouseEvent(EventTypeNames::click, click
TargetNode, m_clickCount, mouseEvent, true); |
| 1332 } | 1324 } |
| 1333 | 1325 |
| 1334 if (m_resizeScrollableArea) { | 1326 if (m_resizeScrollableArea) { |
| 1335 m_resizeScrollableArea->setInResizeMode(false); | 1327 m_resizeScrollableArea->setInResizeMode(false); |
| 1336 m_resizeScrollableArea = 0; | 1328 m_resizeScrollableArea = 0; |
| 1337 } | 1329 } |
| 1338 | 1330 |
| 1339 bool swallowMouseReleaseEvent = false; | 1331 bool swallowMouseReleaseEvent = false; |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1684 if (gestureEvent.type() == PlatformEvent::GestureTapDown && eventSwallow
ed) | 1676 if (gestureEvent.type() == PlatformEvent::GestureTapDown && eventSwallow
ed) |
| 1685 m_scrollbarHandlingScrollGesture = scrollbar; | 1677 m_scrollbarHandlingScrollGesture = scrollbar; |
| 1686 if (eventSwallowed) | 1678 if (eventSwallowed) |
| 1687 return true; | 1679 return true; |
| 1688 } | 1680 } |
| 1689 | 1681 |
| 1690 if (eventTarget && eventTarget->dispatchGestureEvent(gestureEvent)) | 1682 if (eventTarget && eventTarget->dispatchGestureEvent(gestureEvent)) |
| 1691 return true; | 1683 return true; |
| 1692 | 1684 |
| 1693 switch (gestureEvent.type()) { | 1685 switch (gestureEvent.type()) { |
| 1686 case PlatformEvent::GestureTwoFingerTap: // FIXME(sky): Remove this. |
| 1694 case PlatformEvent::GestureTap: | 1687 case PlatformEvent::GestureTap: |
| 1695 return handleGestureTap(targetedEvent); | 1688 return handleGestureTap(targetedEvent); |
| 1696 case PlatformEvent::GestureShowPress: | 1689 case PlatformEvent::GestureShowPress: |
| 1697 return handleGestureShowPress(); | 1690 return handleGestureShowPress(); |
| 1698 case PlatformEvent::GestureLongPress: | 1691 case PlatformEvent::GestureLongPress: |
| 1699 return handleGestureLongPress(targetedEvent); | 1692 return handleGestureLongPress(targetedEvent); |
| 1700 case PlatformEvent::GestureLongTap: | 1693 case PlatformEvent::GestureLongTap: |
| 1701 return handleGestureLongTap(targetedEvent); | 1694 return handleGestureLongTap(targetedEvent); |
| 1702 case PlatformEvent::GestureTwoFingerTap: | |
| 1703 return sendContextMenuEventForGesture(targetedEvent); | |
| 1704 case PlatformEvent::GestureTapDown: | 1695 case PlatformEvent::GestureTapDown: |
| 1705 case PlatformEvent::GesturePinchBegin: | 1696 case PlatformEvent::GesturePinchBegin: |
| 1706 case PlatformEvent::GesturePinchEnd: | 1697 case PlatformEvent::GesturePinchEnd: |
| 1707 case PlatformEvent::GesturePinchUpdate: | 1698 case PlatformEvent::GesturePinchUpdate: |
| 1708 case PlatformEvent::GestureTapDownCancel: | 1699 case PlatformEvent::GestureTapDownCancel: |
| 1709 case PlatformEvent::GestureTapUnconfirmed: | 1700 case PlatformEvent::GestureTapUnconfirmed: |
| 1710 break; | 1701 break; |
| 1711 default: | 1702 default: |
| 1712 ASSERT_NOT_REACHED(); | 1703 ASSERT_NOT_REACHED(); |
| 1713 } | 1704 } |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1858 } | 1849 } |
| 1859 | 1850 |
| 1860 bool EventHandler::handleGestureLongPress(const GestureEventWithHitTestResults&
targetedEvent) | 1851 bool EventHandler::handleGestureLongPress(const GestureEventWithHitTestResults&
targetedEvent) |
| 1861 { | 1852 { |
| 1862 const PlatformGestureEvent& gestureEvent = targetedEvent.event(); | 1853 const PlatformGestureEvent& gestureEvent = targetedEvent.event(); |
| 1863 | 1854 |
| 1864 // FIXME: Ideally we should try to remove the extra mouse-specific hit-tests
here (re-using the | 1855 // FIXME: Ideally we should try to remove the extra mouse-specific hit-tests
here (re-using the |
| 1865 // supplied HitTestResult), but that will require some overhaul of the touch
drag-and-drop code | 1856 // supplied HitTestResult), but that will require some overhaul of the touch
drag-and-drop code |
| 1866 // and LongPress is such a special scenario that it's unlikely to matter muc
h in practice. | 1857 // and LongPress is such a special scenario that it's unlikely to matter muc
h in practice. |
| 1867 | 1858 |
| 1868 m_longTapShouldInvokeContextMenu = false; | |
| 1869 #if OS(ANDROID) | 1859 #if OS(ANDROID) |
| 1870 bool shouldLongPressSelectWord = true; | 1860 bool shouldLongPressSelectWord = true; |
| 1871 #else | 1861 #else |
| 1872 bool shouldLongPressSelectWord = m_frame->settings() && m_frame->settings()-
>touchEditingEnabled(); | 1862 bool shouldLongPressSelectWord = m_frame->settings() && m_frame->settings()-
>touchEditingEnabled(); |
| 1873 #endif | 1863 #endif |
| 1874 if (shouldLongPressSelectWord) { | 1864 if (shouldLongPressSelectWord) { |
| 1875 IntPoint hitTestPoint = m_frame->view()->windowToContents(gestureEvent.p
osition()); | 1865 IntPoint hitTestPoint = m_frame->view()->windowToContents(gestureEvent.p
osition()); |
| 1876 HitTestResult result = hitTestResultAtPoint(hitTestPoint); | 1866 HitTestResult result = hitTestResultAtPoint(hitTestPoint); |
| 1877 Node* innerNode = result.targetNode(); | 1867 Node* innerNode = result.targetNode(); |
| 1878 if (!result.isLiveLink() && innerNode && (innerNode->isContentEditable()
|| innerNode->isTextNode())) { | 1868 if (!result.isLiveLink() && innerNode && (innerNode->isContentEditable()
|| innerNode->isTextNode())) { |
| 1879 selectClosestWordFromHitTestResult(result, DontAppendTrailingWhitesp
ace); | 1869 selectClosestWordFromHitTestResult(result, DontAppendTrailingWhitesp
ace); |
| 1880 if (m_frame->selection().isRange()) { | 1870 if (m_frame->selection().isRange()) { |
| 1881 focusDocumentView(); | 1871 focusDocumentView(); |
| 1882 return true; | 1872 return true; |
| 1883 } | 1873 } |
| 1884 } | 1874 } |
| 1885 } | 1875 } |
| 1886 return sendContextMenuEventForGesture(targetedEvent); | 1876 return true; |
| 1887 } | 1877 } |
| 1888 | 1878 |
| 1889 bool EventHandler::handleGestureLongTap(const GestureEventWithHitTestResults& ta
rgetedEvent) | 1879 bool EventHandler::handleGestureLongTap(const GestureEventWithHitTestResults& ta
rgetedEvent) |
| 1890 { | 1880 { |
| 1891 #if !OS(ANDROID) | |
| 1892 if (m_longTapShouldInvokeContextMenu) { | |
| 1893 m_longTapShouldInvokeContextMenu = false; | |
| 1894 return sendContextMenuEventForGesture(targetedEvent); | |
| 1895 } | |
| 1896 #endif | |
| 1897 return false; | 1881 return false; |
| 1898 } | 1882 } |
| 1899 | 1883 |
| 1900 bool EventHandler::handleScrollGestureOnResizer(Node* eventTarget, const Platfor
mGestureEvent& gestureEvent) { | 1884 bool EventHandler::handleScrollGestureOnResizer(Node* eventTarget, const Platfor
mGestureEvent& gestureEvent) { |
| 1901 if (gestureEvent.type() == PlatformEvent::GestureScrollBegin) { | 1885 if (gestureEvent.type() == PlatformEvent::GestureScrollBegin) { |
| 1902 RenderLayer* layer = eventTarget->renderer() ? eventTarget->renderer()->
enclosingLayer() : 0; | 1886 RenderLayer* layer = eventTarget->renderer() ? eventTarget->renderer()->
enclosingLayer() : 0; |
| 1903 IntPoint p = m_frame->view()->windowToContents(gestureEvent.position()); | 1887 IntPoint p = m_frame->view()->windowToContents(gestureEvent.position()); |
| 1904 if (layer && layer->scrollableArea() && layer->scrollableArea()->isPoint
InResizeControl(p, ResizerForTouch)) { | 1888 if (layer && layer->scrollableArea() && layer->scrollableArea()->isPoint
InResizeControl(p, ResizerForTouch)) { |
| 1905 m_resizeScrollableArea = layer->scrollableArea(); | 1889 m_resizeScrollableArea = layer->scrollableArea(); |
| 1906 m_resizeScrollableArea->setInResizeMode(true); | 1890 m_resizeScrollableArea->setInResizeMode(true); |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2083 IntPoint touchCenter = m_frame->view()->contentsToWindow(result.roundedPoint
InMainFrame()); | 2067 IntPoint touchCenter = m_frame->view()->contentsToWindow(result.roundedPoint
InMainFrame()); |
| 2084 IntRect touchRect = m_frame->view()->contentsToWindow(result.hitTestLocation
().boundingBox()); | 2068 IntRect touchRect = m_frame->view()->contentsToWindow(result.hitTestLocation
().boundingBox()); |
| 2085 | 2069 |
| 2086 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes; | 2070 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes; |
| 2087 copyToVector(result.rectBasedTestResult(), nodes); | 2071 copyToVector(result.rectBasedTestResult(), nodes); |
| 2088 | 2072 |
| 2089 // FIXME: the explicit Vector conversion copies into a temporary and is wast
eful. | 2073 // FIXME: the explicit Vector conversion copies into a temporary and is wast
eful. |
| 2090 return findBestClickableCandidate(targetNode, targetPoint, touchCenter, touc
hRect, WillBeHeapVector<RefPtrWillBeMember<Node> > (nodes)); | 2074 return findBestClickableCandidate(targetNode, targetPoint, touchCenter, touc
hRect, WillBeHeapVector<RefPtrWillBeMember<Node> > (nodes)); |
| 2091 } | 2075 } |
| 2092 | 2076 |
| 2093 bool EventHandler::bestContextMenuNodeForHitTestResult(const HitTestResult& resu
lt, IntPoint& targetPoint, Node*& targetNode) | |
| 2094 { | |
| 2095 ASSERT(result.isRectBasedTest()); | |
| 2096 IntPoint touchCenter = m_frame->view()->contentsToWindow(result.roundedPoint
InMainFrame()); | |
| 2097 IntRect touchRect = m_frame->view()->contentsToWindow(result.hitTestLocation
().boundingBox()); | |
| 2098 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes; | |
| 2099 copyToVector(result.rectBasedTestResult(), nodes); | |
| 2100 | |
| 2101 // FIXME: the explicit Vector conversion copies into a temporary and is wast
eful. | |
| 2102 return findBestContextMenuCandidate(targetNode, targetPoint, touchCenter, to
uchRect, WillBeHeapVector<RefPtrWillBeMember<Node> >(nodes)); | |
| 2103 } | |
| 2104 | |
| 2105 bool EventHandler::bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, co
nst IntSize& touchRadius, IntRect& targetArea, Node*& targetNode) | 2077 bool EventHandler::bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, co
nst IntSize& touchRadius, IntRect& targetArea, Node*& targetNode) |
| 2106 { | 2078 { |
| 2107 IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter); | 2079 IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter); |
| 2108 HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::Re
adOnly | HitTestRequest::Active, touchRadius); | 2080 HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::Re
adOnly | HitTestRequest::Active, touchRadius); |
| 2109 | 2081 |
| 2110 IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius); | 2082 IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius); |
| 2111 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes; | 2083 WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes; |
| 2112 copyToVector(result.rectBasedTestResult(), nodes); | 2084 copyToVector(result.rectBasedTestResult(), nodes); |
| 2113 | 2085 |
| 2114 // FIXME: the explicit Vector conversion copies into a temporary and is wast
eful. | 2086 // FIXME: the explicit Vector conversion copies into a temporary and is wast
eful. |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2223 Node* adjustedNode = 0; | 2195 Node* adjustedNode = 0; |
| 2224 IntPoint adjustedPoint = gestureEvent->position(); | 2196 IntPoint adjustedPoint = gestureEvent->position(); |
| 2225 IntSize radius = gestureEvent->area(); | 2197 IntSize radius = gestureEvent->area(); |
| 2226 radius.scale(1.f / 2); | 2198 radius.scale(1.f / 2); |
| 2227 bool adjusted = false; | 2199 bool adjusted = false; |
| 2228 switch (gestureEvent->type()) { | 2200 switch (gestureEvent->type()) { |
| 2229 case PlatformEvent::GestureTap: | 2201 case PlatformEvent::GestureTap: |
| 2230 case PlatformEvent::GestureTapUnconfirmed: | 2202 case PlatformEvent::GestureTapUnconfirmed: |
| 2231 case PlatformEvent::GestureTapDown: | 2203 case PlatformEvent::GestureTapDown: |
| 2232 case PlatformEvent::GestureShowPress: | 2204 case PlatformEvent::GestureShowPress: |
| 2233 adjusted = bestClickableNodeForHitTestResult(*hitTestResult, adjustedPoi
nt, adjustedNode); | |
| 2234 break; | |
| 2235 case PlatformEvent::GestureLongPress: | 2205 case PlatformEvent::GestureLongPress: |
| 2236 case PlatformEvent::GestureLongTap: | 2206 case PlatformEvent::GestureLongTap: |
| 2237 case PlatformEvent::GestureTwoFingerTap: | 2207 case PlatformEvent::GestureTwoFingerTap: |
| 2238 adjusted = bestContextMenuNodeForHitTestResult(*hitTestResult, adjustedP
oint, adjustedNode); | 2208 adjusted = bestClickableNodeForHitTestResult(*hitTestResult, adjustedPoi
nt, adjustedNode); |
| 2239 break; | 2209 break; |
| 2240 default: | 2210 default: |
| 2241 ASSERT_NOT_REACHED(); | 2211 ASSERT_NOT_REACHED(); |
| 2242 } | 2212 } |
| 2243 | 2213 |
| 2244 // Update the hit-test result to be a point-based result instead of a rect-b
ased result. | 2214 // Update the hit-test result to be a point-based result instead of a rect-b
ased result. |
| 2245 // FIXME: We should do this even when no candidate matches the node filter.
crbug.com/398914 | 2215 // FIXME: We should do this even when no candidate matches the node filter.
crbug.com/398914 |
| 2246 if (adjusted) { | 2216 if (adjusted) { |
| 2247 hitTestResult->resolveRectBasedTest(adjustedNode, m_frame->view()->windo
wToContents(adjustedPoint)); | 2217 hitTestResult->resolveRectBasedTest(adjustedNode, m_frame->view()->windo
wToContents(adjustedPoint)); |
| 2248 gestureEvent->applyTouchAdjustment(adjustedPoint); | 2218 gestureEvent->applyTouchAdjustment(adjustedPoint); |
| 2249 } | 2219 } |
| 2250 } | 2220 } |
| 2251 | 2221 |
| 2252 bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event) | |
| 2253 { | |
| 2254 Document* doc = m_frame->document(); | |
| 2255 FrameView* v = m_frame->view(); | |
| 2256 if (!v) | |
| 2257 return false; | |
| 2258 | |
| 2259 // Clear mouse press state to avoid initiating a drag while context menu is
up. | |
| 2260 m_mousePressed = false; | |
| 2261 LayoutPoint viewportPos = v->windowToContents(event.position()); | |
| 2262 HitTestRequest request(HitTestRequest::Active); | |
| 2263 MouseEventWithHitTestResults mev = doc->prepareMouseEvent(request, viewportP
os, event); | |
| 2264 | |
| 2265 if (!m_frame->selection().contains(viewportPos) | |
| 2266 && !mev.scrollbar() | |
| 2267 // FIXME: In the editable case, word selection sometimes selects content
that isn't underneath the mouse. | |
| 2268 // If the selection is non-editable, we do word selection to make it eas
ier to use the contextual menu items | |
| 2269 // available for text selections. But only if we're above text. | |
| 2270 && (m_frame->selection().isContentEditable() || (mev.targetNode() && mev
.targetNode()->isTextNode()))) { | |
| 2271 m_mouseDownMayStartSelect = true; // context menu events are always allo
wed to perform a selection | |
| 2272 | |
| 2273 if (mev.hitTestResult().isMisspelled()) | |
| 2274 selectClosestMisspellingFromMouseEvent(mev); | |
| 2275 else if (m_frame->editor().behavior().shouldSelectOnContextualMenuClick(
)) | |
| 2276 selectClosestWordOrLinkFromMouseEvent(mev); | |
| 2277 } | |
| 2278 | |
| 2279 return !dispatchMouseEvent(EventTypeNames::contextmenu, mev.targetNode(), 0,
event, false); | |
| 2280 } | |
| 2281 | |
| 2282 bool EventHandler::sendContextMenuEventForKey() | |
| 2283 { | |
| 2284 FrameView* view = m_frame->view(); | |
| 2285 if (!view) | |
| 2286 return false; | |
| 2287 | |
| 2288 Document* doc = m_frame->document(); | |
| 2289 if (!doc) | |
| 2290 return false; | |
| 2291 | |
| 2292 // Clear mouse press state to avoid initiating a drag while context menu is
up. | |
| 2293 m_mousePressed = false; | |
| 2294 | |
| 2295 static const int kContextMenuMargin = 1; | |
| 2296 | |
| 2297 int rightAligned = 0; | |
| 2298 IntPoint location; | |
| 2299 | |
| 2300 Element* focusedElement = doc->focusedElement(); | |
| 2301 FrameSelection& selection = m_frame->selection(); | |
| 2302 Position start = selection.selection().start(); | |
| 2303 bool shouldTranslateToRootView = true; | |
| 2304 | |
| 2305 if (start.deprecatedNode() && (selection.rootEditableElement() || selection.
isRange())) { | |
| 2306 RefPtrWillBeRawPtr<Range> selectionRange = selection.toNormalizedRange()
; | |
| 2307 IntRect firstRect = m_frame->editor().firstRectForRange(selectionRange.g
et()); | |
| 2308 | |
| 2309 int x = rightAligned ? firstRect.maxX() : firstRect.x(); | |
| 2310 // In a multiline edit, firstRect.maxY() would endup on the next line, s
o -1. | |
| 2311 int y = firstRect.maxY() ? firstRect.maxY() - 1 : 0; | |
| 2312 location = IntPoint(x, y); | |
| 2313 } else if (focusedElement) { | |
| 2314 IntRect clippedRect = focusedElement->boundsInRootViewSpace(); | |
| 2315 location = IntPoint(clippedRect.center()); | |
| 2316 } else { | |
| 2317 location = IntPoint( | |
| 2318 rightAligned ? view->contentsWidth() - kContextMenuMargin : kContext
MenuMargin, | |
| 2319 kContextMenuMargin); | |
| 2320 shouldTranslateToRootView = false; | |
| 2321 } | |
| 2322 | |
| 2323 m_frame->view()->setCursor(pointerCursor()); | |
| 2324 | |
| 2325 IntPoint position = shouldTranslateToRootView ? view->contentsToRootView(loc
ation) : location; | |
| 2326 IntPoint globalPosition = view->hostWindow()->rootViewToScreen(IntRect(posit
ion, IntSize())).location(); | |
| 2327 | |
| 2328 Node* targetNode = doc->focusedElement(); | |
| 2329 if (!targetNode) | |
| 2330 targetNode = doc; | |
| 2331 | |
| 2332 // Use the focused node as the target for hover and active. | |
| 2333 HitTestResult result(position); | |
| 2334 result.setInnerNode(targetNode); | |
| 2335 doc->updateHoverActiveState(HitTestRequest::Active, result.innerElement()); | |
| 2336 | |
| 2337 // The contextmenu event is a mouse event even when invoked using the keyboa
rd. | |
| 2338 // This is required for web compatibility. | |
| 2339 | |
| 2340 PlatformEvent::Type eventType = PlatformEvent::MousePressed; | |
| 2341 | |
| 2342 PlatformMouseEvent mouseEvent(position, globalPosition, RightButton, eventTy
pe, 1, false, false, false, false, PlatformMouseEvent::RealOrIndistinguishable,
WTF::currentTime()); | |
| 2343 | |
| 2344 handleMousePressEvent(mouseEvent); | |
| 2345 return sendContextMenuEvent(mouseEvent); | |
| 2346 } | |
| 2347 | |
| 2348 bool EventHandler::sendContextMenuEventForGesture(const GestureEventWithHitTestR
esults& targetedEvent) | |
| 2349 { | |
| 2350 PlatformEvent::Type eventType = PlatformEvent::MousePressed; | |
| 2351 | |
| 2352 PlatformMouseEvent mouseEvent(targetedEvent.event().position(), targetedEven
t.event().globalPosition(), RightButton, eventType, 1, false, false, false, fals
e, PlatformMouseEvent::RealOrIndistinguishable, WTF::currentTime()); | |
| 2353 // To simulate right-click behavior, we send a right mouse down and then | |
| 2354 // context menu event. | |
| 2355 // FIXME: Send HitTestResults to avoid redundant hit tests. | |
| 2356 handleMousePressEvent(mouseEvent); | |
| 2357 return sendContextMenuEvent(mouseEvent); | |
| 2358 // We do not need to send a corresponding mouse release because in case of | |
| 2359 // right-click, the context menu takes capture and consumes all events. | |
| 2360 } | |
| 2361 | |
| 2362 void EventHandler::scheduleHoverStateUpdate() | 2222 void EventHandler::scheduleHoverStateUpdate() |
| 2363 { | 2223 { |
| 2364 if (!m_hoverTimer.isActive()) | 2224 if (!m_hoverTimer.isActive()) |
| 2365 m_hoverTimer.startOneShot(0, FROM_HERE); | 2225 m_hoverTimer.startOneShot(0, FROM_HERE); |
| 2366 } | 2226 } |
| 2367 | 2227 |
| 2368 void EventHandler::scheduleCursorUpdate() | 2228 void EventHandler::scheduleCursorUpdate() |
| 2369 { | 2229 { |
| 2370 if (!m_cursorUpdateTimer.isActive()) | 2230 if (!m_cursorUpdateTimer.isActive()) |
| 2371 m_cursorUpdateTimer.startOneShot(cursorUpdateInterval, FROM_HERE); | 2231 m_cursorUpdateTimer.startOneShot(cursorUpdateInterval, FROM_HERE); |
| (...skipping 698 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3070 unsigned EventHandler::accessKeyModifiers() | 2930 unsigned EventHandler::accessKeyModifiers() |
| 3071 { | 2931 { |
| 3072 #if OS(MACOSX) | 2932 #if OS(MACOSX) |
| 3073 return PlatformEvent::CtrlKey | PlatformEvent::AltKey; | 2933 return PlatformEvent::CtrlKey | PlatformEvent::AltKey; |
| 3074 #else | 2934 #else |
| 3075 return PlatformEvent::AltKey; | 2935 return PlatformEvent::AltKey; |
| 3076 #endif | 2936 #endif |
| 3077 } | 2937 } |
| 3078 | 2938 |
| 3079 } // namespace blink | 2939 } // namespace blink |
| OLD | NEW |