summaryrefslogtreecommitdiff
path: root/Source/WebCore/page/EventHandler.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-02-09 14:16:12 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-02-09 14:16:12 +0100
commit03e12282df9aa1e1fb05a8b90f1cfc2e08764cec (patch)
tree52599cd0ab782b1768e23ad176f7618f98333cb6 /Source/WebCore/page/EventHandler.cpp
parentcd44dc59cdfc39534aef4d417e9f3c412e3be139 (diff)
downloadqtwebkit-03e12282df9aa1e1fb05a8b90f1cfc2e08764cec.tar.gz
Imported WebKit commit e09a82039aa4273ab318b71122e92d8e5f233525 (http://svn.webkit.org/repository/webkit/trunk@107223)
Diffstat (limited to 'Source/WebCore/page/EventHandler.cpp')
-rw-r--r--Source/WebCore/page/EventHandler.cpp138
1 files changed, 127 insertions, 11 deletions
diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp
index a2f322e26..9acfc54d2 100644
--- a/Source/WebCore/page/EventHandler.cpp
+++ b/Source/WebCore/page/EventHandler.cpp
@@ -60,6 +60,7 @@
#include "MouseEvent.h"
#include "MouseEventWithHitTestResults.h"
#include "Page.h"
+#include "PlatformEvent.h"
#include "PlatformKeyboardEvent.h"
#include "PlatformWheelEvent.h"
#include "PluginDocument.h"
@@ -142,6 +143,73 @@ private:
Cursor m_cursor;
};
+#if ENABLE(TOUCH_EVENTS)
+class SyntheticTouchPoint : public PlatformTouchPoint {
+public:
+
+ // The default values are based on http://dvcs.w3.org/hg/webevents/raw-file/tip/touchevents.html
+ explicit SyntheticTouchPoint(const PlatformMouseEvent& event)
+ {
+ const static int idDefaultValue = 0;
+ const static int radiusYDefaultValue = 1;
+ const static int radiusXDefaultValue = 1;
+ const static float rotationAngleDefaultValue = 0.0f;
+ const static float forceDefaultValue = 1.0f;
+
+ m_id = idDefaultValue; // There is only one active TouchPoint.
+ m_screenPos = event.globalPosition();
+ m_pos = event.position();
+ m_radiusY = radiusYDefaultValue;
+ m_radiusX = radiusXDefaultValue;
+ m_rotationAngle = rotationAngleDefaultValue;
+ m_force = forceDefaultValue;
+
+ PlatformEvent::Type type = event.type();
+ ASSERT(type == PlatformEvent::MouseMoved || type == PlatformEvent::MousePressed || type == PlatformEvent::MouseReleased);
+
+ switch (type) {
+ case PlatformEvent::MouseMoved:
+ m_state = TouchMoved;
+ break;
+ case PlatformEvent::MousePressed:
+ m_state = TouchPressed;
+ break;
+ case PlatformEvent::MouseReleased:
+ m_state = TouchReleased;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+ }
+};
+
+class SyntheticSingleTouchEvent : public PlatformTouchEvent {
+public:
+ explicit SyntheticSingleTouchEvent(const PlatformMouseEvent& event)
+ {
+ switch (event.type()) {
+ case PlatformEvent::MouseMoved:
+ m_type = TouchMove;
+ break;
+ case PlatformEvent::MousePressed:
+ m_type = TouchStart;
+ break;
+ case PlatformEvent::MouseReleased:
+ m_type = TouchEnd;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ m_type = NoType;
+ break;
+ }
+ m_timestamp = event.timestamp();
+ m_modifiers = event.modifiers();
+ m_touchPoints.append(SyntheticTouchPoint(event));
+ }
+};
+#endif
+
static inline bool scrollNode(float delta, WheelEvent::Granularity granularity, ScrollDirection positiveDirection, ScrollDirection negativeDirection, Node* node, Node** stopNode)
{
if (!delta)
@@ -1375,6 +1443,12 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
{
RefPtr<FrameView> protector(m_frame->view());
+#if ENABLE(TOUCH_EVENTS)
+ bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(mouseEvent);
+ if (defaultPrevented)
+ return true;
+#endif
+
UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
// FIXME (bug 68185): this call should be made at another abstraction layer
@@ -1401,7 +1475,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
HitTestRequest request(HitTestRequest::Active);
// Save the document point we generate in case the window coordinate is invalidated by what happens
// when we dispatch the event.
- IntPoint documentPoint = documentPointForWindowPoint(m_frame, mouseEvent.position());
+ LayoutPoint documentPoint = documentPointForWindowPoint(m_frame, mouseEvent.position());
MouseEventWithHitTestResults mev = m_frame->document()->prepareMouseEvent(request, documentPoint, mouseEvent);
if (!targetNode(mev)) {
@@ -1561,6 +1635,13 @@ bool EventHandler::mouseMoved(const PlatformMouseEvent& event)
{
RefPtr<FrameView> protector(m_frame->view());
+#if ENABLE(TOUCH_EVENTS)
+ // FIXME: this should be moved elsewhere to also be able to dispatch touchcancel events.
+ bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(event);
+ if (defaultPrevented)
+ return true;
+#endif
+
HitTestResult hoveredNode = HitTestResult(LayoutPoint());
bool result = handleMouseMoveEvent(event, &hoveredNode);
@@ -1569,8 +1650,10 @@ bool EventHandler::mouseMoved(const PlatformMouseEvent& event)
return result;
if (RenderLayer* layer = layerForNode(hoveredNode.innerNode())) {
- if (page->containsScrollableArea(layer))
- layer->mouseMovedInContentArea();
+ if (FrameView* frameView = m_frame->view()) {
+ if (frameView->containsScrollableArea(layer))
+ layer->mouseMovedInContentArea();
+ }
}
if (FrameView* frameView = m_frame->view())
@@ -1698,7 +1781,13 @@ void EventHandler::invalidateClick()
bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
{
RefPtr<FrameView> protector(m_frame->view());
-
+
+#if ENABLE(TOUCH_EVENTS)
+ bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(mouseEvent);
+ if (defaultPrevented)
+ return true;
+#endif
+
UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
#if ENABLE(PAN_SCROLLING)
@@ -2030,10 +2119,14 @@ void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMo
}
} else if (page && (layerForLastNode && (!layerForNodeUnderMouse || layerForNodeUnderMouse != layerForLastNode))) {
// The mouse has moved between layers.
- if (page->containsScrollableArea(layerForLastNode))
- layerForLastNode->mouseExitedContentArea();
+ if (Frame* frame = m_lastNodeUnderMouse->document()->frame()) {
+ if (FrameView* frameView = frame->view()) {
+ if (frameView->containsScrollableArea(layerForLastNode))
+ layerForLastNode->mouseExitedContentArea();
+ }
+ }
}
-
+
if (m_nodeUnderMouse && (!m_lastNodeUnderMouse || m_lastNodeUnderMouse->document() != m_frame->document())) {
// The mouse has moved between frames.
if (Frame* frame = m_nodeUnderMouse->document()->frame()) {
@@ -2042,10 +2135,14 @@ void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMo
}
} else if (page && (layerForNodeUnderMouse && (!layerForLastNode || layerForNodeUnderMouse != layerForLastNode))) {
// The mouse has moved between layers.
- if (page->containsScrollableArea(layerForNodeUnderMouse))
- layerForNodeUnderMouse->mouseEnteredContentArea();
+ if (Frame* frame = m_nodeUnderMouse->document()->frame()) {
+ if (FrameView* frameView = frame->view()) {
+ if (frameView->containsScrollableArea(layerForNodeUnderMouse))
+ layerForNodeUnderMouse->mouseEnteredContentArea();
+ }
+ }
}
-
+
if (m_lastNodeUnderMouse && m_lastNodeUnderMouse->document() != m_frame->document()) {
m_lastNodeUnderMouse = 0;
m_lastScrollbarUnderMouse = 0;
@@ -3194,6 +3291,8 @@ static const AtomicString& eventNameForTouchPointState(PlatformTouchPoint::State
return eventNames().touchstartEvent;
case PlatformTouchPoint::TouchMoved:
return eventNames().touchmoveEvent;
+ case PlatformTouchPoint::TouchStationary:
+ // TouchStationary state is not converted to touch events, so fall through to assert.
default:
ASSERT_NOT_REACHED();
return emptyAtom;
@@ -3249,6 +3348,9 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
case PlatformTouchPoint::TouchCancelled:
hitType |= HitTestRequest::Release;
break;
+ case PlatformTouchPoint::TouchStationary:
+ hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly;
+ break;
default:
ASSERT_NOT_REACHED();
break;
@@ -3281,7 +3383,7 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
// we also remove it from the map.
touchTarget = m_originatingTouchPointTargets.take(touchPointTargetKey);
} else
- // No hittest is performed on move, since the target is not allowed to change anyway.
+ // No hittest is performed on move or stationary, since the target is not allowed to change anyway.
touchTarget = m_originatingTouchPointTargets.get(touchPointTargetKey);
if (!touchTarget.get())
@@ -3362,7 +3464,21 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
return defaultPrevented;
}
+bool EventHandler::dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent& event)
+{
+ if (!m_frame || !m_frame->settings() || !m_frame->settings()->isTouchEventEmulationEnabled())
+ return false;
+
+ PlatformEvent::Type eventType = event.type();
+ if (eventType != PlatformEvent::MouseMoved && eventType != PlatformEvent::MousePressed && eventType != PlatformEvent::MouseReleased)
+ return false;
+ if (eventType == PlatformEvent::MouseMoved && !m_touchPressed)
+ return false;
+
+ SyntheticSingleTouchEvent touchEvent(event);
+ return handleTouchEvent(touchEvent);
+}
#endif