Title: [94797] trunk
Revision
94797
Author
commit-qu...@webkit.org
Date
2011-09-08 14:11:44 -0700 (Thu, 08 Sep 2011)

Log Message

Implement double tap detection in GestureRecognizerChromium
https://bugs.webkit.org/show_bug.cgi?id=67709

Patch by Varun Jain <varunj...@google.com> on 2011-09-08
Reviewed by Dimitri Glazkov.

*  Source/WebCore/page/EventHandler.cpp:
*  Source/WebCore/platform/PlatformGestureEvent.h:

Modified Paths

Diff

Modified: trunk/ChangeLog (94796 => 94797)


--- trunk/ChangeLog	2011-09-08 21:00:05 UTC (rev 94796)
+++ trunk/ChangeLog	2011-09-08 21:11:44 UTC (rev 94797)
@@ -1,3 +1,13 @@
+2011-09-08  Varun Jain  <varunj...@google.com>
+
+        Implement double tap detection in GestureRecognizerChromium
+        https://bugs.webkit.org/show_bug.cgi?id=67709
+
+        Reviewed by Dimitri Glazkov.
+
+        *  Source/WebCore/page/EventHandler.cpp:
+        *  Source/WebCore/platform/PlatformGestureEvent.h:
+
 2011-09-08  Ulan Degenbaev  <u...@chromium.org>
 
         [v8] Improve performance of typed array set() taking Array

Modified: trunk/Source/WebCore/page/EventHandler.cpp (94796 => 94797)


--- trunk/Source/WebCore/page/EventHandler.cpp	2011-09-08 21:00:05 UTC (rev 94796)
+++ trunk/Source/WebCore/page/EventHandler.cpp	2011-09-08 21:11:44 UTC (rev 94797)
@@ -2221,6 +2221,8 @@
         handleMouseReleaseEvent(fakeMouseUp);
         return true;
     }
+    case PlatformGestureEvent::DoubleTapType:
+        break;
     case PlatformGestureEvent::ScrollUpdateType: {
         const float tickDivisor = (float)WheelEvent::tickMultiplier;
         // FIXME: Replace this interim implementation once the above fixme has been addressed.

Modified: trunk/Source/WebCore/platform/PlatformGestureEvent.h (94796 => 94797)


--- trunk/Source/WebCore/platform/PlatformGestureEvent.h	2011-09-08 21:00:05 UTC (rev 94796)
+++ trunk/Source/WebCore/platform/PlatformGestureEvent.h	2011-09-08 21:11:44 UTC (rev 94797)
@@ -40,6 +40,7 @@
         ScrollUpdateType,
         TapType,
         TapDownType,
+        DoubleTapType,
     };
 
     PlatformGestureEvent()

Modified: trunk/Source/WebCore/platform/chromium/GestureRecognizerChromium.cpp (94796 => 94797)


--- trunk/Source/WebCore/platform/chromium/GestureRecognizerChromium.cpp	2011-09-08 21:00:05 UTC (rev 94796)
+++ trunk/Source/WebCore/platform/chromium/GestureRecognizerChromium.cpp	2011-09-08 21:11:44 UTC (rev 94797)
@@ -62,6 +62,12 @@
     addEdgeFunction(Scroll, FirstFinger, Moved, false, &GestureRecognizerChromium::inScroll);
     addEdgeFunction(Scroll, FirstFinger, Released, false, &GestureRecognizerChromium::scrollEnd);
     addEdgeFunction(Scroll, FirstFinger, Cancelled, false, &GestureRecognizerChromium::scrollEnd);
+
+    addEdgeFunction(FirstClickReceived, FirstFinger, Pressed, false, &GestureRecognizerChromium::touchDown);
+    addEdgeFunction(PendingDoubleClick, FirstFinger, Cancelled, false, &GestureRecognizerChromium::noGesture);
+    addEdgeFunction(PendingDoubleClick, FirstFinger, Released, false, &GestureRecognizerChromium::doubleClick);
+    addEdgeFunction(PendingDoubleClick, FirstFinger, Moved, false, &GestureRecognizerChromium::maybeDoubleClick);
+    addEdgeFunction(PendingDoubleClick, FirstFinger, Stationary, false, &GestureRecognizerChromium::maybeDoubleClick);
 }
 
 void GestureRecognizerChromium::reset()
@@ -86,6 +92,12 @@
     return duration >= minimumTouchDownDurationInSecondsForClick && duration < maximumTouchDownDurationInSecondsForClick;
 }
 
