--- a/gfx/layers/apz/src/GestureEventListener.cpp
+++ b/gfx/layers/apz/src/GestureEventListener.cpp
@@ -50,16 +50,17 @@ float GetCurrentSpan(const MultiTouchInp
}
GestureEventListener::GestureEventListener(AsyncPanZoomController* aAsyncPanZoomController)
: mAsyncPanZoomController(aAsyncPanZoomController),
mState(GESTURE_NONE),
mSpanChange(0.0f),
mPreviousSpan(0.0f),
mLastTouchInput(MultiTouchInput::MULTITOUCH_START, 0, TimeStamp(), 0),
+ mLastTapInput(MultiTouchInput::MULTITOUCH_START, 0, TimeStamp(), 0),
mLongTapTimeoutTask(nullptr),
mMaxTapTimeoutTask(nullptr)
{
}
GestureEventListener::~GestureEventListener()
{
}
@@ -163,23 +164,25 @@ nsEventStatus GestureEventListener::Hand
SetState(GESTURE_MULTI_TOUCH_DOWN);
// Prevent APZC::OnTouchStart() from handling MULTITOUCH_START event
rv = nsEventStatus_eConsumeNoDefault;
break;
case GESTURE_FIRST_SINGLE_TOUCH_UP:
// Cancel wait for double tap
CancelMaxTapTimeoutTask();
SetState(GESTURE_MULTI_TOUCH_DOWN);
+ TriggerSingleTapConfirmedEvent();
// Prevent APZC::OnTouchStart() from handling MULTITOUCH_START event
rv = nsEventStatus_eConsumeNoDefault;
break;
case GESTURE_SECOND_SINGLE_TOUCH_DOWN:
// Cancel wait for single tap
CancelMaxTapTimeoutTask();
SetState(GESTURE_MULTI_TOUCH_DOWN);
+ TriggerSingleTapConfirmedEvent();
// Prevent APZC::OnTouchStart() from handling MULTITOUCH_START event
rv = nsEventStatus_eConsumeNoDefault;
break;
case GESTURE_LONG_TOUCH_DOWN:
SetState(GESTURE_MULTI_TOUCH_DOWN);
break;
case GESTURE_MULTI_TOUCH_DOWN:
case GESTURE_PINCH:
@@ -436,20 +439,20 @@ void GestureEventListener::HandleInputTi
NS_WARNING("Unhandled state upon MAX_TAP timeout");
SetState(GESTURE_NONE);
}
}
void GestureEventListener::TriggerSingleTapConfirmedEvent()
{
TapGestureInput tapEvent(TapGestureInput::TAPGESTURE_CONFIRMED,
- mLastTouchInput.mTime,
- mLastTouchInput.mTimeStamp,
- mLastTouchInput.mTouches[0].mScreenPoint,
- mLastTouchInput.modifiers);
+ mLastTapInput.mTime,
+ mLastTapInput.mTimeStamp,
+ mLastTapInput.mTouches[0].mScreenPoint,
+ mLastTapInput.modifiers);
mAsyncPanZoomController->HandleGestureEvent(tapEvent);
}
void GestureEventListener::SetState(GestureState aState)
{
mState = aState;
if (mState == GESTURE_NONE) {
@@ -493,16 +496,18 @@ void GestureEventListener::CancelMaxTapT
if (mMaxTapTimeoutTask) {
mMaxTapTimeoutTask->Cancel();
mMaxTapTimeoutTask = nullptr;
}
}
void GestureEventListener::CreateMaxTapTimeoutTask()
{
+ mLastTapInput = mLastTouchInput;
+
mMaxTapTimeoutTask =
NewRunnableMethod(this, &GestureEventListener::HandleInputTimeoutMaxTap);
mAsyncPanZoomController->PostDelayedTask(
mMaxTapTimeoutTask,
MAX_TAP_TIME);
}
--- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp
+++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp
@@ -1473,16 +1473,72 @@ TEST_F(APZCGestureDetectorTester, Double
apzc->ContentReceivedTouch(true);
apzc->ContentReceivedTouch(true);
while (mcc->RunThroughDelayedTasks());
apzc->AssertStateIsReset();
}
+// Test for bug 947892
+// We test whether we dispatch tap event when the tap is followed by pinch.
+TEST_F(APZCGestureDetectorTester, TapFollowedByPinch) {
+ MakeApzcZoomable();
+
+ EXPECT_CALL(*mcc, HandleSingleTap(CSSPoint(10, 10), 0, apzc->GetGuid())).Times(1);
+
+ int time = 0;
+ ApzcTap(apzc, 10, 10, time, 100);
+
+ int inputId = 0;
+ MultiTouchInput mti;
+ mti = MultiTouchInput(MultiTouchInput::MULTITOUCH_START, time, TimeStamp(), 0);
+ mti.mTouches.AppendElement(SingleTouchData(inputId, ScreenIntPoint(20, 20), ScreenSize(0, 0), 0, 0));
+ mti.mTouches.AppendElement(SingleTouchData(inputId + 1, ScreenIntPoint(10, 10), ScreenSize(0, 0), 0, 0));
+ apzc->ReceiveInputEvent(mti);
+
+ mti = MultiTouchInput(MultiTouchInput::MULTITOUCH_END, time, TimeStamp(), 0);
+ mti.mTouches.AppendElement(SingleTouchData(inputId, ScreenIntPoint(20, 20), ScreenSize(0, 0), 0, 0));
+ mti.mTouches.AppendElement(SingleTouchData(inputId + 1, ScreenIntPoint(10, 10), ScreenSize(0, 0), 0, 0));
+ apzc->ReceiveInputEvent(mti);
+
+ while (mcc->RunThroughDelayedTasks());
+
+ apzc->AssertStateIsReset();
+}
+
+TEST_F(APZCGestureDetectorTester, TapFollowedByMultipleTouches) {
+ MakeApzcZoomable();
+
+ EXPECT_CALL(*mcc, HandleSingleTap(CSSPoint(10, 10), 0, apzc->GetGuid())).Times(1);
+
+ int time = 0;
+ ApzcTap(apzc, 10, 10, time, 100);
+
+ int inputId = 0;
+ MultiTouchInput mti;
+ mti = MultiTouchInput(MultiTouchInput::MULTITOUCH_START, time, TimeStamp(), 0);
+ mti.mTouches.AppendElement(SingleTouchData(inputId, ScreenIntPoint(20, 20), ScreenSize(0, 0), 0, 0));
+ apzc->ReceiveInputEvent(mti);
+
+ mti = MultiTouchInput(MultiTouchInput::MULTITOUCH_START, time, TimeStamp(), 0);
+ mti.mTouches.AppendElement(SingleTouchData(inputId, ScreenIntPoint(20, 20), ScreenSize(0, 0), 0, 0));
+ mti.mTouches.AppendElement(SingleTouchData(inputId + 1, ScreenIntPoint(10, 10), ScreenSize(0, 0), 0, 0));
+ apzc->ReceiveInputEvent(mti);
+
+ mti = MultiTouchInput(MultiTouchInput::MULTITOUCH_END, time, TimeStamp(), 0);
+ mti.mTouches.AppendElement(SingleTouchData(inputId, ScreenIntPoint(20, 20), ScreenSize(0, 0), 0, 0));
+ mti.mTouches.AppendElement(SingleTouchData(inputId + 1, ScreenIntPoint(10, 10), ScreenSize(0, 0), 0, 0));
+ apzc->ReceiveInputEvent(mti);
+
+ while (mcc->RunThroughDelayedTasks());
+
+ apzc->AssertStateIsReset();
+}
+
class APZCTreeManagerTester : public ::testing::Test {
protected:
virtual void SetUp() {
gfxPrefs::GetSingleton();
AsyncPanZoomController::SetThreadAssertionsEnabled(false);
testStartTime = TimeStamp::Now();
AsyncPanZoomController::SetFrameTime(testStartTime);