зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1249040 - Allow wheel scrolls to accumulate in the presence of scroll snapping. r=kats
MozReview-Commit-ID: EUyGvkoyu8I --HG-- extra : rebase_source : b9f9bbb7a11a976ff696c28b026d292a8f90d0e1
This commit is contained in:
Родитель
3098112a41
Коммит
460fb32c11
|
@ -58,7 +58,7 @@ AxisPhysicsMSDModel::Acceleration(const State &aState)
|
|||
|
||||
|
||||
double
|
||||
AxisPhysicsMSDModel::GetDestination()
|
||||
AxisPhysicsMSDModel::GetDestination() const
|
||||
{
|
||||
return mDestination;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
/**
|
||||
* Gets the raw destination of this axis at this moment.
|
||||
*/
|
||||
double GetDestination();
|
||||
double GetDestination() const;
|
||||
|
||||
/**
|
||||
* Sets the raw destination of this axis at this moment.
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace mozilla {
|
|||
namespace layers {
|
||||
|
||||
class WheelScrollAnimation;
|
||||
class SmoothScrollAnimation;
|
||||
|
||||
class AsyncPanZoomAnimation {
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncPanZoomAnimation)
|
||||
|
@ -52,6 +53,9 @@ public:
|
|||
virtual WheelScrollAnimation* AsWheelScrollAnimation() {
|
||||
return nullptr;
|
||||
}
|
||||
virtual SmoothScrollAnimation* AsSmoothScrollAnimation() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual bool WantsRepaints() {
|
||||
return true;
|
||||
|
|
|
@ -742,7 +742,7 @@ public:
|
|||
* frame. Returns true if the smooth scroll should be advanced by one frame,
|
||||
* or false if the smooth scroll has ended.
|
||||
*/
|
||||
bool DoSample(FrameMetrics& aFrameMetrics, const TimeDuration& aDelta) {
|
||||
bool DoSample(FrameMetrics& aFrameMetrics, const TimeDuration& aDelta) override {
|
||||
nsPoint oneParentLayerPixel =
|
||||
CSSPoint::ToAppUnits(ParentLayerPoint(1, 1) / aFrameMetrics.GetZoom());
|
||||
if (mXAxisModel.IsFinished(oneParentLayerPixel.x) &&
|
||||
|
@ -839,6 +839,15 @@ public:
|
|||
mYAxisModel.SetDestination(static_cast<int32_t>(aNewDestination.y));
|
||||
}
|
||||
|
||||
CSSPoint GetDestination() const {
|
||||
return CSSPoint::FromAppUnits(
|
||||
nsPoint(mXAxisModel.GetDestination(), mYAxisModel.GetDestination()));
|
||||
}
|
||||
|
||||
SmoothScrollAnimation* AsSmoothScrollAnimation() override {
|
||||
return this;
|
||||
}
|
||||
|
||||
private:
|
||||
AsyncPanZoomController& mApzc;
|
||||
AxisPhysicsMSDModel mXAxisModel, mYAxisModel;
|
||||
|
@ -1827,13 +1836,16 @@ nsEventStatus AsyncPanZoomController::OnScrollWheel(const ScrollWheelInput& aEve
|
|||
mozilla::Telemetry::Accumulate(mozilla::Telemetry::SCROLL_INPUT_METHODS,
|
||||
(uint32_t) ScrollInputMethodForWheelDeltaType(aEvent.mDeltaType));
|
||||
|
||||
// Wheel events from "clicky" mouse wheels trigger scroll snapping to the
|
||||
// next snap point. Check for this, and adjust the delta to take into
|
||||
// account the snap point.
|
||||
bool scrollSnapping = MaybeAdjustDeltaForScrollSnapping(delta, aEvent);
|
||||
|
||||
switch (aEvent.mScrollMode) {
|
||||
case ScrollWheelInput::SCROLLMODE_INSTANT: {
|
||||
|
||||
// Wheel events from "clicky" mouse wheels trigger scroll snapping to the
|
||||
// next snap point. Check for this, and adjust the delta to take into
|
||||
// account the snap point.
|
||||
CSSPoint startPosition = mFrameMetrics.GetScrollOffset();
|
||||
MaybeAdjustDeltaForScrollSnapping(aEvent, delta, startPosition);
|
||||
|
||||
ScreenPoint distance = ToScreenCoordinates(
|
||||
ParentLayerPoint(fabs(delta.x), fabs(delta.y)), aEvent.mLocalOrigin);
|
||||
|
||||
|
@ -1863,13 +1875,24 @@ nsEventStatus AsyncPanZoomController::OnScrollWheel(const ScrollWheelInput& aEve
|
|||
// update it.
|
||||
ReentrantMonitorAutoEnter lock(mMonitor);
|
||||
|
||||
if (scrollSnapping) {
|
||||
// If we're scroll snapping use a smooth scroll animation to get
|
||||
// Perform scroll snapping if appropriate.
|
||||
CSSPoint startPosition = mFrameMetrics.GetScrollOffset();
|
||||
// If we're already in a wheel scroll or smooth scroll animation,
|
||||
// the delta is applied to its destination, not to the current
|
||||
// scroll position. Take this into account when finding a snap point.
|
||||
if (mState == WHEEL_SCROLL) {
|
||||
startPosition = mAnimation->AsWheelScrollAnimation()->GetDestination();
|
||||
} else if (mState == SMOOTH_SCROLL) {
|
||||
startPosition = mAnimation->AsSmoothScrollAnimation()->GetDestination();
|
||||
}
|
||||
if (MaybeAdjustDeltaForScrollSnapping(aEvent, delta, startPosition)) {
|
||||
// If we're scroll snapping, use a smooth scroll animation to get
|
||||
// the desired physics. Note that SmoothScrollTo() will re-use an
|
||||
// existing smooth scroll animation if there is one.
|
||||
CSSPoint snapPoint = mFrameMetrics.GetScrollOffset() + (delta / mFrameMetrics.GetZoom());
|
||||
SmoothScrollTo(snapPoint);
|
||||
} else {
|
||||
SmoothScrollTo(startPosition);
|
||||
break;
|
||||
}
|
||||
|
||||
// Otherwise, use a wheel scroll animation, also reusing one if possible.
|
||||
if (mState != WHEEL_SCROLL) {
|
||||
CancelAnimation();
|
||||
|
@ -1889,7 +1912,6 @@ nsEventStatus AsyncPanZoomController::OnScrollWheel(const ScrollWheelInput& aEve
|
|||
|
||||
WheelScrollAnimation* animation = mAnimation->AsWheelScrollAnimation();
|
||||
animation->Update(aEvent.mTimeStamp, deltaInAppUnits, nsSize(velocity.x, velocity.y));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4027,7 +4049,9 @@ void AsyncPanZoomController::ScrollSnapToDestination() {
|
|||
}
|
||||
|
||||
bool AsyncPanZoomController::MaybeAdjustDeltaForScrollSnapping(
|
||||
ParentLayerPoint& aDelta, const ScrollWheelInput& aEvent)
|
||||
const ScrollWheelInput& aEvent,
|
||||
ParentLayerPoint& aDelta,
|
||||
CSSPoint& aStartPosition)
|
||||
{
|
||||
// Don't scroll snap for pixel scrolls. This matches the main thread
|
||||
// behaviour in EventStateManager::DoScrollText().
|
||||
|
@ -4036,15 +4060,15 @@ bool AsyncPanZoomController::MaybeAdjustDeltaForScrollSnapping(
|
|||
}
|
||||
|
||||
ReentrantMonitorAutoEnter lock(mMonitor);
|
||||
CSSPoint scrollOffset = mFrameMetrics.GetScrollOffset();
|
||||
CSSToParentLayerScale2D zoom = mFrameMetrics.GetZoom();
|
||||
CSSPoint destination = mFrameMetrics.CalculateScrollRange().ClampPoint(
|
||||
scrollOffset + (aDelta / zoom));
|
||||
aStartPosition + (aDelta / zoom));
|
||||
nsIScrollableFrame::ScrollUnit unit =
|
||||
ScrollWheelInput::ScrollUnitForDeltaType(aEvent.mDeltaType);
|
||||
|
||||
if (Maybe<CSSPoint> snapPoint = FindSnapPointNear(destination, unit)) {
|
||||
aDelta = (*snapPoint - scrollOffset) * zoom;
|
||||
aDelta = (*snapPoint - aStartPosition) * zoom;
|
||||
aStartPosition = *snapPoint;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -1155,9 +1155,13 @@ private:
|
|||
|
||||
// If |aEvent| should trigger scroll snapping, adjust |aDelta| to reflect
|
||||
// the snapping (that is, make it a delta that will take us to the desired
|
||||
// snap point). Returns true iff. the delta was so adjusted.
|
||||
bool MaybeAdjustDeltaForScrollSnapping(ParentLayerPoint& aDelta,
|
||||
const ScrollWheelInput& aEvent);
|
||||
// snap point). The delta is interpreted as being relative to
|
||||
// |aStartPosition|, and if a target snap point is found, |aStartPosition|
|
||||
// is also updated, to the value of the snap point.
|
||||
// Returns true iff. a target snap point was found.
|
||||
bool MaybeAdjustDeltaForScrollSnapping(const ScrollWheelInput& aEvent,
|
||||
ParentLayerPoint& aDelta,
|
||||
CSSPoint& aStartPosition);
|
||||
|
||||
// Snap to a snap position nearby the current scroll position, if appropriate.
|
||||
void ScrollSnap();
|
||||
|
|
|
@ -32,6 +32,10 @@ public:
|
|||
return this;
|
||||
}
|
||||
|
||||
CSSPoint GetDestination() const {
|
||||
return CSSPoint::FromAppUnits(mFinalDestination);
|
||||
}
|
||||
|
||||
private:
|
||||
void InitPreferences(TimeStamp aTime);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче