Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Page Up/Down scrolling feels too slow
https://bugs.webkit.org/show_bug.cgi?id=250224
rdar://101651891

Reviewed by Tim Horton.

Adjusts the keyboard scrolling parameters so that it feels faster.

* Source/WebCore/platform/KeyboardScroll.h:

Canonical link: https://commits.webkit.org/258598@main
  • Loading branch information
rr-codes committed Jan 7, 2023
1 parent 4a374fe commit f7ad74a
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 26 deletions.
35 changes: 26 additions & 9 deletions Source/WebCore/platform/KeyboardScroll.h
Expand Up @@ -51,19 +51,36 @@ struct KeyboardScroll {
};

struct KeyboardScrollParameters {
float springMass { 1 };
float springStiffness { 109 };
float springDamping { 20 };
const float springMass;
const float springStiffness;
const float springDamping;

float maximumVelocityMultiplier { 25 };
float timeToMaximumVelocity { 1 };
const float maximumVelocityMultiplier;
const float timeToMaximumVelocity;

float rubberBandForce { 5000 };
const float rubberBandForce;

static const KeyboardScrollParameters& parameters()
static constexpr KeyboardScrollParameters parameters()
{
static const KeyboardScrollParameters parameters;
return parameters;
#if PLATFORM(MAC) || PLATFORM(MACCATALYST)
return {
.springMass = 1,
.springStiffness = 175,
.springDamping = 20,
.maximumVelocityMultiplier = 25,
.timeToMaximumVelocity = 0.2,
.rubberBandForce = 3000
};
#else
return {
.springMass = 1,
.springStiffness = 109,
.springDamping = 20,
.maximumVelocityMultiplier = 25,
.timeToMaximumVelocity = 1.0,
.rubberBandForce = 5000
};
#endif
}
};

Expand Down
10 changes: 5 additions & 5 deletions Source/WebCore/platform/ScrollAnimationKeyboard.cpp
Expand Up @@ -124,7 +124,7 @@ void ScrollAnimationKeyboard::stopKeyboardScrollAnimation()
if (!m_currentKeyboardScroll)
return;

auto params = KeyboardScrollParameters::parameters();
constexpr auto params = KeyboardScrollParameters::parameters();

// Determine the settling position of the spring, conserving the system's current energy.
// Kinetic = elastic potential
Expand Down Expand Up @@ -168,7 +168,7 @@ bool ScrollAnimationKeyboard::animateScroll(MonotonicTime currentTime)
{
auto force = FloatSize { };
auto axesToApplySpring = FloatSize { 1, 1 };
KeyboardScrollParameters params = KeyboardScrollParameters::parameters();
constexpr auto parameters = KeyboardScrollParameters::parameters();

if (m_currentKeyboardScroll) {
auto scrollableDirections = scrollableDirectionsFromPosition(m_currentOffset);
Expand All @@ -183,7 +183,7 @@ bool ScrollAnimationKeyboard::animateScroll(MonotonicTime currentTime)
// The scroll view cannot scroll in this direction, and is rubber-banding.
// Apply a constant and significant force; otherwise, the force for a
// single-line increment is not strong enough to rubber-band perceptibly.
force = unitVectorForScrollDirection(direction).scaled(params.rubberBandForce);
force = unitVectorForScrollDirection(direction).scaled(parameters.rubberBandForce);
}

if (fabs(m_velocity.width()) >= fabs(m_currentKeyboardScroll->maximumVelocity.width()))
Expand All @@ -198,13 +198,13 @@ bool ScrollAnimationKeyboard::animateScroll(MonotonicTime currentTime)
FloatPoint idealPosition = (IntPoint(m_currentKeyboardScroll ? m_currentOffset : m_idealPosition).constrainedBetween(IntPoint(extents.minimumScrollOffset()), IntPoint(extents.maximumScrollOffset())));
FloatSize displacement = m_currentOffset - idealPosition;

auto springForce = -displacement.scaled(params.springStiffness) - m_velocity.scaled(params.springDamping);
auto springForce = -displacement.scaled(parameters.springStiffness) - m_velocity.scaled(parameters.springDamping);
force += springForce * axesToApplySpring;

float frameDuration = (currentTime - m_timeAtLastFrame).value();
m_timeAtLastFrame = currentTime;

FloatSize acceleration = force.scaled(1. / params.springMass);
FloatSize acceleration = force.scaled(1. / parameters.springMass);
m_velocity += acceleration.scaled(frameDuration);
m_currentOffset = m_currentOffset + m_velocity.scaled(frameDuration);

Expand Down
24 changes: 12 additions & 12 deletions Source/WebKit/UIProcess/ios/WKKeyboardScrollingAnimator.mm
Expand Up @@ -102,12 +102,6 @@ - (instancetype)initWithScrollable:(id <WKKeyboardScrollableInternal>)scrollable
return self;
}

