Bug 1153711 - Do not discard a component of a fling if an APZC further in the handoff chain has room to scroll in that direction. r=kats

This commit is contained in:
Botond Ballo 2015-04-15 12:38:26 -04:00
parent dad0ba9181
commit 0c32733c66
4 changed files with 49 additions and 9 deletions

View File

@ -434,17 +434,17 @@ public:
MOZ_ASSERT(mOverscrollHandoffChain);
TimeStamp now = AsyncPanZoomController::GetFrameTime();
// Drop any velocity on axes where we don't have room to scroll anyways.
// Drop any velocity on axes where we don't have room to scroll anyways
// (in this APZC, or an APZC further in the handoff chain).
// This ensures that we don't take the 'overscroll' path in Sample()
// on account of one axis which can't scroll having a velocity.
{
if (!mOverscrollHandoffChain->CanScrollInDirection(&mApzc, Layer::HORIZONTAL)) {
ReentrantMonitorAutoEnter lock(mApzc.mMonitor);
if (!mApzc.mX.CanScroll()) {
mApzc.mX.SetVelocity(0);
}
if (!mApzc.mY.CanScroll()) {
mApzc.mY.SetVelocity(0);
}
mApzc.mX.SetVelocity(0);
}
if (!mOverscrollHandoffChain->CanScrollInDirection(&mApzc, Layer::VERTICAL)) {
ReentrantMonitorAutoEnter lock(mApzc.mMonitor);
mApzc.mY.SetVelocity(0);
}
ParentLayerPoint velocity = mApzc.GetVelocityVector();
@ -1484,6 +1484,17 @@ AsyncPanZoomController::CanScrollWithWheel(const LayoutDevicePoint& aDelta) cons
return false;
}
bool
AsyncPanZoomController::CanScroll(Layer::ScrollDirection aDirection) const
{
ReentrantMonitorAutoEnter lock(mMonitor);
switch (aDirection) {
case Layer::HORIZONTAL: return mX.CanScroll();
case Layer::VERTICAL: return mY.CanScroll();
default: MOZ_ASSERT(false); return false;
}
}
bool
AsyncPanZoomController::AllowScrollHandoffInWheelTransaction() const
{

View File

@ -22,6 +22,7 @@
#include "Axis.h"
#include "InputQueue.h"
#include "APZUtils.h"
#include "Layers.h" // for Layer::ScrollDirection
#include "LayersTypes.h"
#include "TaskThrottler.h"
#include "mozilla/gfx/Matrix.h"
@ -370,6 +371,10 @@ public:
// direction.
bool CanScrollWithWheel(const LayoutDevicePoint& aDelta) const;
// Return whether or not there is room to scroll this APZC
// in the given direction.
bool CanScroll(Layer::ScrollDirection aDirection) const;
void NotifyMozMouseScrollEvent(const nsString& aString) const;
protected:

View File

@ -143,6 +143,24 @@ OverscrollHandoffChain::CanBePanned(const AsyncPanZoomController* aApzc) const
return false;
}
bool
OverscrollHandoffChain::CanScrollInDirection(const AsyncPanZoomController* aApzc,
Layer::ScrollDirection aDirection) const
{
// Find |aApzc| in the handoff chain.
uint32_t i = IndexOf(aApzc);
// See whether any APZC in the handoff chain starting from |aApzc|
// has room to scroll in the given direction.
for (uint32_t j = i; j < Length(); ++j) {
if (mChain[j]->CanScroll(aDirection)) {
return true;
}
}
return false;
}
bool
OverscrollHandoffChain::HasOverscrolledApzc() const
{

View File

@ -10,8 +10,9 @@
#include <vector>
#include "nsAutoPtr.h"
#include "nsISupportsImpl.h" // for NS_INLINE_DECL_REFCOUNTING
#include "Units.h" // for ScreenPoint
#include "APZUtils.h" // for CancelAnimationFlags
#include "Layers.h" // for Layer::ScrollDirection
#include "Units.h" // for ScreenPoint
namespace mozilla {
namespace layers {
@ -107,6 +108,11 @@ public:
// has room to be panned.
bool CanBePanned(const AsyncPanZoomController* aApzc) const;
// Determine whether the given APZC, or any APZC further in the chain,
// can scroll in the given direction.
bool CanScrollInDirection(const AsyncPanZoomController* aApzc,
Layer::ScrollDirection aDirection) const;
// Determine whether any APZC along this handoff chain is overscrolled.
bool HasOverscrolledApzc() const;