Bug 927033 - Don't reset mApzcForInputBlock until all touches are gone [r=kats]

This commit is contained in:
Matt Brubeck 2013-11-07 13:10:29 -08:00
Родитель e97e27e96e
Коммит dc8d2c3cd9
4 изменённых файлов: 33 добавлений и 15 удалений

Просмотреть файл

@ -16,6 +16,7 @@
#include "mozilla/MouseEvents.h"
#include "mozilla/mozalloc.h" // for operator new
#include "mozilla/TouchEvents.h"
#include "nsDebug.h" // for NS_WARNING
#include "nsPoint.h" // for nsIntPoint
#include "nsTArray.h" // for nsTArray, nsTArray_Impl, etc
#include "nsThreadUtils.h" // for NS_IsMainThread
@ -29,7 +30,8 @@ namespace layers {
float APZCTreeManager::sDPI = 72.0;
APZCTreeManager::APZCTreeManager()
: mTreeLock("APZCTreeLock")
: mTreeLock("APZCTreeLock"),
mTouchCount(0)
{
MOZ_ASSERT(NS_IsMainThread());
AsyncPanZoomController::InitializeGlobalState();
@ -238,6 +240,7 @@ APZCTreeManager::ReceiveInputEvent(const InputData& aEvent)
case MULTITOUCH_INPUT: {
const MultiTouchInput& multiTouchInput = aEvent.AsMultiTouchInput();
if (multiTouchInput.mType == MultiTouchInput::MULTITOUCH_START) {
mTouchCount++;
mApzcForInputBlock = GetTargetAPZC(ScreenPoint(multiTouchInput.mTouches[0].mScreenPoint));
for (size_t i = 1; i < multiTouchInput.mTouches.Length(); i++) {
nsRefPtr<AsyncPanZoomController> apzc2 = GetTargetAPZC(ScreenPoint(multiTouchInput.mTouches[i].mScreenPoint));
@ -267,10 +270,18 @@ APZCTreeManager::ReceiveInputEvent(const InputData& aEvent)
ApplyTransform(&(inputForApzc.mTouches[i].mScreenPoint), transformToApzc);
}
result = mApzcForInputBlock->ReceiveInputEvent(inputForApzc);
}
if (multiTouchInput.mType == MultiTouchInput::MULTITOUCH_CANCEL ||
multiTouchInput.mType == MultiTouchInput::MULTITOUCH_END) {
if (mTouchCount >= multiTouchInput.mTouches.Length()) {
mTouchCount -= multiTouchInput.mTouches.Length();
} else {
NS_WARNING("Got an unexpected touchend/touchcancel");
mTouchCount = 0;
}
// If we have an mApzcForInputBlock and it's the end of the touch sequence
// then null it out so we don't keep a dangling reference and leak things.
if (multiTouchInput.mType == MultiTouchInput::MULTITOUCH_CANCEL ||
(multiTouchInput.mType == MultiTouchInput::MULTITOUCH_END && multiTouchInput.mTouches.Length() == 1)) {
if (mTouchCount == 0) {
mApzcForInputBlock = nullptr;
}
}
@ -356,9 +367,17 @@ APZCTreeManager::ProcessTouchEvent(const WidgetTouchEvent& aEvent,
// If we have an mApzcForInputBlock and it's the end of the touch sequence
// then null it out so we don't keep a dangling reference and leak things.
if (aEvent.message == NS_TOUCH_CANCEL ||
(aEvent.message == NS_TOUCH_END && aEvent.touches.Length() == 1)) {
aEvent.message == NS_TOUCH_END) {
if (mTouchCount >= aEvent.touches.Length()) {
mTouchCount -= aEvent.touches.Length();
} else {
NS_WARNING("Got an unexpected touchend/touchcancel");
mTouchCount = 0;
}
if (mTouchCount == 0) {
mApzcForInputBlock = nullptr;
}
}
return ret;
}
@ -410,6 +429,7 @@ APZCTreeManager::ReceiveInputEvent(const WidgetInputEvent& aEvent,
return nsEventStatus_eIgnore;
}
if (touchEvent.message == NS_TOUCH_START) {
mTouchCount++;
ScreenPoint point = ScreenPoint(touchEvent.touches[0]->mRefPoint.x, touchEvent.touches[0]->mRefPoint.y);
mApzcForInputBlock = GetTouchInputBlockAPZC(touchEvent, point);
}
@ -442,6 +462,7 @@ APZCTreeManager::ReceiveInputEvent(WidgetInputEvent& aEvent)
return nsEventStatus_eIgnore;
}
if (touchEvent.message == NS_TOUCH_START) {
mTouchCount++;
ScreenPoint point = ScreenPoint(touchEvent.touches[0]->mRefPoint.x, touchEvent.touches[0]->mRefPoint.y);
mApzcForInputBlock = GetTouchInputBlockAPZC(touchEvent, point);
}

Просмотреть файл

@ -321,6 +321,8 @@ private:
* input delivery thread, and so does not require locking.
*/
nsRefPtr<AsyncPanZoomController> mApzcForInputBlock;
/* The number of touch points we are tracking that are currently on the screen. */
uint32_t mTouchCount;
/* The transform from root screen coordinates into mApzcForInputBlock's
* screen coordinates, as returned through the 'aTransformToApzcOut' parameter
* of GetInputTransform(), at the start of the input block. This is cached

Просмотреть файл

@ -1,5 +1,5 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=4 ts=8 et tw=80 : */
/* vim: set sw=2 ts=8 et tw=80 : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -73,11 +73,7 @@ nsEventStatus GestureEventListener::HandleInputEvent(const InputData& aEvent)
}
}
NS_WARN_IF_FALSE(!foundAlreadyExistingTouch, "Tried to add a touch that already exists");
// If we didn't find a touch in our list that matches this, then add it.
// If it already existed, we don't want to add it twice because that
// messes with our touch move/end code.
if (!foundAlreadyExistingTouch) {
mTouches.AppendElement(event.mTouches[i]);
}
@ -137,17 +133,16 @@ nsEventStatus GestureEventListener::HandleInputEvent(const InputData& aEvent)
}
case MultiTouchInput::MULTITOUCH_END:
case MultiTouchInput::MULTITOUCH_LEAVE: {
for (size_t i = 0; i < event.mTouches.Length(); i++) {
bool foundAlreadyExistingTouch = false;
for (size_t i = 0; i < event.mTouches.Length() && !foundAlreadyExistingTouch; i++) {
for (size_t j = 0; j < mTouches.Length() && !foundAlreadyExistingTouch; j++) {
if (event.mTouches[i].mIdentifier == mTouches[j].mIdentifier) {
foundAlreadyExistingTouch = true;
mTouches.RemoveElementAt(j);
}
}
}
NS_WARN_IF_FALSE(foundAlreadyExistingTouch, "Touch ended, but not in list");
}
if (mState == GESTURE_WAITING_DOUBLE_TAP) {
CancelDoubleTapTimeoutTask();

Просмотреть файл

@ -1,5 +1,5 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=4 ts=8 et tw=80 : */
/* vim: set sw=2 ts=8 et tw=80 : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */