From e20eec18046125901ff31741ce8533fe228d02c7 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Thu, 22 Aug 2013 10:40:44 -0400 Subject: [PATCH] Bug 906427 - When a touch event has multiple touch points, send it to the root APZC for the layer subtree. r=BenWa --- gfx/layers/composite/APZCTreeManager.cpp | 17 +++++++++++++++++ gfx/layers/composite/APZCTreeManager.h | 1 + gfx/layers/ipc/AsyncPanZoomController.h | 8 ++++++++ 3 files changed, 26 insertions(+) diff --git a/gfx/layers/composite/APZCTreeManager.cpp b/gfx/layers/composite/APZCTreeManager.cpp index b5ca54fb0651..fcdfba5aa08b 100644 --- a/gfx/layers/composite/APZCTreeManager.cpp +++ b/gfx/layers/composite/APZCTreeManager.cpp @@ -222,6 +222,10 @@ APZCTreeManager::ReceiveInputEvent(const InputData& aEvent) nsRefPtr apzc2 = GetTargetAPZC(ScreenPoint(multiTouchInput.mTouches[i].mScreenPoint)); mApzcForInputBlock = CommonAncestor(mApzcForInputBlock.get(), apzc2.get()); APZC_LOG("Using APZC %p as the common ancestor\n", mApzcForInputBlock.get()); + // For now, we only ever want to do pinching on the root APZC for a given layers id. So + // when we find the common ancestor of multiple points, also walk up to the root APZC. + mApzcForInputBlock = RootAPZCForLayersId(mApzcForInputBlock); + APZC_LOG("Using APZC %p as the root APZC for multi-touch\n", mApzcForInputBlock.get()); } } else if (mApzcForInputBlock) { APZC_LOG("Re-using APZC %p as continuation of event block\n", mApzcForInputBlock.get()); @@ -289,6 +293,10 @@ APZCTreeManager::ReceiveInputEvent(const nsInputEvent& aEvent, GetTargetAPZC(ScreenPoint(point.x, point.y)); mApzcForInputBlock = CommonAncestor(mApzcForInputBlock.get(), apzc2.get()); APZC_LOG("Using APZC %p as the common ancestor\n", mApzcForInputBlock.get()); + // For now, we only ever want to do pinching on the root APZC for a given layers id. So + // when we find the common ancestor of multiple points, also walk up to the root APZC. + mApzcForInputBlock = RootAPZCForLayersId(mApzcForInputBlock); + APZC_LOG("Using APZC %p as the root APZC for multi-touch\n", mApzcForInputBlock.get()); } } else if (mApzcForInputBlock) { APZC_LOG("Re-using APZC %p as continuation of event block\n", mApzcForInputBlock.get()); @@ -659,5 +667,14 @@ APZCTreeManager::CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomCont return nullptr; } +AsyncPanZoomController* +APZCTreeManager::RootAPZCForLayersId(AsyncPanZoomController* aApzc) +{ + while (aApzc && !aApzc->IsRootForLayersId()) { + aApzc = aApzc->GetParent(); + } + return aApzc; +} + } } diff --git a/gfx/layers/composite/APZCTreeManager.h b/gfx/layers/composite/APZCTreeManager.h index 351b9a55ef55..fd5f5352364e 100644 --- a/gfx/layers/composite/APZCTreeManager.h +++ b/gfx/layers/composite/APZCTreeManager.h @@ -258,6 +258,7 @@ private: AsyncPanZoomController* FindTargetAPZC(AsyncPanZoomController* aApzc, const ScrollableLayerGuid& aGuid); AsyncPanZoomController* GetAPZCAtPoint(AsyncPanZoomController* aApzc, const gfxPoint& aHitTestPoint); AsyncPanZoomController* CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2); + AsyncPanZoomController* RootAPZCForLayersId(AsyncPanZoomController* aApzc); /** * Recursive helper function to build the APZC tree. The tree of APZC instances has diff --git a/gfx/layers/ipc/AsyncPanZoomController.h b/gfx/layers/ipc/AsyncPanZoomController.h index 1941283c7eab..bf9bfd1e0df6 100644 --- a/gfx/layers/ipc/AsyncPanZoomController.h +++ b/gfx/layers/ipc/AsyncPanZoomController.h @@ -633,6 +633,14 @@ public: AsyncPanZoomController* GetLastChild() const { return mLastChild; } AsyncPanZoomController* GetPrevSibling() const { return mPrevSibling; } AsyncPanZoomController* GetParent() const { return mParent; } + + /* Returns true if there is no APZC higher in the tree with the same + * layers id. + */ + bool IsRootForLayersId() const { + return !mParent || (mParent->mLayersId != mLayersId); + } + private: nsRefPtr mLastChild; nsRefPtr mPrevSibling;