OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
690 handleGestureEvent(syntheticGestureEvent); | 690 handleGestureEvent(syntheticGestureEvent); |
691 } | 691 } |
692 } | 692 } |
693 | 693 |
694 #if ENABLE(GESTURE_EVENTS) | 694 #if ENABLE(GESTURE_EVENTS) |
695 bool WebViewImpl::handleGestureEvent(const WebGestureEvent& event) | 695 bool WebViewImpl::handleGestureEvent(const WebGestureEvent& event) |
696 { | 696 { |
697 bool eventSwallowed = false; | 697 bool eventSwallowed = false; |
698 bool eventCancelled = false; // for disambiguation | 698 bool eventCancelled = false; // for disambiguation |
699 | 699 |
| 700 // Special handling for slow-path fling gestures, which have no PlatformGest
ureEvent equivalent. |
| 701 switch (event.type) { |
| 702 case WebInputEvent::GestureFlingStart: { |
| 703 if (mainFrameImpl()->frame()->eventHandler()->isScrollbarHandlingGesture
s()) { |
| 704 m_client->didHandleGestureEvent(event, eventCancelled); |
| 705 return eventSwallowed; |
| 706 } |
| 707 m_client->cancelScheduledContentIntents(); |
| 708 m_positionOnFlingStart = WebPoint(event.x / pageScaleFactor(), event.y /
pageScaleFactor()); |
| 709 m_globalPositionOnFlingStart = WebPoint(event.globalX, event.globalY); |
| 710 m_flingModifier = event.modifiers; |
| 711 m_flingSourceDevice = event.sourceDevice; |
| 712 OwnPtr<WebGestureCurve> flingCurve = adoptPtr(Platform::current()->creat
eFlingAnimationCurve(event.sourceDevice, WebFloatPoint(event.data.flingStart.vel
ocityX, event.data.flingStart.velocityY), WebSize())); |
| 713 m_gestureAnimation = WebActiveGestureAnimation::createAtAnimationStart(f
lingCurve.release(), this); |
| 714 scheduleAnimation(); |
| 715 eventSwallowed = true; |
| 716 |
| 717 m_client->didHandleGestureEvent(event, eventCancelled); |
| 718 return eventSwallowed; |
| 719 } |
| 720 case WebInputEvent::GestureFlingCancel: |
| 721 if (m_gestureAnimation) { |
| 722 m_gestureAnimation.clear(); |
| 723 if (m_layerTreeView) |
| 724 m_layerTreeView->didStopFlinging(); |
| 725 eventSwallowed = true; |
| 726 } |
| 727 |
| 728 m_client->didHandleGestureEvent(event, eventCancelled); |
| 729 return eventSwallowed; |
| 730 default: |
| 731 break; |
| 732 } |
| 733 |
| 734 PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(), even
t); |
| 735 |
700 // Handle link highlighting outside the main switch to avoid getting lost in
the | 736 // Handle link highlighting outside the main switch to avoid getting lost in
the |
701 // complicated set of cases handled below. | 737 // complicated set of cases handled below. |
702 switch (event.type) { | 738 switch (event.type) { |
703 case WebInputEvent::GestureTapDown: | 739 case WebInputEvent::GestureTapDown: |
704 // Queue a highlight animation, then hand off to regular handler. | 740 // Queue a highlight animation, then hand off to regular handler. |
705 #if OS(LINUX) | 741 #if OS(LINUX) |
706 if (settingsImpl()->gestureTapHighlightEnabled()) | 742 if (settingsImpl()->gestureTapHighlightEnabled()) |
707 enableTouchHighlight(event); | 743 enableTapHighlight(platformEvent); |
708 #endif | 744 #endif |
709 break; | 745 break; |
710 case WebInputEvent::GestureTapCancel: | 746 case WebInputEvent::GestureTapCancel: |
711 case WebInputEvent::GestureTap: | 747 case WebInputEvent::GestureTap: |
712 case WebInputEvent::GestureLongPress: | 748 case WebInputEvent::GestureLongPress: |
713 if (m_linkHighlight) | 749 if (m_linkHighlight) |
714 m_linkHighlight->startHighlightAnimationIfNeeded(); | 750 m_linkHighlight->startHighlightAnimationIfNeeded(); |
715 break; | 751 break; |
716 default: | 752 default: |
717 break; | 753 break; |
718 } | 754 } |
719 | 755 |
720 switch (event.type) { | 756 switch (event.type) { |
721 case WebInputEvent::GestureFlingStart: { | |
722 if (mainFrameImpl()->frame()->eventHandler()->isScrollbarHandlingGesture
s()) | |
723 break; | |
724 m_client->cancelScheduledContentIntents(); | |
725 m_positionOnFlingStart = WebPoint(event.x, event.y); | |
726 m_globalPositionOnFlingStart = WebPoint(event.globalX, event.globalY); | |
727 m_flingModifier = event.modifiers; | |
728 m_flingSourceDevice = event.sourceDevice; | |
729 OwnPtr<WebGestureCurve> flingCurve = adoptPtr(Platform::current()->creat
eFlingAnimationCurve(event.sourceDevice, WebFloatPoint(event.data.flingStart.vel
ocityX, event.data.flingStart.velocityY), WebSize())); | |
730 m_gestureAnimation = WebActiveGestureAnimation::createAtAnimationStart(f
lingCurve.release(), this); | |
731 scheduleAnimation(); | |
732 eventSwallowed = true; | |
733 break; | |
734 } | |
735 case WebInputEvent::GestureFlingCancel: | |
736 if (m_gestureAnimation) { | |
737 m_gestureAnimation.clear(); | |
738 if (m_layerTreeView) | |
739 m_layerTreeView->didStopFlinging(); | |
740 eventSwallowed = true; | |
741 } | |
742 break; | |
743 case WebInputEvent::GestureTap: { | 757 case WebInputEvent::GestureTap: { |
744 m_client->cancelScheduledContentIntents(); | 758 m_client->cancelScheduledContentIntents(); |
745 if (detectContentOnTouch(WebPoint(event.x, event.y))) { | 759 if (detectContentOnTouch(platformEvent.position())) { |
746 eventSwallowed = true; | 760 eventSwallowed = true; |
747 break; | 761 break; |
748 } | 762 } |
749 | 763 |
750 RefPtr<WebCore::PopupContainer> selectPopup; | 764 RefPtr<WebCore::PopupContainer> selectPopup; |
751 selectPopup = m_selectPopup; | 765 selectPopup = m_selectPopup; |
752 hideSelectPopup(); | 766 hideSelectPopup(); |
753 ASSERT(!m_selectPopup); | 767 ASSERT(!m_selectPopup); |
754 | 768 |
755 // Don't trigger a disambiguation popup on sites designed for mobile dev
ices. | 769 // Don't trigger a disambiguation popup on sites designed for mobile dev
ices. |
756 // Instead, assume that the page has been designed with big enough butto
ns and links. | 770 // Instead, assume that the page has been designed with big enough butto
ns and links. |
757 if (event.data.tap.width > 0 && !shouldDisableDesktopWorkarounds()) { | 771 if (event.data.tap.width > 0 && !shouldDisableDesktopWorkarounds()) { |
758 // FIXME: didTapMultipleTargets should just take a rect instead of | 772 // FIXME: didTapMultipleTargets should just take a rect instead of |
759 // an event. | 773 // an event. |
760 WebGestureEvent scaledEvent; | 774 WebGestureEvent scaledEvent = event; |
761 scaledEvent.x = event.x / pageScaleFactor(); | 775 scaledEvent.x = event.x / pageScaleFactor(); |
762 scaledEvent.y = event.y / pageScaleFactor(); | 776 scaledEvent.y = event.y / pageScaleFactor(); |
763 scaledEvent.data.tap.width = event.data.tap.width / pageScaleFactor(
); | 777 scaledEvent.data.tap.width = event.data.tap.width / pageScaleFactor(
); |
764 scaledEvent.data.tap.height = event.data.tap.height / pageScaleFacto
r(); | 778 scaledEvent.data.tap.height = event.data.tap.height / pageScaleFacto
r(); |
765 IntRect boundingBox(scaledEvent.x - scaledEvent.data.tap.width / 2,
scaledEvent.y - scaledEvent.data.tap.height / 2, scaledEvent.data.tap.width, sca
ledEvent.data.tap.height); | 779 IntRect boundingBox(scaledEvent.x - scaledEvent.data.tap.width / 2,
scaledEvent.y - scaledEvent.data.tap.height / 2, scaledEvent.data.tap.width, sca
ledEvent.data.tap.height); |
766 Vector<IntRect> goodTargets; | 780 Vector<IntRect> goodTargets; |
767 findGoodTouchTargets(boundingBox, mainFrameImpl()->frame(), goodTarg
ets); | 781 findGoodTouchTargets(boundingBox, mainFrameImpl()->frame(), goodTarg
ets); |
768 // FIXME: replace touch adjustment code when numberOfGoodTargets ==
1? | 782 // FIXME: replace touch adjustment code when numberOfGoodTargets ==
1? |
769 // Single candidate case is currently handled by: https://bugs.webki
t.org/show_bug.cgi?id=85101 | 783 // Single candidate case is currently handled by: https://bugs.webki
t.org/show_bug.cgi?id=85101 |
770 if (goodTargets.size() >= 2 && m_client && m_client->didTapMultipleT
argets(scaledEvent, goodTargets)) { | 784 if (goodTargets.size() >= 2 && m_client && m_client->didTapMultipleT
argets(scaledEvent, goodTargets)) { |
771 eventSwallowed = true; | 785 eventSwallowed = true; |
772 eventCancelled = true; | 786 eventCancelled = true; |
773 break; | 787 break; |
774 } | 788 } |
775 } | 789 } |
776 | 790 |
777 PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(),
event); | |
778 eventSwallowed = mainFrameImpl()->frame()->eventHandler()->handleGesture
Event(platformEvent); | 791 eventSwallowed = mainFrameImpl()->frame()->eventHandler()->handleGesture
Event(platformEvent); |
779 | 792 |
780 if (m_selectPopup && m_selectPopup == selectPopup) { | 793 if (m_selectPopup && m_selectPopup == selectPopup) { |
781 // That tap triggered a select popup which is the same as the one th
at | 794 // That tap triggered a select popup which is the same as the one th
at |
782 // was showing before the tap. It means the user tapped the select | 795 // was showing before the tap. It means the user tapped the select |
783 // while the popup was showing, and as a result we first closed then | 796 // while the popup was showing, and as a result we first closed then |
784 // immediately reopened the select popup. It needs to be closed. | 797 // immediately reopened the select popup. It needs to be closed. |
785 hideSelectPopup(); | 798 hideSelectPopup(); |
786 } | 799 } |
787 | 800 |
788 break; | 801 break; |
789 } | 802 } |
790 case WebInputEvent::GestureTwoFingerTap: | 803 case WebInputEvent::GestureTwoFingerTap: |
791 case WebInputEvent::GestureLongPress: | 804 case WebInputEvent::GestureLongPress: |
792 case WebInputEvent::GestureLongTap: { | 805 case WebInputEvent::GestureLongTap: { |
793 if (!mainFrameImpl() || !mainFrameImpl()->frameView()) | 806 if (!mainFrameImpl() || !mainFrameImpl()->frameView()) |
794 break; | 807 break; |
795 | 808 |
796 m_client->cancelScheduledContentIntents(); | 809 m_client->cancelScheduledContentIntents(); |
797 m_page->contextMenuController()->clearContextMenu(); | 810 m_page->contextMenuController()->clearContextMenu(); |
798 m_contextMenuAllowed = true; | 811 m_contextMenuAllowed = true; |
799 PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(),
event); | |
800 eventSwallowed = mainFrameImpl()->frame()->eventHandler()->handleGesture
Event(platformEvent); | 812 eventSwallowed = mainFrameImpl()->frame()->eventHandler()->handleGesture
Event(platformEvent); |
801 m_contextMenuAllowed = false; | 813 m_contextMenuAllowed = false; |
802 | 814 |
803 break; | 815 break; |
804 } | 816 } |
805 case WebInputEvent::GestureTapDown: { | 817 case WebInputEvent::GestureTapDown: { |
806 m_client->cancelScheduledContentIntents(); | 818 m_client->cancelScheduledContentIntents(); |
807 PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(),
event); | |
808 eventSwallowed = mainFrameImpl()->frame()->eventHandler()->handleGesture
Event(platformEvent); | 819 eventSwallowed = mainFrameImpl()->frame()->eventHandler()->handleGesture
Event(platformEvent); |
809 break; | 820 break; |
810 } | 821 } |
811 case WebInputEvent::GestureDoubleTap: | 822 case WebInputEvent::GestureDoubleTap: |
812 if (m_webSettings->doubleTapToZoomEnabled() && m_minimumPageScaleFactor
!= m_maximumPageScaleFactor) { | 823 if (m_webSettings->doubleTapToZoomEnabled() && m_minimumPageScaleFactor
!= m_maximumPageScaleFactor) { |
813 m_client->cancelScheduledContentIntents(); | 824 m_client->cancelScheduledContentIntents(); |
814 animateZoomAroundPoint(WebPoint(event.x, event.y), DoubleTap); | 825 animateZoomAroundPoint(platformEvent.position(), DoubleTap); |
815 eventSwallowed = true; | 826 eventSwallowed = true; |
816 break; | 827 break; |
817 } | 828 } |
818 case WebInputEvent::GestureScrollBegin: | 829 case WebInputEvent::GestureScrollBegin: |
819 case WebInputEvent::GesturePinchBegin: | 830 case WebInputEvent::GesturePinchBegin: |
820 m_client->cancelScheduledContentIntents(); | 831 m_client->cancelScheduledContentIntents(); |
821 case WebInputEvent::GestureScrollEnd: | 832 case WebInputEvent::GestureScrollEnd: |
822 case WebInputEvent::GestureScrollUpdate: | 833 case WebInputEvent::GestureScrollUpdate: |
823 case WebInputEvent::GestureScrollUpdateWithoutPropagation: | 834 case WebInputEvent::GestureScrollUpdateWithoutPropagation: |
824 case WebInputEvent::GestureTapCancel: | 835 case WebInputEvent::GestureTapCancel: |
825 case WebInputEvent::GesturePinchEnd: | 836 case WebInputEvent::GesturePinchEnd: |
826 case WebInputEvent::GesturePinchUpdate: { | 837 case WebInputEvent::GesturePinchUpdate: { |
827 PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(),
event); | |
828 eventSwallowed = mainFrameImpl()->frame()->eventHandler()->handleGesture
Event(platformEvent); | 838 eventSwallowed = mainFrameImpl()->frame()->eventHandler()->handleGesture
Event(platformEvent); |
829 break; | 839 break; |
830 } | 840 } |
831 default: | 841 default: |
832 ASSERT_NOT_REACHED(); | 842 ASSERT_NOT_REACHED(); |
833 } | 843 } |
834 m_client->didHandleGestureEvent(event, eventCancelled); | 844 m_client->didHandleGestureEvent(event, eventCancelled); |
835 return eventSwallowed; | 845 return eventSwallowed; |
836 } | 846 } |
837 | 847 |
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1264 static bool invokesHandCursor(Node* node, bool shiftKey, Frame* frame) | 1274 static bool invokesHandCursor(Node* node, bool shiftKey, Frame* frame) |
1265 { | 1275 { |
1266 if (!node || !node->renderer()) | 1276 if (!node || !node->renderer()) |
1267 return false; | 1277 return false; |
1268 | 1278 |
1269 ECursor cursor = node->renderer()->style()->cursor(); | 1279 ECursor cursor = node->renderer()->style()->cursor(); |
1270 return cursor == CURSOR_POINTER | 1280 return cursor == CURSOR_POINTER |
1271 || (cursor == CURSOR_AUTO && frame->eventHandler()->useHandCursor(node,
node->isLink(), shiftKey)); | 1281 || (cursor == CURSOR_AUTO && frame->eventHandler()->useHandCursor(node,
node->isLink(), shiftKey)); |
1272 } | 1282 } |
1273 | 1283 |
1274 Node* WebViewImpl::bestTouchLinkNode(const WebGestureEvent& touchEvent) | 1284 Node* WebViewImpl::bestTapNode(const PlatformGestureEvent& tapEvent) |
1275 { | 1285 { |
1276 if (!m_page || !m_page->mainFrame()) | 1286 if (!m_page || !m_page->mainFrame()) |
1277 return 0; | 1287 return 0; |
1278 | 1288 |
1279 Node* bestTouchNode = 0; | 1289 Node* bestTouchNode = 0; |
1280 | 1290 |
1281 IntSize touchEventSearchRegionSize(touchEvent.data.tapDown.width / 2, touchE
vent.data.tapDown.height / 2); | 1291 IntPoint touchEventLocation(tapEvent.position()); |
1282 IntPoint touchEventLocation(touchEvent.x, touchEvent.y); | |
1283 #if ENABLE(TOUCH_ADJUSTMENT) | 1292 #if ENABLE(TOUCH_ADJUSTMENT) |
1284 m_page->mainFrame()->eventHandler()->adjustGesturePosition(PlatformGestureEv
entBuilder(mainFrameImpl()->frameView(), touchEvent), touchEventLocation); | 1293 m_page->mainFrame()->eventHandler()->adjustGesturePosition(tapEvent, touchEv
entLocation); |
1285 #endif | 1294 #endif |
1286 | 1295 |
1287 IntPoint hitTestPoint = m_page->mainFrame()->view()->windowToContents(touchE
ventLocation); | 1296 IntPoint hitTestPoint = m_page->mainFrame()->view()->windowToContents(touchE
ventLocation); |
1288 HitTestResult result = m_page->mainFrame()->eventHandler()->hitTestResultAtP
oint( | 1297 HitTestResult result = m_page->mainFrame()->eventHandler()->hitTestResultAtP
oint( |
1289 hitTestPoint, false, false, DontHitTestScrollbars, HitTestRequest::Touch
Event); | 1298 hitTestPoint, false, false, DontHitTestScrollbars, HitTestRequest::Touch
Event); |
1290 bestTouchNode = result.targetNode(); | 1299 bestTouchNode = result.targetNode(); |
1291 | 1300 |
1292 // Make sure our highlight candidate uses a hand cursor as a heuristic to | 1301 // Make sure our highlight candidate uses a hand cursor as a heuristic to |
1293 // choose appropriate targets. | 1302 // choose appropriate targets. |
1294 bool shiftKey = touchEvent.modifiers & WebGestureEvent::ShiftKey; | 1303 while (bestTouchNode && !invokesHandCursor(bestTouchNode, false, m_page->mai
nFrame())) |
1295 while (bestTouchNode && !invokesHandCursor(bestTouchNode, shiftKey, m_page->
mainFrame())) | |
1296 bestTouchNode = bestTouchNode->parentNode(); | 1304 bestTouchNode = bestTouchNode->parentNode(); |
1297 | 1305 |
1298 // We should pick the largest enclosing node with hand cursor set. | 1306 // We should pick the largest enclosing node with hand cursor set. |
1299 while (bestTouchNode && bestTouchNode->parentNode() && invokesHandCursor(bes
tTouchNode->parentNode(), shiftKey, m_page->mainFrame())) | 1307 while (bestTouchNode && bestTouchNode->parentNode() && invokesHandCursor(bes
tTouchNode->parentNode(), false, m_page->mainFrame())) |
1300 bestTouchNode = bestTouchNode->parentNode(); | 1308 bestTouchNode = bestTouchNode->parentNode(); |
1301 | 1309 |
1302 return bestTouchNode; | 1310 return bestTouchNode; |
1303 } | 1311 } |
1304 | 1312 |
1305 void WebViewImpl::enableTouchHighlight(const WebGestureEvent& touchEvent) | 1313 void WebViewImpl::enableTapHighlight(const PlatformGestureEvent& tapEvent) |
1306 { | 1314 { |
1307 // Always clear any existing highlight when this is invoked, even if we don'
t get a new target to highlight. | 1315 // Always clear any existing highlight when this is invoked, even if we don'
t get a new target to highlight. |
1308 m_linkHighlight.clear(); | 1316 m_linkHighlight.clear(); |
1309 | 1317 |
1310 Node* touchNode = bestTouchLinkNode(touchEvent); | 1318 Node* touchNode = bestTapNode(tapEvent); |
1311 | 1319 |
1312 if (!touchNode || !touchNode->renderer() || !touchNode->renderer()->enclosin
gLayer()) | 1320 if (!touchNode || !touchNode->renderer() || !touchNode->renderer()->enclosin
gLayer()) |
1313 return; | 1321 return; |
1314 | 1322 |
1315 Color highlightColor = touchNode->renderer()->style()->tapHighlightColor(); | 1323 Color highlightColor = touchNode->renderer()->style()->tapHighlightColor(); |
1316 // Safari documentation for -webkit-tap-highlight-color says if the specifie
d color has 0 alpha, | 1324 // Safari documentation for -webkit-tap-highlight-color says if the specifie
d color has 0 alpha, |
1317 // then tap highlighting is disabled. | 1325 // then tap highlighting is disabled. |
1318 // http://developer.apple.com/library/safari/#documentation/appleapplication
s/reference/safaricssref/articles/standardcssproperties.html | 1326 // http://developer.apple.com/library/safari/#documentation/appleapplication
s/reference/safaricssref/articles/standardcssproperties.html |
1319 if (!highlightColor.alpha()) | 1327 if (!highlightColor.alpha()) |
1320 return; | 1328 return; |
(...skipping 3067 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4388 #endif | 4396 #endif |
4389 | 4397 |
4390 bool WebViewImpl::shouldDisableDesktopWorkarounds() | 4398 bool WebViewImpl::shouldDisableDesktopWorkarounds() |
4391 { | 4399 { |
4392 ViewportArguments arguments = mainFrameImpl()->frame()->document()->viewport
Arguments(); | 4400 ViewportArguments arguments = mainFrameImpl()->frame()->document()->viewport
Arguments(); |
4393 return arguments.width == ViewportArguments::ValueDeviceWidth || !arguments.
userZoom | 4401 return arguments.width == ViewportArguments::ValueDeviceWidth || !arguments.
userZoom |
4394 || (arguments.minZoom == arguments.maxZoom && arguments.minZoom != Viewp
ortArguments::ValueAuto); | 4402 || (arguments.minZoom == arguments.maxZoom && arguments.minZoom != Viewp
ortArguments::ValueAuto); |
4395 } | 4403 } |
4396 | 4404 |
4397 } // namespace WebKit | 4405 } // namespace WebKit |
OLD | NEW |