[webkit-changes] [WebKit/WebKit] 939e8d: [macOS] Scrolling with a physical mouse wheel shou...

Wenson Hsieh noreply at github.com
Tue Apr 18 07:56:44 PDT 2023


  Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 939e8d49f5a536e5b1227da1c0a93786342f839d
      https://github.com/WebKit/WebKit/commit/939e8d49f5a536e5b1227da1c0a93786342f839d
  Author: Wenson Hsieh <wenson_hsieh at apple.com>
  Date:   2023-04-18 (Tue, 18 Apr 2023)

  Changed paths:
    A LayoutTests/css3/scroll-snap/scroll-snap-discrete-wheel-event-in-mainframe-expected.txt
    A LayoutTests/css3/scroll-snap/scroll-snap-discrete-wheel-event-in-mainframe.html
    M LayoutTests/css3/scroll-snap/scroll-snap-wheel-event.html
    M LayoutTests/platform/glib/TestExpectations
    M LayoutTests/platform/ios-wk2/TestExpectations
    M LayoutTests/platform/mac-wk1/TestExpectations
    M Source/WebCore/platform/ScrollingEffectsController.h
    M Source/WebCore/platform/mac/ScrollingEffectsController.mm

  Log Message:
  -----------
  [macOS] Scrolling with a physical mouse wheel should not always animate to the closest snap point
https://bugs.webkit.org/show_bug.cgi?id=255493
rdar://107885426

Reviewed by Simon Fraser.

When scrolling using a physical mouse wheel in a scroll snap container, WebKit's current scroll snap
implementation handles each wheel event in a stateless manner, kicking off a scroll snap animation
to the closest snap point if no other wheel event is observed after 750 ms. This can lead to some
unintuitive behaviors when distances between scroll snap points are large, since the user may scroll
for a single wheel tick expecting to advance to the next page, only for the scroll position to
animate back to where they started.

This patch improves this by treating a stream of discrete wheel events similarly to trackpad-based
momentum scrolling, and animates to the appropriate snap point in the direction of scrolling; this
also aligns our implementation more closely with both Gecko and Blink.

See below for more details.

Test: css3/scroll-snap/scroll-snap-discrete-wheel-event-in-mainframe.html

* LayoutTests/css3/scroll-snap/scroll-snap-discrete-wheel-event-in-mainframe-expected.txt: Added.
* LayoutTests/css3/scroll-snap/scroll-snap-discrete-wheel-event-in-mainframe.html: Added.

Add a new layout test to exercise the change, in a mainframe (root) scroll snapping context.

* LayoutTests/css3/scroll-snap/scroll-snap-wheel-event.html:

Adjust an existing stateless scroll snapping test to exercise the change by lowering the scrolling
tick count from 3 to 1. Without this change, this adjustment would've bumped us back to the original
scroll position; after this change, we'll now animate to the next snap point.

* LayoutTests/platform/glib/TestExpectations:
* LayoutTests/platform/ios-wk2/TestExpectations:
* LayoutTests/platform/mac-wk1/TestExpectations:

Discrete wheel events on the root don't seem to trigger scroll snapping at all in WebKit1, both
before and after this patch. I filed webkit.org/b/255498, to track that issue separately.

* Source/WebCore/platform/ScrollingEffectsController.h:

Maintain a LIFO queue of up to three discrete wheel event deltas, which we use to determine the
user's intended scrolling direction after finishing a stream of discrete wheel events.

* Source/WebCore/platform/mac/ScrollingEffectsController.mm:
(WebCore::ScrollingEffectsController::stopAllTimers):
(WebCore::toWheelEventStatus):
(WebCore::operator<<):
(WebCore::ScrollingEffectsController::scheduleDiscreteScrollSnap):
(WebCore::ScrollingEffectsController::discreteSnapTransitionTimerFired):

Rename "stateless" -> "discrete", to reflect the fact that the new implementation is now stateful
by way of maintaining a queue of recent discrete wheel event deltas. Additionally, use
`transitionToGlideAnimationState()` to kick off scroll snapping if the average wheel event delta is
nonzero.

(WebCore::ScrollingEffectsController::processWheelEventForScrollSnap):
(WebCore::ScrollingEffectsController::scheduleStatelessScrollSnap): Deleted.

Dramatically reduce the delay before firing the scroll snap timer for discrete wheel events, now
that the purpose is no longer to wait for the user to manually scroll to the next page before
snapping, but rather observe enough events to estimate the user's intended scrolling direction.

(WebCore::ScrollingEffectsController::statelessSnapTransitionTimerFired): Deleted.

Canonical link: https://commits.webkit.org/263071@main




More information about the webkit-changes mailing list