Changeset 106642 in webkit


Ignore:
Timestamp:
Feb 3, 2012 2:10:54 AM (12 years ago)
Author:
apavlov@chromium.org
Message:

Implement touch event emulation in the WebCore layer
https://bugs.webkit.org/show_bug.cgi?id=77105

Reviewed by Ryosuke Niwa.

Source/WebCore:

This change essentially maps mouse events into single-touch events in the following way:

  • mousedown -> touchstart
  • mouseup -> touchend
  • mousemove -> touchmove (between mousedown and mouseup).

Test: fast/events/touch/emulate-touch-events.html

  • page/EventHandler.cpp:

(SyntheticTouchPoint): A synthetic touch point built from PlatformMouseEvent.
(WebCore::SyntheticTouchPoint::SyntheticTouchPoint):
(SyntheticSingleTouchEvent): A synthetic touch point event built from PlatformMouseEvent.
(WebCore::SyntheticSingleTouchEvent::SyntheticSingleTouchEvent):
(WebCore::EventHandler::handleMouseReleaseEvent): Invoke maybeDispatchSyntheticTouchEvent() and bail out if necessary.
(WebCore::EventHandler::handleMousePressEvent): Invoke maybeDispatchSyntheticTouchEvent() and bail out if necessary.
(WebCore::EventHandler::mouseMoved): Invoke maybeDispatchSyntheticTouchEvent() and bail out if necessary.
(WebCore::EventHandler::dispatchSyntheticTouchEventIfEnabled): Dispatch a synthetic touch event if necessary.

  • page/EventHandler.h: Added new method.
  • page/Settings.cpp:

(WebCore::Settings::Settings): Added m_touchEventEmulationEnabled initializer.

  • page/Settings.h: Added m_touchEventEmulationEnabled, getter, and setter.

(WebCore::Settings::setTouchEventEmulationEnabled): Added.
(WebCore::Settings::isTouchEventEmulationEnabled): Added.

  • platform/PlatformTouchPoint.h:

(WebCore::PlatformTouchPoint::PlatformTouchPoint): Unconditionally compile the parameterless ctor.

  • testing/InternalSettings.cpp:

(WebCore::InternalSettings::setTouchEventEmulationEnabled): Added for testing.

  • testing/InternalSettings.h: Added setTouchEventEmulationEnabled() for testing.
  • testing/InternalSettings.idl: Added setTouchEventEmulationEnabled() for testing.

LayoutTests:

  • fast/events/touch/emulate-touch-events-expected.txt: Added.
  • fast/events/touch/emulate-touch-events.html: Added.
