Skip to content
Permalink
Browse files
Wheel event does not stop macOS smooth keyboard scroll
https://bugs.webkit.org/show_bug.cgi?id=244303
rdar://99101109

Reviewed by Tim Horton.

Currently, if you enable EventHandlerDrivenSmoothKeyboardScrolling,
scroll using the keyboard, then immediately after use the trackpad to
scroll, the webpage will scroll back to the position where the keyboard
scroll left off. This patch improves the smooth scroll setting so that a
wheel event tells the KeyboardScrollingAnimator to stop scrolling.

This adds a method to KeyboardScrollingAnimator, stopScrollingImmediately
 that can be called to stop the animation without taking the time
To decelerate, which is what should happen when a wheel event
Interrupts the keyboard scroll.

* LayoutTests/fast/scrolling/mac/keyboard-scrolling-with-mouse-scroll.html:
* Source/WebCore/platform/KeyboardScrollingAnimator.cpp
(WebCore::KeyboardScrollingAnimator::stopScrollingImmediately):
* Source/WebCore/platform/KeyboardScrollingAnimator.h
* Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp

Canonical link: https://commits.webkit.org/254561@main
  • Loading branch information
rr-codes authored and whsieh committed Sep 16, 2022
1 parent 1cbf001 commit 8c822fa15adbdecd22d0c3ece07c9e9aa2260af1
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 3 deletions.
@@ -0,0 +1,5 @@
PASS successfullyParsed is true

TEST COMPLETE
Successful.

@@ -0,0 +1,43 @@
<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true EventHandlerDrivenSmoothKeyboardScrollingEnabled=true ] -->

<html>

<head>
<script src="../../../resources/ui-helper.js"></script>
<script src="../../../resources/js-test.js"></script>
<meta name="viewport" content="initial-scale=1.5, user-scalable=no">
<script>
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.waitUntilDone();
}

async function runTest()
{
if (!window.testRunner || !testRunner.runUIScript)
return;

await UIHelper.rawKeyDown("downArrow");

setTimeout(async () => {
await UIHelper.rawKeyUp("downArrow");
await UIHelper.mouseWheelScrollAt(10, 10, 0, 1, 0, 10);

const position = window.scrollY;
if (position <= 1)
debug("Successful.");
else
debug("Unsuccessful. window.scrollY == " + position);

testRunner.notifyDone();
}, 100);
}
</script>
</head>

<body onload="runTest()">
<div style="height: 5000px;">
</div>
</body>

</html>
@@ -270,9 +270,7 @@ bool KeyboardScrollingAnimator::beginKeyboardScrollGesture(ScrollDirection direc

auto scrollableDirections = scrollableDirectionsFromPosition(m_scrollAnimator.currentPosition());
if (!scrollableDirections.at(boxSideForDirection(direction))) {
m_scrollTriggeringKeyIsPressed = false;
m_scrollController.didStopKeyboardScrolling();
m_velocity = { };
stopScrollingImmediately();
return false;
}

@@ -345,7 +343,13 @@ void KeyboardScrollingAnimator::handleKeyUpEvent()
return;

stopKeyboardScrollAnimation();
}

void KeyboardScrollingAnimator::stopScrollingImmediately()
{
m_scrollTriggeringKeyIsPressed = false;
m_scrollController.didStopKeyboardScrolling();
m_velocity = { };
}

} // namespace WebCore
@@ -57,6 +57,7 @@ class KeyboardScrollingAnimator : public CanMakeWeakPtr<KeyboardScrollingAnimato
bool beginKeyboardScrollGesture(ScrollDirection, ScrollGranularity);
void handleKeyUpEvent();
void updateKeyboardScrollPosition(MonotonicTime);
WEBCORE_EXPORT void stopScrollingImmediately();

private:
void stopKeyboardScrollAnimation();
@@ -104,6 +104,16 @@ void EventDispatcher::initializeConnection(IPC::Connection* connection)
void EventDispatcher::internalWheelEvent(PageIdentifier pageID, const WebWheelEvent& wheelEvent, RectEdges<bool> rubberBandableEdges, WheelEventOrigin wheelEventOrigin)
{
auto processingSteps = OptionSet<WebCore::WheelEventProcessingSteps> { WheelEventProcessingSteps::MainThreadForScrolling, WheelEventProcessingSteps::MainThreadForBlockingDOMEventDispatch };

ensureOnMainRunLoop([pageID] {
if (auto* webPage = WebProcess::singleton().webPage(pageID)) {
if (auto* corePage = webPage->corePage()) {
if (auto* keyboardScrollingAnimator = corePage->currentKeyboardScrollingAnimator())
keyboardScrollingAnimator->stopScrollingImmediately();
}
}
});

#if ENABLE(ASYNC_SCROLLING) && ENABLE(SCROLLING_THREAD)
do {
auto platformWheelEvent = platform(wheelEvent);

0 comments on commit 8c822fa

Please sign in to comment.