- (const WebCore::KeyboardScrollParameters &)parameters
{
static const WebCore::KeyboardScrollParameters parameters;
return parameters;
}

- (void)invalidate
{
[self stopAnimatedScroll];
Expand Down Expand Up @@ -261,17 +255,19 @@ - (void)invalidate
// FIXME (227461): Replace with call to WebCore::KeyboardScroll constructor.
// FIXME (245749): Use `ScrollableArea::adjustVerticalPageScrollStepForFixedContent` to account for fixed content

constexpr auto parameters = WebCore::KeyboardScrollParameters::parameters();

CGFloat scrollDistance = [_scrollable distanceForIncrement:increment inDirection:direction];

WebCore::KeyboardScroll scroll;
scroll.offset = WebCore::unitVectorForScrollDirection(direction).scaled(scrollDistance);
scroll.granularity = increment;
scroll.direction = direction;
scroll.maximumVelocity = scroll.offset.scaled(self.parameters.maximumVelocityMultiplier);
scroll.maximumVelocity = scroll.offset.scaled(parameters.maximumVelocityMultiplier);

// Apply a constant force to achieve Vmax in timeToMaximumVelocity seconds.
// F_constant = m * Vmax / t
scroll.force = scroll.maximumVelocity.scaled(self.parameters.springMass / self.parameters.timeToMaximumVelocity);
scroll.force = scroll.maximumVelocity.scaled(parameters.springMass / parameters.timeToMaximumVelocity);

return scroll;
}
Expand Down Expand Up @@ -349,11 +345,13 @@ - (void)stopAnimatedScroll
if (!_currentScroll)
return;

constexpr auto parameters = WebCore::KeyboardScrollParameters::parameters();

// Determine the settling position of the spring, conserving the system's current energy.
// Kinetic = elastic potential
// 1/2 * m * v^2 = 1/2 * k * x^2
// x = sqrt(v^2 * m / k)
auto displacementMagnitudeSquared = (_velocity * _velocity).scaled(self.parameters.springMass / self.parameters.springStiffness);
auto displacementMagnitudeSquared = (_velocity * _velocity).scaled(parameters.springMass / parameters.springStiffness);
WebCore::FloatSize displacement = {
std::copysign(sqrt(displacementMagnitudeSquared.width()), _velocity.width()),
std::copysign(sqrt(displacementMagnitudeSquared.height()), _velocity.height())
Expand Down Expand Up @@ -400,6 +398,8 @@ - (void)displayLinkFired:(CADisplayLink *)sender
WebCore::FloatSize force;
WebCore::FloatSize axesToApplySpring = { 1, 1 };

constexpr auto parameters = WebCore::KeyboardScrollParameters::parameters();

if (_currentScroll) {
auto scrollableDirections = [_scrollable scrollableDirectionsFromOffset:_currentPosition];
auto direction = _currentScroll->direction;
Expand All @@ -413,7 +413,7 @@ - (void)displayLinkFired:(CADisplayLink *)sender
// The scroll view cannot scroll in this direction, and is rubber-banding.
// Apply a constant and significant force; otherwise, the force for a
// single-line increment is not strong enough to rubber-band perceptibly.
force = WebCore::unitVectorForScrollDirection(direction).scaled(self.parameters.rubberBandForce);
force = WebCore::unitVectorForScrollDirection(direction).scaled(parameters.rubberBandForce);
}

// If we've reached or exceeded the maximum velocity, stop applying any force.
Expand All @@ -430,12 +430,12 @@ - (void)displayLinkFired:(CADisplayLink *)sender

// Compute the spring's force, and apply it in allowed directions.
// F_spring = -k * x - c * v
auto springForce = - displacement.scaled(self.parameters.springStiffness) - _velocity.scaled(self.parameters.springDamping);
auto springForce = - displacement.scaled(parameters.springStiffness) - _velocity.scaled(parameters.springDamping);
force += springForce * axesToApplySpring;

// Integrate acceleration -> velocity -> position for this time step.
CFTimeInterval frameDuration = sender.targetTimestamp - sender.timestamp;
WebCore::FloatSize acceleration = force.scaled(1. / self.parameters.springMass);
WebCore::FloatSize acceleration = force.scaled(1. / parameters.springMass);
_velocity += acceleration.scaled(frameDuration);
_currentPosition += _velocity.scaled(frameDuration);

Expand Down

0 comments on commit f7ad74a

Please sign in to comment.