+bool GestureRecognizerChromium::isInSecondClickTimeWindow()
+{
+    double duration(m_lastTouchTime - m_lastClickTime);
+    return duration >= minimumTouchDownDurationInSecondsForClick && duration < maximumTouchDownDurationInSecondsForClick;
+}
+
 bool GestureRecognizerChromium::isInsideManhattanSquare(const PlatformTouchPoint& point)
 {
     int manhattanDistance = abs(point.pos().x() - m_firstTouchPosition.x()) + abs(point.pos().y() - m_firstTouchPosition.y());
@@ -102,6 +114,11 @@
     gestures->append(PlatformGestureEvent(PlatformGestureEvent::TapType, m_firstTouchPosition, m_firstTouchScreenPosition, m_lastTouchTime, 0.f, 0.f, m_shiftKey, m_ctrlKey, m_altKey, m_metaKey));
 }
 
+void GestureRecognizerChromium::appendDoubleClickGestureEvent(const PlatformTouchPoint& touchPoint, Gestures gestures)
+{
+    gestures->append(PlatformGestureEvent(PlatformGestureEvent::DoubleTapType, m_firstTouchPosition, m_firstTouchScreenPosition, m_lastTouchTime, 0.f, 0.f, m_shiftKey, m_ctrlKey, m_altKey, m_metaKey));
+}
+
 PlatformGestureRecognizer::PassGestures GestureRecognizerChromium::processTouchEventForGestures(const PlatformTouchEvent& event, bool defaultPrevented)
 {
     m_ctrlKey = event.ctrlKey();
@@ -142,6 +159,10 @@
 
 void GestureRecognizerChromium::updateValues(const double touchTime, const PlatformTouchPoint& touchPoint)
 {
+    if (state() == FirstClickReceived) {
+        m_firstTouchTime = touchTime;
+        m_lastClickTime = m_lastTouchTime;
+    }
     m_lastTouchTime = touchTime;
     if (state() == NoGesture) {
         m_firstTouchTime = touchTime;
@@ -164,8 +185,13 @@
 
 bool GestureRecognizerChromium::touchDown(const PlatformTouchPoint& touchPoint, Gestures gestures)
 {
+    ASSERT(state() == NoGesture || state() == FirstClickReceived);
+    appendTapDownGestureEvent(touchPoint, gestures);
+    if (state() == FirstClickReceived && isInSecondClickTimeWindow() && isInsideManhattanSquare(touchPoint)) {
+        setState(PendingDoubleClick);
+        return false;
+    }
     setState(PendingSyntheticClick);
-    appendTapDownGestureEvent(touchPoint, gestures);
     return false;
 }
 
@@ -177,6 +203,24 @@
     return false;
 }
 
+bool GestureRecognizerChromium::doubleClick(const PlatformTouchPoint& point, Gestures gestures)
+{
+    if (isInClickTimeWindow() && isInsideManhattanSquare(point)) {
+        setState(NoGesture);
+        appendDoubleClickGestureEvent(point, gestures);
+        return true;
+    }
+    return noGesture(point, gestures);
+}
+
+bool GestureRecognizerChromium::maybeDoubleClick(const PlatformTouchPoint& point, Gestures gestures)
+{
+    ASSERT(state() == GestureRecognizerChromium::PendingDoubleClick);
+    if (point.state() == PlatformTouchPoint::TouchMoved && !isInsideManhattanSquare(point))
+        return noGesture(point, gestures);
+    return false;
+}
+
 bool GestureRecognizerChromium::noGesture(const PlatformTouchPoint&, Gestures)
 {
     reset();
@@ -186,7 +230,7 @@
 bool GestureRecognizerChromium::click(const PlatformTouchPoint& point, Gestures gestures)
 {
     if (isInClickTimeWindow() && isInsideManhattanSquare(point)) {
-        setState(NoGesture);
+        setState(FirstClickReceived);
         appendClickGestureEvent(point, gestures);
         return true;
     }

Modified: trunk/Source/WebCore/platform/chromium/GestureRecognizerChromium.h (94796 => 94797)


--- trunk/Source/WebCore/platform/chromium/GestureRecognizerChromium.h	2011-09-08 21:00:05 UTC (rev 94796)
+++ trunk/Source/WebCore/platform/chromium/GestureRecognizerChromium.h	2011-09-08 21:11:44 UTC (rev 94797)
@@ -48,7 +48,9 @@
     enum State {
         NoGesture,
         PendingSyntheticClick,
-        Scroll
+        Scroll,
+        FirstClickReceived,
+        PendingDoubleClick,
     };
 
     typedef Vector<PlatformGestureEvent>* Gestures;
@@ -68,10 +70,12 @@
     void addEdgeFunction(State, unsigned finger, PlatformTouchPoint::State, bool touchHandledByJavaScript, GestureTransitionFunction);
     void appendTapDownGestureEvent(const PlatformTouchPoint&, Gestures);
     void appendClickGestureEvent(const PlatformTouchPoint&, Gestures);
+    void appendDoubleClickGestureEvent(const PlatformTouchPoint&, Gestures);
     void appendScrollGestureBegin(const PlatformTouchPoint&, Gestures);
     void appendScrollGestureEnd(const PlatformTouchPoint&, Gestures);
     void appendScrollGestureUpdate(const PlatformTouchPoint&, Gestures);
     bool isInClickTimeWindow();
+    bool isInSecondClickTimeWindow();
     bool isInsideManhattanSquare(const PlatformTouchPoint&);
     void setState(State value) { m_state = value; }
     void updateValues(double touchTime, const PlatformTouchPoint&);
@@ -83,12 +87,16 @@
     bool touchDown(const PlatformTouchPoint&, Gestures);
     bool scrollEnd(const PlatformTouchPoint&, Gestures);
 
+    bool doubleClick(const PlatformTouchPoint&, Gestures);
+    bool maybeDoubleClick(const PlatformTouchPoint&, Gestures);
+
     WTF::HashMap<int, GestureTransitionFunction> m_edgeFunctions;
     IntPoint m_firstTouchPosition;
     IntPoint m_firstTouchScreenPosition;
     double m_firstTouchTime;
     State m_state;
     double m_lastTouchTime;
+    double m_lastClickTime;
 
     bool m_ctrlKey;
     bool m_altKey;

Modified: trunk/Source/WebCore/platform/chromium/PopupContainer.cpp (94796 => 94797)


--- trunk/Source/WebCore/platform/chromium/PopupContainer.cpp	2011-09-08 21:00:05 UTC (rev 94796)
+++ trunk/Source/WebCore/platform/chromium/PopupContainer.cpp	2011-09-08 21:11:44 UTC (rev 94797)
@@ -306,6 +306,8 @@
         handleMouseReleaseEvent(fakeMouseUp);
         return true;
     }
+    case PlatformGestureEvent::DoubleTapType:
+        break;
     case PlatformGestureEvent::ScrollUpdateType: {
         PlatformWheelEvent syntheticWheelEvent(gestureEvent.position(), gestureEvent.globalPosition(), gestureEvent.deltaX(), gestureEvent.deltaY(), gestureEvent.deltaX() / 120.0f, gestureEvent.deltaY() / 120.0f, ScrollByPixelWheelEvent, /* isAccepted */ false, gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey());
         handleWheelEvent(syntheticWheelEvent);

Modified: trunk/Source/WebKit/chromium/tests/InnerGestureRecognizerTest.cpp (94796 => 94797)


--- trunk/Source/WebKit/chromium/tests/InnerGestureRecognizerTest.cpp	2011-09-08 21:00:05 UTC (rev 94796)
+++ trunk/Source/WebKit/chromium/tests/InnerGestureRecognizerTest.cpp	2011-09-08 21:11:44 UTC (rev 94797)
@@ -36,7 +36,6 @@
 
 using namespace WebCore;
 
-
 class InspectableGestureRecognizerChromium : public WebCore::GestureRecognizerChromium {
 public:
     InspectableGestureRecognizerChromium()
@@ -157,6 +156,25 @@
     virtual void TearDown() { }
 };
 
+void SimulateAndTestFirstClick(InspectableGestureRecognizerChromium& gm)
+{
+    ASSERT_EQ(GestureRecognizerChromium::NoGesture, gm.state());
+
+    BuildablePlatformTouchPoint press(10, 15, PlatformTouchPoint::TouchPressed);
+    BuildablePlatformTouchEvent pressEvent(WebCore::TouchStart, press);
+    OwnPtr<Vector<WebCore::PlatformGestureEvent> > gestureStart(gm.processTouchEventForGestures(pressEvent, false));
+    ASSERT_EQ((unsigned int)1, gestureStart->size());
+    ASSERT_EQ(PlatformGestureEvent::TapDownType, (*gestureStart)[0].type());
+    ASSERT_EQ(GestureRecognizerChromium::PendingSyntheticClick, gm.state());
+
+    BuildablePlatformTouchPoint release(10, 16, PlatformTouchPoint::TouchReleased);
+    BuildablePlatformTouchEvent releaseEvent(WebCore::TouchEnd, release);
+    gm.setFirstTouchTime(gm.firstTouchTime() - 0.01);
+    OwnPtr<Vector<WebCore::PlatformGestureEvent> > gestureEnd(gm.processTouchEventForGestures(releaseEvent, false));
+    ASSERT_EQ((unsigned int)1, gestureEnd->size());
+    ASSERT_EQ(PlatformGestureEvent::TapType, (*gestureEnd)[0].type());
+}
+
 typedef OwnPtr<Vector<WebCore::PlatformGestureEvent> > Gestures;
 
 TEST_F(GestureRecognizerTest, hash)
@@ -284,6 +302,63 @@
     ASSERT_EQ(0.0, gm.lastTouchTime() - gm.firstTouchTime());
 }
 
+TEST_F(GestureRecognizerTest, doubleTapGestureTest)
+{
+    InspectableGestureRecognizerChromium gm;
+    SimulateAndTestFirstClick(gm);
+    ASSERT_EQ(GestureRecognizerChromium::FirstClickReceived, gm.state());
+
+    BuildablePlatformTouchPoint press(10, 15, PlatformTouchPoint::TouchPressed);
+    BuildablePlatformTouchEvent pressEvent(WebCore::TouchStart, press);
+    gm.setLastTouchTime(gm.lastTouchTime() - 0.01);
+    Gestures gestureStart(gm.processTouchEventForGestures(pressEvent, false));
+    ASSERT_EQ((unsigned int)1, gestureStart->size());
+    ASSERT_EQ(PlatformGestureEvent::TapDownType, (*gestureStart)[0].type());
+    ASSERT_EQ(GestureRecognizerChromium::PendingDoubleClick, gm.state());
+
+    BuildablePlatformTouchPoint move(10, 16, PlatformTouchPoint::TouchMoved);
+    BuildablePlatformTouchEvent moveEvent(WebCore::TouchMove, move);
+    Gestures gestureMove(gm.processTouchEventForGestures(moveEvent, false));
+    ASSERT_EQ((unsigned int)0, gestureMove->size());
+    ASSERT_EQ(GestureRecognizerChromium::PendingDoubleClick, gm.state());
+
+    BuildablePlatformTouchPoint release(10, 16, PlatformTouchPoint::TouchReleased);
+    BuildablePlatformTouchEvent releaseEvent(WebCore::TouchEnd, release);
+    gm.setFirstTouchTime(gm.firstTouchTime() - 0.01);
+    Gestures gestureEnd(gm.processTouchEventForGestures(releaseEvent, false));
+    ASSERT_EQ((unsigned int)1, gestureEnd->size());
+    ASSERT_EQ(PlatformGestureEvent::DoubleTapType, (*gestureEnd)[0].type());
+    ASSERT_EQ(GestureRecognizerChromium::NoGesture, gm.state());
+}
+
+TEST_F(GestureRecognizerTest, doubleTapGestureIncompleteTest)
+{
+    InspectableGestureRecognizerChromium gm;
+    SimulateAndTestFirstClick(gm);
+    ASSERT_EQ(GestureRecognizerChromium::FirstClickReceived, gm.state());
+
+    BuildablePlatformTouchPoint press(10, 15, PlatformTouchPoint::TouchPressed);
+    BuildablePlatformTouchEvent pressEvent(WebCore::TouchStart, press);
+    gm.setLastTouchTime(gm.lastTouchTime() - 0.01);
+    Gestures gestureStart(gm.processTouchEventForGestures(pressEvent, false));
+    ASSERT_EQ((unsigned int)1, gestureStart->size());
+    ASSERT_EQ(PlatformGestureEvent::TapDownType, (*gestureStart)[0].type());
+    ASSERT_EQ(GestureRecognizerChromium::PendingDoubleClick, gm.state());
+
+    BuildablePlatformTouchPoint move(10, 50, PlatformTouchPoint::TouchMoved);
+    BuildablePlatformTouchEvent moveEvent(WebCore::TouchMove, move);
+    Gestures gestureMove(gm.processTouchEventForGestures(moveEvent, false));
+    ASSERT_EQ((unsigned int)0, gestureMove->size());
+    ASSERT_EQ(GestureRecognizerChromium::NoGesture, gm.state());
+
+    BuildablePlatformTouchPoint release(10, 50, PlatformTouchPoint::TouchReleased);
+    BuildablePlatformTouchEvent releaseEvent(WebCore::TouchEnd, release);
+    gm.setFirstTouchTime(gm.firstTouchTime() - 0.01);
+    Gestures gestureEnd(gm.processTouchEventForGestures(releaseEvent, false));
+    ASSERT_EQ((unsigned int)0, gestureEnd->size());
+    ASSERT_EQ(GestureRecognizerChromium::NoGesture, gm.state());
+}
+
 TEST_F(GestureRecognizerTest, tapDownWithoutTapGestureTest)
 {
     InspectableGestureRecognizerChromium gm;
@@ -338,7 +413,7 @@
     Gestures gestureEnd(gm.processTouchEventForGestures(releaseEvent, false));
     ASSERT_EQ((unsigned int)1, gestureEnd->size());
     ASSERT_EQ(PlatformGestureEvent::TapType, (*gestureEnd)[0].type());
-    ASSERT_EQ(GestureRecognizerChromium::NoGesture, gm.state());
+    ASSERT_EQ(GestureRecognizerChromium::FirstClickReceived, gm.state());
 }
 
 TEST_F(GestureRecognizerTest, gestureScrollEvents)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to