Location:
trunk
Files:
2 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r106641 r106642  
     12012-01-27  Alexander Pavlov  <apavlov@chromium.org>
     2
     3        Implement touch event emulation in the WebCore layer
     4        https://bugs.webkit.org/show_bug.cgi?id=77105
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        * fast/events/touch/emulate-touch-events-expected.txt: Added.
     9        * fast/events/touch/emulate-touch-events.html: Added.
     10
    1112012-02-03  Adam Barth  <abarth@webkit.org>
    212
  • trunk/Source/WebCore/ChangeLog

    r106640 r106642  
     12012-01-27  Alexander Pavlov  <apavlov@chromium.org>
     2
     3        Implement touch event emulation in the WebCore layer
     4        https://bugs.webkit.org/show_bug.cgi?id=77105
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        This change essentially maps mouse events into single-touch events in the following way:
     9        - mousedown -> touchstart
     10        - mouseup -> touchend
     11        - mousemove -> touchmove (between mousedown and mouseup).
     12
     13        Test: fast/events/touch/emulate-touch-events.html
     14
     15        * page/EventHandler.cpp:
     16        (SyntheticTouchPoint): A synthetic touch point built from PlatformMouseEvent.
     17        (WebCore::SyntheticTouchPoint::SyntheticTouchPoint):
     18        (SyntheticSingleTouchEvent): A synthetic touch point event built from PlatformMouseEvent.
     19        (WebCore::SyntheticSingleTouchEvent::SyntheticSingleTouchEvent):
     20        (WebCore::EventHandler::handleMouseReleaseEvent): Invoke maybeDispatchSyntheticTouchEvent() and bail out if necessary.
     21        (WebCore::EventHandler::handleMousePressEvent): Invoke maybeDispatchSyntheticTouchEvent() and bail out if necessary.
     22        (WebCore::EventHandler::mouseMoved): Invoke maybeDispatchSyntheticTouchEvent() and bail out if necessary.
     23        (WebCore::EventHandler::dispatchSyntheticTouchEventIfEnabled): Dispatch a synthetic touch event if necessary.
     24        * page/EventHandler.h: Added new method.
     25        * page/Settings.cpp:
     26        (WebCore::Settings::Settings): Added m_touchEventEmulationEnabled initializer.
     27        * page/Settings.h: Added m_touchEventEmulationEnabled, getter, and setter.
     28        (WebCore::Settings::setTouchEventEmulationEnabled): Added.
     29        (WebCore::Settings::isTouchEventEmulationEnabled): Added.
     30        * platform/PlatformTouchPoint.h:
     31        (WebCore::PlatformTouchPoint::PlatformTouchPoint): Unconditionally compile the parameterless ctor.
     32        * testing/InternalSettings.cpp:
     33        (WebCore::InternalSettings::setTouchEventEmulationEnabled): Added for testing.
     34        * testing/InternalSettings.h: Added setTouchEventEmulationEnabled() for testing.
     35        * testing/InternalSettings.idl: Added setTouchEventEmulationEnabled() for testing.
     36
    1372012-02-03  Kentaro Hara  <haraken@chromium.org>
    238
  • trunk/Source/WebCore/page/EventHandler.cpp

    r106554 r106642  
    6161#include "MouseEventWithHitTestResults.h"
    6262#include "Page.h"
     63#include "PlatformEvent.h"
    6364#include "PlatformKeyboardEvent.h"
    6465#include "PlatformWheelEvent.h"
     
    143144};
    144145
     146#if ENABLE(TOUCH_EVENTS)
     147class SyntheticTouchPoint : public PlatformTouchPoint {
     148public:
     149
     150    // The default values are based on http://dvcs.w3.org/hg/webevents/raw-file/tip/touchevents.html
     151    explicit SyntheticTouchPoint(const PlatformMouseEvent& event)
     152    {
     153        const static int idDefaultValue = 0;
     154        const static int radiusYDefaultValue = 1;
     155        const static int radiusXDefaultValue = 1;
     156        const static float rotationAngleDefaultValue = 0.0f;
     157        const static float forceDefaultValue = 1.0f;
     158
     159        m_id = idDefaultValue; // There is only one active TouchPoint.
     160        m_screenPos = event.globalPosition();
     161        m_pos = event.position();
     162        m_radiusY = radiusYDefaultValue;
     163        m_radiusX = radiusXDefaultValue;
     164        m_rotationAngle = rotationAngleDefaultValue;
     165        m_force = forceDefaultValue;
     166
     167        PlatformEvent::Type type = event.type();
     168        ASSERT(type == PlatformEvent::MouseMoved || type == PlatformEvent::MousePressed || type == PlatformEvent::MouseReleased);
     169
     170        switch (type) {
     171        case PlatformEvent::MouseMoved:
     172            m_state = TouchMoved;
     173            break;
     174        case PlatformEvent::MousePressed:
     175            m_state = TouchPressed;
     176            break;
     177        case PlatformEvent::MouseReleased:
     178            m_state = TouchReleased;
     179            break;
     180        default:
     181            ASSERT_NOT_REACHED();
     182            break;
     183        }
     184    }
     185};
     186
     187class SyntheticSingleTouchEvent : public PlatformTouchEvent {
     188public:
     189    explicit SyntheticSingleTouchEvent(const PlatformMouseEvent& event)
     190    {
     191        switch (event.type()) {
     192        case PlatformEvent::MouseMoved:
     193            m_type = TouchMove;
     194            break;
     195        case PlatformEvent::MousePressed:
     196            m_type = TouchStart;
     197            break;
     198        case PlatformEvent::MouseReleased:
     199            m_type = TouchEnd;
     200            break;
     201        default:
     202            ASSERT_NOT_REACHED();
     203            m_type = NoType;
     204            break;
     205        }
     206        m_timestamp = event.timestamp();
     207        m_modifiers = event.modifiers();
     208        m_touchPoints.append(SyntheticTouchPoint(event));
     209    }
     210};
     211#endif
     212
    145213static inline bool scrollNode(float delta, WheelEvent::Granularity granularity, ScrollDirection positiveDirection, ScrollDirection negativeDirection, Node* node, Node** stopNode)
    146214{
     
    740808bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& event)
    741809{
     810#if ENABLE(TOUCH_EVENTS)
     811    bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(event.event());
     812    if (defaultPrevented)
     813        return true;
     814#endif
     815
    742816    if (m_autoscrollInProgress)
    743817        stopAutoscrollTimer();
     
    13761450    RefPtr<FrameView> protector(m_frame->view());
    13771451
     1452#if ENABLE(TOUCH_EVENTS)
     1453    bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(mouseEvent);
     1454    if (defaultPrevented)
     1455        return true;
     1456#endif
     1457
    13781458    UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
    13791459
     
    15611641{
    15621642    RefPtr<FrameView> protector(m_frame->view());
     1643
     1644#if ENABLE(TOUCH_EVENTS)
     1645    // FIXME: this should be moved elsewhere to also be able to dispatch touchcancel events.
     1646    bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(event);
     1647    if (defaultPrevented)
     1648        return true;
     1649#endif
    15631650
    15641651    HitTestResult hoveredNode = HitTestResult(LayoutPoint());
     
    33633450}
    33643451
    3365 
    3366 
    3367 #endif
    3368 
    3369 }
     3452bool EventHandler::dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent& event)
     3453{
     3454    if (!m_frame->document()->settings()->isTouchEventEmulationEnabled())
     3455        return false;
     3456
     3457    PlatformEvent::Type eventType = event.type();
     3458    if (eventType != PlatformEvent::MouseMoved && eventType != PlatformEvent::MousePressed && eventType != PlatformEvent::MouseReleased)
     3459        return false;
     3460
     3461    if (eventType == PlatformEvent::MouseMoved && !m_touchPressed)
     3462        return false;
     3463
     3464    SyntheticSingleTouchEvent touchEvent(event);
     3465    return handleTouchEvent(touchEvent);
     3466}
     3467
     3468#endif
     3469
     3470}
  • trunk/Source/WebCore/page/EventHandler.h

    r105396 r106642  
    265265    void cancelFakeMouseMoveEvent();
    266266
     267#if ENABLE(TOUCH_EVENTS)
     268    bool dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent&);
     269#endif
     270
    267271    void invalidateClick();
    268272
  • trunk/Source/WebCore/page/Settings.cpp

    r106500 r106642  
    241241#endif
    242242    , m_notificationsEnabled(true)
     243#if ENABLE(TOUCH_EVENTS)
     244    , m_touchEventEmulationEnabled(false)
     245#endif
    243246    , m_loadsImagesAutomaticallyTimer(this, &Settings::loadsImagesAutomaticallyTimerFired)
    244247{
  • trunk/Source/WebCore/page/Settings.h

    r106500 r106642  
    523523        void setNotificationsEnabled(bool enabled) { m_notificationsEnabled = enabled; }
    524524        bool notificationsEnabled() const { return m_notificationsEnabled; }
     525
     526#if ENABLE(TOUCH_EVENTS)
     527        void setTouchEventEmulationEnabled(bool enabled) { m_touchEventEmulationEnabled = enabled; }
     528        bool isTouchEventEmulationEnabled() const { return m_touchEventEmulationEnabled; }
     529#endif
    525530
    526531    private:
     
    670675        bool m_notificationsEnabled : 1;
    671676
     677#if ENABLE(TOUCH_EVENTS)
     678        bool m_touchEventEmulationEnabled : 1;
     679#endif
     680
    672681        Timer<Settings> m_loadsImagesAutomaticallyTimer;
    673682        void loadsImagesAutomaticallyTimerFired(Timer<Settings>*);
  • trunk/Source/WebCore/platform/PlatformTouchPoint.h

    r95901 r106642  
    4545    };
    4646
     47    // This is necessary for us to be able to build synthetic events.
     48    PlatformTouchPoint() { };
     49
    4750#if PLATFORM(QT)
    4851    PlatformTouchPoint(const QTouchEvent::TouchPoint&);
    49     PlatformTouchPoint() {};
    5052#elif PLATFORM(EFL)
    5153    PlatformTouchPoint(unsigned id, const IntPoint& windowPos, State);
  • trunk/Source/WebCore/testing/InternalSettings.cpp

    r106146 r106642  
    272272}
    273273
    274 }
     274void InternalSettings::setTouchEventEmulationEnabled(bool enabled, ExceptionCode& ec)
     275{
     276#if ENABLE(TOUCH_EVENTS)
     277    InternalSettingsGuardForSettings();
     278    settings()->setTouchEventEmulationEnabled(enabled);
     279#else
     280    UNUSED_PARAM(enabled);
     281    UNUSED_PARAM(ec);
     282#endif
     283}
     284
     285}
  • trunk/Source/WebCore/testing/InternalSettings.h

    r106146 r106642  
    6565    void setPageScaleFactor(float scaleFactor, int x, int y, ExceptionCode&);
    6666    void setPerTileDrawingEnabled(bool enabled, ExceptionCode&);
     67    void setTouchEventEmulationEnabled(bool enabled, ExceptionCode&);
    6768
    6869private:
  • trunk/Source/WebCore/testing/InternalSettings.idl

    r106146 r106642  
    4545        float pageScaleFactor() raises(DOMException);
    4646        void setPageScaleFactor(in float scaleFactor, in long x, in long y) raises(DOMException);
     47        void setTouchEventEmulationEnabled(in boolean enabled) raises(DOMException);
    4748    };
    4849}
Note: See TracChangeset for help on using the changeset viewer.