Bug 1143655 - Add sending NS_TOUCH_CANCEL event. r=kats

This commit is contained in:
Maksim Lebedev 2015-03-25 12:20:20 -04:00
parent e2514a23d9
commit 9e2e275653
8 changed files with 52 additions and 21 deletions

View File

@ -2392,7 +2392,8 @@ TabChild::RecvRealTouchEvent(const WidgetTouchEvent& aEvent,
return true;
}
mAPZEventState->ProcessTouchEvent(localEvent, aGuid, aInputBlockId);
mAPZEventState->ProcessTouchEvent(localEvent, aGuid, aInputBlockId,
nsEventStatus_eIgnore);
return true;
}

View File

@ -236,7 +236,8 @@ APZEventState::ProcessLongTap(const nsCOMPtr<nsIDOMWindowUtils>& aUtils,
void
APZEventState::ProcessTouchEvent(const WidgetTouchEvent& aEvent,
const ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId)
uint64_t aInputBlockId,
nsEventStatus aApzResponse)
{
if (aEvent.message == NS_TOUCH_START && aEvent.touches.Length() > 0) {
mActiveElementManager->SetTargetElement(aEvent.touches[0]->GetTarget());
@ -244,6 +245,7 @@ APZEventState::ProcessTouchEvent(const WidgetTouchEvent& aEvent,
bool isTouchPrevented = TouchManager::gPreventMouseEvents ||
aEvent.mFlags.mMultipleActionsPrevented;
bool sentContentResponse = false;
switch (aEvent.message) {
case NS_TOUCH_START: {
mTouchEndCancelled = false;
@ -252,10 +254,12 @@ APZEventState::ProcessTouchEvent(const WidgetTouchEvent& aEvent,
// respond to the first one. Respond to it now.
mContentReceivedInputBlockCallback->Run(mPendingTouchPreventedGuid,
mPendingTouchPreventedBlockId, false);
sentContentResponse = true;
mPendingTouchPreventedResponse = false;
}
if (isTouchPrevented) {
mContentReceivedInputBlockCallback->Run(aGuid, aInputBlockId, isTouchPrevented);
sentContentResponse = true;
} else {
mPendingTouchPreventedResponse = true;
mPendingTouchPreventedGuid = aGuid;
@ -274,13 +278,28 @@ APZEventState::ProcessTouchEvent(const WidgetTouchEvent& aEvent,
mActiveElementManager->HandleTouchEndEvent(mEndTouchIsClick);
// fall through
case NS_TOUCH_MOVE: {
SendPendingTouchPreventedResponse(isTouchPrevented, aGuid);
sentContentResponse = SendPendingTouchPreventedResponse(isTouchPrevented, aGuid);
break;
}
default:
NS_WARNING("Unknown touch event type");
}
if (sentContentResponse &&
aApzResponse == nsEventStatus_eConsumeDoDefault &&
gfxPrefs::PointerEventsEnabled()) {
WidgetTouchEvent cancelEvent(aEvent);
cancelEvent.message = NS_TOUCH_CANCEL;
cancelEvent.mFlags.mCancelable = false; // message != NS_TOUCH_CANCEL;
for (uint32_t i = 0; i < cancelEvent.touches.Length(); ++i) {
if (mozilla::dom::Touch* touch = cancelEvent.touches[i]) {
touch->convertToPointer = true;
}
}
nsEventStatus status;
cancelEvent.widget->DispatchEvent(&cancelEvent, status);
}
}
void
@ -364,7 +383,7 @@ APZEventState::ProcessAPZStateChange(const nsCOMPtr<nsIDocument>& aDocument,
}
}
void
bool
APZEventState::SendPendingTouchPreventedResponse(bool aPreventDefault,
const ScrollableLayerGuid& aGuid)
{
@ -373,7 +392,9 @@ APZEventState::SendPendingTouchPreventedResponse(bool aPreventDefault,
mContentReceivedInputBlockCallback->Run(mPendingTouchPreventedGuid,
mPendingTouchPreventedBlockId, aPreventDefault);
mPendingTouchPreventedResponse = false;
return true;
}
return false;
}
already_AddRefed<nsIWidget>

View File

@ -61,7 +61,8 @@ public:
float aPresShellResolution);
void ProcessTouchEvent(const WidgetTouchEvent& aEvent,
const ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId);
uint64_t aInputBlockId,
nsEventStatus aApzResponse);
void ProcessWheelEvent(const WidgetWheelEvent& aEvent,
const ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId);
@ -71,7 +72,7 @@ public:
int aArg);
private:
~APZEventState();
void SendPendingTouchPreventedResponse(bool aPreventDefault,
bool SendPendingTouchPreventedResponse(bool aPreventDefault,
const ScrollableLayerGuid& aGuid);
already_AddRefed<nsIWidget> GetWidget() const;
private:

View File

@ -186,6 +186,7 @@ private:
DECL_GFX_PREF(Once, "dom.vr.enabled", VREnabled, bool, false);
DECL_GFX_PREF(Once, "dom.vr.add-test-devices", VRAddTestDevices, int32_t, 1);
DECL_GFX_PREF(Live, "dom.w3c_pointer_events.enabled", PointerEventsEnabled, bool, false);
DECL_GFX_PREF(Once, "gfx.android.rgb16.force", AndroidRGB16Force, bool, false);
#if defined(ANDROID)

View File

@ -259,15 +259,17 @@ class DispatchTouchInputOnMainThread : public nsRunnable
public:
DispatchTouchInputOnMainThread(const MultiTouchInput& aInput,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId)
const uint64_t& aInputBlockId,
nsEventStatus aApzResponse)
: mInput(aInput)
, mGuid(aGuid)
, mInputBlockId(aInputBlockId)
, mApzResponse(aApzResponse)
{}
NS_IMETHOD Run() {
if (gFocusedWindow) {
gFocusedWindow->DispatchTouchEventForAPZ(mInput, mGuid, mInputBlockId);
gFocusedWindow->DispatchTouchEventForAPZ(mInput, mGuid, mInputBlockId, mApzResponse);
}
return NS_OK;
}
@ -276,6 +278,7 @@ private:
MultiTouchInput mInput;
ScrollableLayerGuid mGuid;
uint64_t mInputBlockId;
nsEventStatus mApzResponse;
};
void
@ -292,9 +295,9 @@ nsWindow::DispatchTouchInputViaAPZ(MultiTouchInput& aInput)
// First send it through the APZ code
mozilla::layers::ScrollableLayerGuid guid;
uint64_t inputBlockId;
nsEventStatus rv = mAPZC->ReceiveInputEvent(aInput, &guid, &inputBlockId);
nsEventStatus result = mAPZC->ReceiveInputEvent(aInput, &guid, &inputBlockId);
// If the APZ says to drop it, then we drop it
if (rv == nsEventStatus_eConsumeNoDefault) {
if (result == nsEventStatus_eConsumeNoDefault) {
return;
}
@ -303,13 +306,14 @@ nsWindow::DispatchTouchInputViaAPZ(MultiTouchInput& aInput)
// refcounting is not threadsafe. Instead we just use the gFocusedWindow
// static ptr inside the task.
NS_DispatchToMainThread(new DispatchTouchInputOnMainThread(
aInput, guid, inputBlockId));
aInput, guid, inputBlockId, result));
}
void
nsWindow::DispatchTouchEventForAPZ(const MultiTouchInput& aInput,
const ScrollableLayerGuid& aGuid,
const uint64_t aInputBlockId)
const uint64_t aInputBlockId,
nsEventStatus aApzResponse)
{
MOZ_ASSERT(NS_IsMainThread());
UserActivity();
@ -318,10 +322,10 @@ nsWindow::DispatchTouchEventForAPZ(const MultiTouchInput& aInput,
WidgetTouchEvent event = aInput.ToWidgetTouchEvent(this);
// Dispatch the event into the gecko root process for "normal" flow.
// The event might get sent to a child process, but if it doesn't we need to
// notify the APZ of various things. All of that happens in
// ProcessUntransformedAPZEvent
ProcessUntransformedAPZEvent(&event, aGuid, aInputBlockId);
// The event might get sent to a child process,
// but if it doesn't we need to notify the APZ of various things.
// All of that happens in ProcessUntransformedAPZEvent
ProcessUntransformedAPZEvent(&event, aGuid, aInputBlockId, aApzResponse);
}
class DispatchTouchInputOnControllerThread : public Task

View File

@ -90,7 +90,8 @@ public:
void DispatchTouchInputViaAPZ(mozilla::MultiTouchInput& aInput);
void DispatchTouchEventForAPZ(const mozilla::MultiTouchInput& aInput,
const ScrollableLayerGuid& aGuid,
const uint64_t aInputBlockId);
const uint64_t aInputBlockId,
nsEventStatus aApzResponse);
NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent,
nsEventStatus& aStatus);
virtual nsresult SynthesizeNativeTouchPoint(uint32_t aPointerId,

View File

@ -993,7 +993,8 @@ void nsBaseWidget::ConfigureAPZCTreeManager()
nsEventStatus
nsBaseWidget::ProcessUntransformedAPZEvent(WidgetInputEvent* aEvent,
const ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId)
uint64_t aInputBlockId,
nsEventStatus aApzResponse)
{
MOZ_ASSERT(NS_IsMainThread());
InputAPZContext context(aGuid, aInputBlockId);
@ -1026,7 +1027,7 @@ nsBaseWidget::ProcessUntransformedAPZEvent(WidgetInputEvent* aEvent,
APZCCallbackHelper::SendSetTargetAPZCNotification(this, GetDocument(), *aEvent,
aGuid, aInputBlockId, mSetTargetAPZCCallback);
}
mAPZEventState->ProcessTouchEvent(*touchEvent, aGuid, aInputBlockId);
mAPZEventState->ProcessTouchEvent(*touchEvent, aGuid, aInputBlockId, aApzResponse);
} else if (WidgetWheelEvent* wheelEvent = aEvent->AsWheelEvent()) {
APZCCallbackHelper::SendSetTargetAPZCNotification(this, GetDocument(), *aEvent,
aGuid, aInputBlockId, mSetTargetAPZCCallback);
@ -1063,7 +1064,7 @@ nsBaseWidget::DispatchAPZAwareEvent(WidgetInputEvent* aEvent)
if (result == nsEventStatus_eConsumeNoDefault) {
return result;
}
return ProcessUntransformedAPZEvent(aEvent, guid, inputBlockId);
return ProcessUntransformedAPZEvent(aEvent, guid, inputBlockId, result);
}
nsEventStatus status;

View File

@ -336,7 +336,8 @@ protected:
// Dispatch an event that has already been routed through APZ.
nsEventStatus ProcessUntransformedAPZEvent(mozilla::WidgetInputEvent* aEvent,
const ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId);
uint64_t aInputBlockId,
nsEventStatus aApzResponse);
const nsIntRegion RegionFromArray(const nsTArray<nsIntRect>& aRects);
void ArrayFromRegion(const nsIntRegion& aRegion, nsTArray<nsIntRect>& aRects);