Bug 1256339 - Add a eLongTapUp tap type, which fires an observer notification rather than doing a click. r=botond

For B2G we had this "special" behaviour where a long-press that didn't trigger
a contextmenu or whose contextmenu event was cancelled would still trigger a
click event. No other browser does this, and so I think it doesn't make sense
for us to keep doing it either. It also makes it much harder to implement the
Windows-style contextmenu, where the contextmenu pops up when you *lift* your
finger after doing a long-press.

MozReview-Commit-ID: K7NmkNbjfqY
This commit is contained in:
Kartikaya Gupta 2016-07-05 13:24:54 -04:00
parent 4152d69a8e
commit eb0b1afe65
8 changed files with 37 additions and 12 deletions

View File

@ -1808,6 +1808,11 @@ TabChild::HandleTap(GeckoContentController::TapType aType,
aInputBlockId);
}
break;
case GeckoContentController::TapType::eLongTapUp:
if (mGlobal && mTabChildGlobal) {
mAPZEventState->ProcessLongTapUp();
}
break;
case GeckoContentController::TapType::eSentinel:
// Should never happen, but we need to handle this case to make the compiler
// happy.

View File

@ -40,11 +40,16 @@ public:
/**
* Different types of tap-related events that can be sent in
* the HandleTap function. The names should be relatively self-explanatory.
* Note that the eLongTapUp will always be preceded by an eLongTap, but not
* all eLongTap notifications will be followed by an eLongTapUp (for instance,
* if the user moves their finger after triggering the long-tap but before
* lifting it).
*/
enum class TapType {
eSingleTap,
eDoubleTap,
eLongTap,
eLongTapUp,
eSentinel,
};

View File

@ -2005,10 +2005,11 @@ nsEventStatus AsyncPanZoomController::OnLongPress(const TapGestureInput& aEvent)
nsEventStatus AsyncPanZoomController::OnLongPressUp(const TapGestureInput& aEvent) {
APZC_LOG("%p got a long-tap-up in state %d\n", this, mState);
return GenerateSingleTap(aEvent.mPoint, aEvent.modifiers);
return GenerateSingleTap(TapType::eLongTapUp, aEvent.mPoint, aEvent.modifiers);
}
nsEventStatus AsyncPanZoomController::GenerateSingleTap(const ScreenIntPoint& aPoint, mozilla::Modifiers aModifiers) {
nsEventStatus AsyncPanZoomController::GenerateSingleTap(TapType aType,
const ScreenIntPoint& aPoint, mozilla::Modifiers aModifiers) {
RefPtr<GeckoContentController> controller = GetGeckoContentController();
if (controller) {
CSSPoint geckoScreenPoint;
@ -2038,7 +2039,7 @@ nsEventStatus AsyncPanZoomController::GenerateSingleTap(const ScreenIntPoint& aP
NewRunnableMethod<TapType, CSSPoint, mozilla::Modifiers,
ScrollableLayerGuid, uint64_t>(controller,
&GeckoContentController::HandleTap,
TapType::eSingleTap, geckoScreenPoint,
aType, geckoScreenPoint,
aModifiers, GetGuid(),
touch ? touch->GetBlockId() : 0);
@ -2061,14 +2062,14 @@ nsEventStatus AsyncPanZoomController::OnSingleTapUp(const TapGestureInput& aEven
// If mZoomConstraints.mAllowDoubleTapZoom is true we wait for a call to OnSingleTapConfirmed before
// sending event to content
if (!(mZoomConstraints.mAllowDoubleTapZoom && CurrentTouchBlock()->TouchActionAllowsDoubleTapZoom())) {
return GenerateSingleTap(aEvent.mPoint, aEvent.modifiers);
return GenerateSingleTap(TapType::eSingleTap, aEvent.mPoint, aEvent.modifiers);
}
return nsEventStatus_eIgnore;
}
nsEventStatus AsyncPanZoomController::OnSingleTapConfirmed(const TapGestureInput& aEvent) {
APZC_LOG("%p got a single-tap-confirmed in state %d\n", this, mState);
return GenerateSingleTap(aEvent.mPoint, aEvent.modifiers);
return GenerateSingleTap(TapType::eSingleTap, aEvent.mPoint, aEvent.modifiers);
}
nsEventStatus AsyncPanZoomController::OnDoubleTap(const TapGestureInput& aEvent) {

View File

@ -623,8 +623,11 @@ protected:
static AxisLockMode GetAxisLockMode();
// Helper function for OnSingleTapUp() and OnSingleTapConfirmed().
nsEventStatus GenerateSingleTap(const ScreenIntPoint& aPoint, mozilla::Modifiers aModifiers);
// Helper function for OnSingleTapUp(), OnSingleTapConfirmed(), and
// OnLongPressUp().
nsEventStatus GenerateSingleTap(GeckoContentController::TapType aType,
const ScreenIntPoint& aPoint,
mozilla::Modifiers aModifiers);
// Common processing at the end of a touch block.
void OnTouchEndOrCancel();

View File

@ -359,9 +359,9 @@ protected:
EXPECT_CALL(*mcc, HandleTap(TapType::eLongTap, CSSPoint(10, 10), 0, apzc->GetGuid(), blockId)).Times(1);
EXPECT_CALL(check, Call("postHandleLongTap"));
EXPECT_CALL(check, Call("preHandleSingleTap"));
EXPECT_CALL(*mcc, HandleTap(TapType::eSingleTap, CSSPoint(10, 10), 0, apzc->GetGuid(), _)).Times(1);
EXPECT_CALL(check, Call("postHandleSingleTap"));
EXPECT_CALL(check, Call("preHandleLongTapUp"));
EXPECT_CALL(*mcc, HandleTap(TapType::eLongTapUp, CSSPoint(10, 10), 0, apzc->GetGuid(), _)).Times(1);
EXPECT_CALL(check, Call("postHandleLongTapUp"));
}
// Manually invoke the longpress while the touch is currently down.
@ -379,11 +379,11 @@ protected:
// Finally, simulate lifting the finger. Since the long-press wasn't
// prevent-defaulted, we should get a long-tap-up event.
check.Call("preHandleSingleTap");
check.Call("preHandleLongTapUp");
status = TouchUp(apzc, ScreenIntPoint(10, 10), mcc->Time());
mcc->RunThroughDelayedTasks();
EXPECT_EQ(nsEventStatus_eConsumeDoDefault, status);
check.Call("postHandleSingleTap");
check.Call("postHandleLongTapUp");
apzc->AssertStateIsReset();
}

View File

@ -263,6 +263,13 @@ APZEventState::ProcessLongTap(const nsCOMPtr<nsIPresShell>& aPresShell,
}
}
void
APZEventState::ProcessLongTapUp()
{
nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
observerService->NotifyObservers(nullptr, "APZ:LongTapUp", nullptr);
}
void
APZEventState::ProcessTouchEvent(const WidgetTouchEvent& aEvent,
const ScrollableLayerGuid& aGuid,

View File

@ -54,6 +54,7 @@ public:
Modifiers aModifiers,
const ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId);
void ProcessLongTapUp();
void ProcessTouchEvent(const WidgetTouchEvent& aEvent,
const ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId,

View File

@ -170,6 +170,9 @@ ChromeProcessController::HandleTap(TapType aType,
mAPZEventState->ProcessLongTap(GetPresShell(), aPoint, aModifiers, aGuid,
aInputBlockId);
break;
case TapType::eLongTapUp:
mAPZEventState->ProcessLongTapUp();
break;
case TapType::eSentinel:
// Should never happen, but we need to handle this case branch for the
// compiler to be happy.