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)