mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 898443 - Ensure that all multitouch events following a START go to the same APZC instance. r=BenWa
This commit is contained in:
parent
d65bcff71e
commit
7430b1e2b7
@ -211,25 +211,37 @@ ApplyTransform(nsIntPoint* aPoint, const gfx3DMatrix& aMatrix)
|
||||
nsEventStatus
|
||||
APZCTreeManager::ReceiveInputEvent(const InputData& aEvent)
|
||||
{
|
||||
nsRefPtr<AsyncPanZoomController> apzc;
|
||||
gfx3DMatrix transformToApzc;
|
||||
gfx3DMatrix transformToScreen;
|
||||
switch (aEvent.mInputType) {
|
||||
case MULTITOUCH_INPUT: {
|
||||
const MultiTouchInput& multiTouchInput = aEvent.AsMultiTouchInput();
|
||||
apzc = GetTargetAPZC(ScreenPoint(multiTouchInput.mTouches[0].mScreenPoint),
|
||||
transformToApzc, transformToScreen);
|
||||
if (apzc) {
|
||||
if (multiTouchInput.mType == MultiTouchInput::MULTITOUCH_START) {
|
||||
mApzcForInputBlock = GetTargetAPZC(ScreenPoint(multiTouchInput.mTouches[0].mScreenPoint),
|
||||
transformToApzc, transformToScreen);
|
||||
} else {
|
||||
if (mApzcForInputBlock) {
|
||||
APZC_LOG("Re-using APZC %p as continuation of event block\n", mApzcForInputBlock.get());
|
||||
GetInputTransforms(mApzcForInputBlock, transformToApzc, transformToScreen);
|
||||
// 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)) {
|
||||
mApzcForInputBlock = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mApzcForInputBlock) {
|
||||
MultiTouchInput inputForApzc(multiTouchInput);
|
||||
for (int i = inputForApzc.mTouches.Length() - 1; i >= 0; i--) {
|
||||
ApplyTransform(&(inputForApzc.mTouches[i].mScreenPoint), transformToApzc);
|
||||
}
|
||||
apzc->ReceiveInputEvent(inputForApzc);
|
||||
mApzcForInputBlock->ReceiveInputEvent(inputForApzc);
|
||||
}
|
||||
break;
|
||||
} case PINCHGESTURE_INPUT: {
|
||||
const PinchGestureInput& pinchInput = aEvent.AsPinchGestureInput();
|
||||
apzc = GetTargetAPZC(pinchInput.mFocusPoint, transformToApzc, transformToScreen);
|
||||
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(pinchInput.mFocusPoint, transformToApzc, transformToScreen);
|
||||
if (apzc) {
|
||||
PinchGestureInput inputForApzc(pinchInput);
|
||||
ApplyTransform(&(inputForApzc.mFocusPoint), transformToApzc);
|
||||
@ -238,7 +250,7 @@ APZCTreeManager::ReceiveInputEvent(const InputData& aEvent)
|
||||
break;
|
||||
} case TAPGESTURE_INPUT: {
|
||||
const TapGestureInput& tapInput = aEvent.AsTapGestureInput();
|
||||
apzc = GetTargetAPZC(ScreenPoint(tapInput.mPoint), transformToApzc, transformToScreen);
|
||||
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(ScreenPoint(tapInput.mPoint), transformToApzc, transformToScreen);
|
||||
if (apzc) {
|
||||
TapGestureInput inputForApzc(tapInput);
|
||||
ApplyTransform(&(inputForApzc.mPoint), transformToApzc);
|
||||
@ -256,37 +268,50 @@ APZCTreeManager::ReceiveInputEvent(const nsInputEvent& aEvent,
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsRefPtr<AsyncPanZoomController> apzc;
|
||||
gfx3DMatrix transformToApzc;
|
||||
gfx3DMatrix transformToScreen;
|
||||
switch (aEvent.eventStructType) {
|
||||
case NS_TOUCH_EVENT: {
|
||||
const nsTouchEvent& touchEvent = static_cast<const nsTouchEvent&>(aEvent);
|
||||
if (touchEvent.touches.Length() > 0) {
|
||||
if (touchEvent.touches.Length() == 0) {
|
||||
break;
|
||||
}
|
||||
if (touchEvent.message == NS_TOUCH_START) {
|
||||
nsIntPoint point = touchEvent.touches[0]->mRefPoint;
|
||||
apzc = GetTargetAPZC(ScreenPoint::FromUnknownPoint(gfx::Point(point.x, point.y)),
|
||||
transformToApzc, transformToScreen);
|
||||
if (apzc) {
|
||||
MultiTouchInput inputForApzc(touchEvent);
|
||||
for (int i = inputForApzc.mTouches.Length() - 1; i >= 0; i--) {
|
||||
ApplyTransform(&(inputForApzc.mTouches[i].mScreenPoint), transformToApzc);
|
||||
mApzcForInputBlock = GetTargetAPZC(ScreenPoint(point.x, point.y),
|
||||
transformToApzc, transformToScreen);
|
||||
} else {
|
||||
if (mApzcForInputBlock) {
|
||||
APZC_LOG("Re-using APZC %p as continuation of event block\n", mApzcForInputBlock.get());
|
||||
GetInputTransforms(mApzcForInputBlock, transformToApzc, transformToScreen);
|
||||
// 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 (touchEvent.message == NS_TOUCH_CANCEL ||
|
||||
(touchEvent.message == NS_TOUCH_END && touchEvent.touches.Length() == 1)) {
|
||||
mApzcForInputBlock = nullptr;
|
||||
}
|
||||
|
||||
gfx3DMatrix outTransform = transformToApzc * transformToScreen;
|
||||
nsTouchEvent* outEvent = static_cast<nsTouchEvent*>(aOutEvent);
|
||||
for (int i = outEvent->touches.Length() - 1; i >= 0; i--) {
|
||||
ApplyTransform(&(outEvent->touches[i]->mRefPoint), outTransform);
|
||||
}
|
||||
|
||||
return apzc->ReceiveInputEvent(inputForApzc);
|
||||
}
|
||||
}
|
||||
if (mApzcForInputBlock) {
|
||||
MultiTouchInput inputForApzc(touchEvent);
|
||||
for (int i = inputForApzc.mTouches.Length() - 1; i >= 0; i--) {
|
||||
ApplyTransform(&(inputForApzc.mTouches[i].mScreenPoint), transformToApzc);
|
||||
}
|
||||
|
||||
gfx3DMatrix outTransform = transformToApzc * transformToScreen;
|
||||
nsTouchEvent* outEvent = static_cast<nsTouchEvent*>(aOutEvent);
|
||||
for (int i = outEvent->touches.Length() - 1; i >= 0; i--) {
|
||||
ApplyTransform(&(outEvent->touches[i]->mRefPoint), outTransform);
|
||||
}
|
||||
|
||||
return mApzcForInputBlock->ReceiveInputEvent(inputForApzc);
|
||||
}
|
||||
break;
|
||||
} case NS_MOUSE_EVENT: {
|
||||
const nsMouseEvent& mouseEvent = static_cast<const nsMouseEvent&>(aEvent);
|
||||
apzc = GetTargetAPZC(ScreenPoint::FromUnknownPoint(gfx::Point(mouseEvent.refPoint.x,
|
||||
mouseEvent.refPoint.y)),
|
||||
transformToApzc, transformToScreen);
|
||||
nsRefPtr<AsyncPanZoomController> apzc =
|
||||
GetTargetAPZC(ScreenPoint(mouseEvent.refPoint.x, mouseEvent.refPoint.y),
|
||||
transformToApzc, transformToScreen);
|
||||
if (apzc) {
|
||||
MultiTouchInput inputForApzc(mouseEvent);
|
||||
ApplyTransform(&(inputForApzc.mTouches[0].mScreenPoint), transformToApzc);
|
||||
|
@ -142,7 +142,6 @@ public:
|
||||
* General handler for incoming input events. Manipulates the frame metrics
|
||||
* based on what type of input it is. For example, a PinchGestureEvent will
|
||||
* cause scaling. This should only be called externally to this class.
|
||||
* HandleInputEvent() should be used internally.
|
||||
*/
|
||||
nsEventStatus ReceiveInputEvent(const InputData& aEvent);
|
||||
|
||||
@ -286,6 +285,12 @@ private:
|
||||
* is considered part of the APZC tree management state. */
|
||||
mozilla::Monitor mTreeLock;
|
||||
nsRefPtr<AsyncPanZoomController> mRootApzc;
|
||||
/* This tracks the APZC that should receive all inputs for the current input event block.
|
||||
* This allows touch points to move outside the thing they started on, but still have the
|
||||
* touch events delivered to the same initial APZC. This will only ever be touched on the
|
||||
* input delivery thread, and so does not require locking.
|
||||
*/
|
||||
nsRefPtr<AsyncPanZoomController> mApzcForInputBlock;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user