Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[macOS] Scrolling with a physical mouse wheel should not always animate to the closest snap point #12777

Merged
merged 43 commits into from Apr 18, 2023

Conversation

whsieh
Copy link
Member

@whsieh whsieh commented Apr 16, 2023

939e8d4

[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

7bbecb1

Misc iOS, tvOS & watchOS macOS Linux Windows
βœ… πŸ§ͺ style βœ… πŸ›  ios βœ… πŸ›  mac βœ… πŸ›  wpe βœ… πŸ›  wincairo
βœ… πŸ§ͺ bindings βœ… πŸ›  ios-sim βœ… πŸ›  mac-AS-debug βœ… πŸ§ͺ wpe-wk2
βœ… πŸ§ͺ webkitperl βœ… πŸ§ͺ ios-wk2 βœ… πŸ§ͺ api-mac βœ… πŸ›  gtk
βœ… πŸ§ͺ ios-wk2-wpt βœ… πŸ§ͺ mac-wk1 βœ… πŸ§ͺ gtk-wk2
βœ… πŸ§ͺ api-ios βœ… πŸ§ͺ mac-wk2 βœ… πŸ§ͺ api-gtk
βœ… πŸ›  tv βœ… πŸ§ͺ mac-AS-debug-wk2
βœ… πŸ›  tv-sim βœ… πŸ§ͺ mac-wk2-stress
βœ… πŸ›  πŸ§ͺ merge βœ… πŸ›  watch
βœ… πŸ›  watch-sim

@whsieh whsieh self-assigned this Apr 16, 2023
@whsieh whsieh added the Scrolling Bugs related to main thread and off-main thread scrolling label Apr 16, 2023
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Apr 16, 2023
@whsieh whsieh removed the merging-blocked Applied to prevent a change from being merged label Apr 16, 2023
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Apr 16, 2023
@whsieh whsieh removed the merging-blocked Applied to prevent a change from being merged label Apr 16, 2023
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Apr 16, 2023
@whsieh whsieh removed the merging-blocked Applied to prevent a change from being merged label Apr 16, 2023
Mark Lam and others added 11 commits April 17, 2023 11:52
…ONS is always 4.

https://bugs.webkit.org/show_bug.cgi?id=255497
rdar://108108389

Reviewed by Alexey Shvayka.

The code doesn't need to be conditional because for ARM64E, NUMBER_OF_ADDRESS_ENCODING_INSTRUCTIONS always equals 4.

* Source/JavaScriptCore/assembler/ARM64EAssembler.h:
(JSC::ARM64EAssembler::linkPointer):
(JSC::ARM64EAssembler::setPointer):
(JSC::ARM64EAssembler::readPointer):
(JSC::ARM64EAssembler::readCallTarget):

Canonical link: https://commits.webkit.org/263029@main
https://bugs.webkit.org/show_bug.cgi?id=248076

Reviewed by Michael Catanzaro.

Similar to the GTK port, a contextmenuevent should be generated for long
presses instead of a click event. We could generate a sequence of mouse
motion towards the desired point, mouse down, mouse up
(wpe_input_pointer_modifier_button2). This would cause the
contextmenuevent to be emitted, but also mousedown/mouseup events, which
are not expected. Since there seems to be no other way of doing this (at
the moment), implement a compromise: implement the detection of long tap
gestures, but don't generate the context mouse events yet.

Use a threshold value of 500 ms for detecting long tap gestures similar
to gtk-long-press-time's default of 500 ms.

See also: https://bugs.webkit.org/show_bug.cgi?id=251925

* Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp:
(WebKit::PageClientImpl::doneWithTouchEvent): Add no-op on
TouchGestureController::ContextMenuEvent.
* Source/WebKit/UIProcess/API/libwpe/TouchGestureController.cpp:
(WebKit::TouchGestureController::handleEvent): Generate ContextMenuEvent
for long presses.
* Source/WebKit/UIProcess/API/libwpe/TouchGestureController.h: Add
ContextMenu to GesturedEvent enum, create ContextMenuEvent and add it to
EventVariant.
* Source/WebKit/UIProcess/API/wpe/WPEView.cpp:
(WKWPE::m_backend): Add no-op for
TouchGestureController::ContextMenuEvent.

Canonical link: https://commits.webkit.org/263030@main
https://bugs.webkit.org/show_bug.cgi?id=255417
rdar://105621258

Reviewed by Chris Dumez.

If a WebContent process is a standalone worker process with a foreground
assertion/activity (e.g. a worker for a foreground view) and then a page
gets added to the process it will never take an assertion on the network
process as it should. We need to make sure we call
WebProcessProxy::didChangeThrottleState() when a standalone worker
process becomes a web content process with a page.
WebProcessProxy::didChangeThrottleState() checks
isStandaloneServiceWorkerProcess() and drops all network assertions if
it returns true.

* Source/WebKit/UIProcess/ProcessThrottler.h:
(WebKit::ProcessThrottler::currentState):
* Source/WebKit/UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::addExistingWebPage):

Canonical link: https://commits.webkit.org/263031@main
…sing it

https://bugs.webkit.org/show_bug.cgi?id=255539
rdar://problem/108150437

Reviewed by Eric Carlson.

* Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm:
(WebCore::AVVideoCaptureSource::monitorOrientation):

Canonical link: https://commits.webkit.org/263032@main
…review'

https://bugs.webkit.org/show_bug.cgi?id=255535
<rdar://107159915>

Reviewed by Patrick Angle.

We have a number of features that were in Preview state, that are now on-by-default. Since
Preview is only meant to indicate features that are off-by-default for stable software, we
should reflect the fact that these feature are complete by moving them to 'stable'.

* Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml:

Canonical link: https://commits.webkit.org/263033@main
https://bugs.webkit.org/show_bug.cgi?id=255534
rdar://108148657

Reviewed by Dewei Zhu.

* Tools/Scripts/webkitpy/benchmark_runner/data/plans/speedometer2.1.plan:

Canonical link: https://commits.webkit.org/263034@main
… be slow.

https://bugs.webkit.org/show_bug.cgi?id=24438
<rdar://103334931>

Reviewed by Dean Jackson.

This detects the case where we want to create a transparency layer, but the only contents that
will be drawn is a single bitmap image. We can instead just set the alpha on the GraphicsContext
and save the transparency layer (as well as the save/restore pair and the clip).

This could be extended in the future to detect more cases where we will only do a single draw call
within the transparency layer.

* Source/WebCore/rendering/RenderLayer.cpp:
(WebCore::RenderLayer::beginTransparencyLayers):
(WebCore::RenderLayer::paintLayerContents):
(WebCore::RenderLayer::calculateClipRects const):
* Source/WebCore/rendering/RenderLayer.h:
(WebCore::RenderLayer::paintsWithTransparency const):
(WebCore::RenderLayer::canPaintTransparencyWithSetOpacity const):
(WebCore::RenderLayer::hasNonOpacityTransparency const):
* Source/WebCore/rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::isBitmapOnly const):

Canonical link: https://commits.webkit.org/263035@main
…it.com and many other websites, flickering on cnn.com

https://bugs.webkit.org/show_bug.cgi?id=255488

Reviewed by Adrian Perez de Castro.

The second parameter to cairo_scaled_font_text_extents() must be a
NUL-terminated UTF-8 string.

* Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp:
(WebCore::heightOfCharacter):
(WebCore::Font::platformInit):

Canonical link: https://commits.webkit.org/263036@main
…ction reference date

https://bugs.webkit.org/show_bug.cgi?id=255541
rdar://108108131

Reviewed by Tim Horton.

This fixes a regression from 262558@main with a test that would hit the crash.

* Source/WebCore/editing/cocoa/DataDetection.h:
* Source/WebCore/editing/cocoa/DataDetection.mm:
(WebCore::DataDetection::extractReferenceDate):
(WebCore::DataDetection::detectContentInRange):
* Source/WebCore/loader/FrameLoader.cpp:
(WebCore::FrameLoader::checkLoadCompleteForThisFrame):
* Source/WebCore/loader/FrameLoaderClient.h:
* Source/WebKit/Shared/Cocoa/LoadParametersCocoa.mm:
(WebKit::LoadParameters::platformEncode const):
(WebKit::LoadParameters::platformDecode):
* Source/WebKit/Shared/LoadParameters.h:
* Source/WebKit/UIProcess/API/APIUIClient.h:
(API::UIClient::dataDetectionReferenceDate):
(API::UIClient::dataDetectionContext): Deleted.
* Source/WebKit/UIProcess/Cocoa/UIDelegate.h:
* Source/WebKit/UIProcess/Cocoa/UIDelegate.mm:
(WebKit::UIDelegate::UIClient::dataDetectionReferenceDate):
(WebKit::UIDelegate::UIClient::dataDetectionContext): Deleted.
* Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm:
(WebKit::WebPageProxy::addPlatformLoadParameters):
* Source/WebKit/WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInRangeHandle.mm:
(-[WKWebProcessPlugInRangeHandle detectDataWithTypes:context:]):
* Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::dataDetectionReferenceDate):
(WebKit::WebFrameLoaderClient::dataDetectionContext): Deleted.
* Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h:
* Source/WebKit/WebProcess/WebPage/Cocoa/WebPageCocoa.mm:
(WebKit::WebPage::platformDidReceiveLoadParameters):
* Source/WebKit/WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::detectDataInAllFrames):
* Source/WebKit/WebProcess/WebPage/WebPage.h:
(WebKit::WebPage::dataDetectionReferenceDate const):
(WebKit::WebPage::dataDetectionContext const): Deleted.
* Tools/TestWebKitAPI/Tests/WebKitCocoa/DataDetection.mm:
(-[DataDetectionUIDelegate _dataDetectionContextForWebView:]):
* Tools/TestWebKitAPI/Tests/ios/ActionSheetTests.mm:
(TestWebKitAPI::TEST):

Canonical link: https://commits.webkit.org/263037@main
https://bugs.webkit.org/show_bug.cgi?id=255545
<rdar://107159906>

Reviewed by Patrick Angle.

The 'NotificationsEnabled' feature flag is not a development flag; it is just
a toggle for A/B testing. It should therefore be in the 'stable' category.

* Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml:

Canonical link: https://commits.webkit.org/263038@main
https://bugs.webkit.org/show_bug.cgi?id=255547
rdar://108158754

Reviewed by Brent Fulgham.

It seems that 258448@main mistakenly turned on the color part of CSS Typed OM
which is incomplete and definitely not ready to ship.

* Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml:

Canonical link: https://commits.webkit.org/263039@main
yury-s and others added 25 commits April 17, 2023 17:24
https://bugs.webkit.org/show_bug.cgi?id=255548

Reviewed by Fujii Hironori.

When using ephemeral context the following error message was printed to the console:
Unable to create the Cookie Database path :memory:

* Source/WebCore/platform/network/curl/CookieJarDB.cpp:
(WebCore::CookieJarDB::openDatabase):

Canonical link: https://commits.webkit.org/263046@main
https://bugs.webkit.org/show_bug.cgi?id=255561
rdar://108166036

Reviewed by Alex Christensen.

Add DataTaskReceivedChallengeReply to the expected messages list for
secure mode decoding of NSURLCredential.

* Source/WebKit/Shared/Cocoa/ArgumentCodersCocoa.mm:
(IPC::shouldEnableStrictMode):

Canonical link: https://commits.webkit.org/263047@main
https://bugs.webkit.org/show_bug.cgi?id=255567

Broke internal Safari build

Reverted changeset:

"clang-cl reports "error: reference to 'UUID' is ambiguous" for Windows port"
https://bugs.webkit.org/show_bug.cgi?id=234696
https://commits.webkit.org/263042@main

Canonical link: https://commits.webkit.org/263048@main
…oesn't throw IndexSizeError

https://bugs.webkit.org/show_bug.cgi?id=255500
rdar://problem/108115821

Reviewed by Said Abou-Hallawa.

This patch aligns WebKit to Blink / Chromium, Gecko / Firefox and Web-Spec.

Cherry-Pick: https://src.chromium.org/viewvc/blink?view=revision&revision=201411

According to the spec [1], IndexSizeError should be thrown if:

"...the charnum is negative or if charnum is greater than or equal to
 the number of characters at this node."

[1] http://www.w3.org/TR/SVG11/text.html#__svg__SVGTextContentElement__getStartPositionOfChar
    The current SVG2 draft has a different formulation:

     SVG2 - https://svgwg.org/svg2-draft/text.html#__svg__SVGTextContentElement__getStartPositionOfChar
     "If cluster is null, then then throw a DOMException with code
      INDEX_SIZE_ERR."

    but will have the same result.

* Source/WebCore/svg/SVGTextContentElement.cpp:
(SVGTextContentElement::getStartPositionOfChar):
(SVGTextContentElement::getEndPositionOfChar):
(SVGTextContentElement::getExtentOfChar):
(SVGTextContentElement::getRotationOfChar):
* LayoutTests/svg/text/svgtextcontentelement-equality-methods-parameters.html: Add Test
* LayoutTests/svg/text/svgtextcontentelement-equality-methods-parameters-expected.txt: Add Test Expectation

Canonical link: https://commits.webkit.org/263049@main
…ING_INSTRUCTIONS is always 4.

https://bugs.webkit.org/show_bug.cgi?id=255497
rdar://108108389

Reviewed by Justin Michaud.

The code doesn't need to be conditional because for ARM64E, NUMBER_OF_ADDRESS_ENCODING_INSTRUCTIONS always equals 4.
The previous patch removed ARM64EAssembler::MAX_POINTER_BITS.  Turns out, this is needed to override the one in
ARM64Assembler.  This patch keeps it, which fixes all the regressions from the previous landing.

* Source/JavaScriptCore/assembler/ARM64EAssembler.h:
(JSC::ARM64EAssembler::linkPointer):
(JSC::ARM64EAssembler::setPointer):
(JSC::ARM64EAssembler::readPointer):
(JSC::ARM64EAssembler::readCallTarget):
* Source/JavaScriptCore/assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::moveWithFixedWidth):

Canonical link: https://commits.webkit.org/263050@main
…eWithHTMLTreeBuilder

https://bugs.webkit.org/show_bug.cgi?id=255510
rdar://107979390

Reviewed by Ryosuke Niwa.

This change fixes a crash which is caused because we end up in state
where m_lastNodeInserted is NULL after a call to
ReplaceSelectionCommand::InsertedNodes::willRemoveNode, which means that
when makeInsertedContentRoundTrippableWithHTMLTreeBuilder calls
pastLastLeaf() we trip over an assertion.

* LayoutTests/fast/editing/replace-selection-command-crash-expected.txt: Added.
* LayoutTests/fast/editing/replace-selection-command-crash.html: Added.
* Source/WebCore/editing/ReplaceSelectionCommand.cpp:
(WebCore::ReplaceSelectionCommand::InsertedNodes::willRemoveNode):

Canonical link: https://commits.webkit.org/263051@main
https://bugs.webkit.org/show_bug.cgi?id=255419
<rdar://problem/108026194>

Reviewed by Antti Koivisto.

Form controls with appearance are supposed to set their minimum (intrinsic) widths so that they don't get overlapped (e.g. by getting sized to 0px)
in over-constrained situations.

* LayoutTests/fast/flexbox/overlapped-form-controls-expected.html: Added.
* LayoutTests/fast/flexbox/overlapped-form-controls.html: Added.
* Source/WebCore/platform/Theme.cpp:
(WebCore::Theme::minimumControlSize const):

Canonical link: https://commits.webkit.org/263052@main
… crash

https://bugs.webkit.org/show_bug.cgi?id=255566
rdar://108169157

Reviewed by Wenson Hsieh.

When selecting text with Live Text, if the selection contains different writing modes, a crash
can occur when collecting the selection geometries if the ancestor does not have a renderer.

This PR fixes this by adding a null check for the existence of a renderer.

* Source/WebCore/rendering/RenderObject.cpp:
(WebCore::RenderObject::collectSelectionGeometriesInternal):

Canonical link: https://commits.webkit.org/263053@main
…PUConnectionToWebProcess

https://bugs.webkit.org/show_bug.cgi?id=255429
<rdar://problem/108171820>

Reviewed by Matt Woodrow.

This patch isn't strictly necessary, but I do think this is a better design.

Previously, every GPU object in the web process got its own identifier, and that identifier got sent to the GPU process.
The GPU process has a GPUConnectionToWebProcess for each web process, and it owned a HashMap<> of the GPU objects for
that web process.

That's okay, but it doesn't fit very well with the design of the GPU process. Every Page in the web process has an
associated RemoteRenderingBackend for that page, which is the owner of all the resources used by that page (the
RemoteRenderingBackend owns a RemoteResourceCache which contains all the resources). It's a generally better design to
match this for WebGPU, and make the GPU object owned by the RemoteRenderingBackend rather than the
GPUConnectionToWebProcess.

There are a few benefits to this design:
1. It more closely matches the ownership model for normal page drawing, which just makes it less complicated to understand
       and reason about
2. At some point, we're going to have to implement interactions with other parts of the web platform (videos, canvas 2d,
       etc.) in WebGPU. All those resources are owned by the RemoteRenderingBackend. We could have each individual entry
       point reach into the RemoteRenderingBackend to pull out what it needs, but it's a more convenient design if
       everything just already lives in the same place.

No tests because there is no behavior change.

* Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp:
(WebKit::GPUConnectionToWebProcess::createRemoteGPU): Deleted.
(WebKit::GPUConnectionToWebProcess::releaseRemoteGPU): Deleted.
* Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h:
* Source/WebKit/GPUProcess/GPUConnectionToWebProcess.messages.in:
* Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp:
(WebKit::RemoteRenderingBackend::createRemoteGPU):
(WebKit::RemoteRenderingBackend::releaseRemoteGPU):
* Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.h:
* Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.messages.in:
* Source/WebKit/GPUProcess/graphics/WebGPU/RemoteGPU.cpp:
(WebKit::RemoteGPU::RemoteGPU):
(WebKit::RemoteGPU::initialize):
(WebKit::RemoteGPU::stopListeningForIPC):
* Source/WebKit/GPUProcess/graphics/WebGPU/RemoteGPU.h:
* Source/WebKit/WebProcess/GPU/graphics/WebGPU/RemoteGPUProxy.cpp:
(WebKit::RemoteGPUProxy::create):
(WebKit::RemoteGPUProxy::RemoteGPUProxy):
(WebKit::RemoteGPUProxy::~RemoteGPUProxy):
(WebKit::RemoteGPUProxy::initializeIPC):
(WebKit::RemoteGPUProxy::disconnectGpuProcessIfNeeded): Deleted.
(WebKit::RemoteGPUProxy::gpuProcessConnectionDidClose): Deleted.
(WebKit::RemoteGPUProxy::abandonGPUProcess): Deleted.
* Source/WebKit/WebProcess/GPU/graphics/WebGPU/RemoteGPUProxy.h:
* Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::createGPUForWebGPU const):

Canonical link: https://commits.webkit.org/263054@main
https://bugs.webkit.org/show_bug.cgi?id=255345

Reviewed by Mark Lam, Elliott Williams and David Kilzer.

When a process crashes we will now try to determine whether this crash was caused by
a PGM allocation in WebKit. ReportCrash will call into JSC, which would forward the information
onto libpas. libpas will respond with a report generated from the memory of the now dead process.

libpas will determine whether this was a PGM crash and if so what kind of crash (UAF or OOB).
This information will be added to the local crash log generated.

* Source/JavaScriptCore/API/PASReportCrashPrivate.cpp: Added.
(PASReportCrashExtractResults):
* Source/JavaScriptCore/API/PASReportCrashPrivate.h: Added.
* Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj:
* Source/JavaScriptCore/SourcesCocoa.txt:
* Source/bmalloc/CMakeLists.txt:
* Source/bmalloc/bmalloc.xcodeproj/project.pbxproj:
* Source/bmalloc/libpas/libpas.xcodeproj/project.pbxproj:
* Source/bmalloc/libpas/src/libpas/pas_enumerate_large_heaps.c:
(pas_hash_map_entry_callback):
* Source/bmalloc/libpas/src/libpas/pas_report_crash.c: Added.
(memory_reader_adapter):
(setup_memory_reader):
(pas_report_crash_extract_pgm_failure):
* Source/bmalloc/libpas/src/libpas/pas_report_crash.h: Added.
* Source/bmalloc/libpas/src/libpas/pas_report_crash_pgm_report.h: Added.

Canonical link: https://commits.webkit.org/263055@main
https://bugs.webkit.org/show_bug.cgi?id=255542
rdar://108153724

Reviewed by Justin Michaud.

We found that for-in + put_by_val is common pattern, like

    for (var key in object)
        object[key] = object[key] + 42;

Previously, we handle `object[key]` as normal put_by_val. But since we can propagate offset information from JSPropertyNameEnumerator,
we can make `object[key]` super fast as the same way to `enumerator_get_by_val`. This patch adds op_enumerator_put_by_val, which is
handled almost the same way to op_enumerator_get_by_val.

1. We add op_enumerator_put_by_val, very similar to op_enumerator_get_by_val. And we add corresponding DFG / FTL node, EnumeratorPutByVal.
1. We add didWatchReplacement bit to Structure since it needs watchpoint invalidation. So we cannot do super fast replace for that.

* JSTests/stress/for-in-put-by-val.js: Added.
(shouldBe):
(test):
* Source/JavaScriptCore/bytecode/BytecodeList.rb:
* Source/JavaScriptCore/bytecode/BytecodeUseDef.cpp:
(JSC::computeUsesForBytecodeIndexImpl):
(JSC::computeDefsForBytecodeIndexImpl):
* Source/JavaScriptCore/bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finishCreation):
* Source/JavaScriptCore/bytecode/Opcode.h:
* Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitPutByVal):
(JSC::BytecodeGenerator::emitEnumeratorPutByVal):
(JSC::ForInContext::finalize):
* Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h:
(JSC::ForInContext::addPutInst):
* Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:
(JSC::AssignBracketNode::emitBytecode):
* Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp:
(JSC::DFG::BackwardsPropagationPhase::propagate):
* Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* Source/JavaScriptCore/dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* Source/JavaScriptCore/dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* Source/JavaScriptCore/dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* Source/JavaScriptCore/dfg/DFGNode.h:
(JSC::DFG::Node::hasStorageChild const):
(JSC::DFG::Node::storageChildIndex):
(JSC::DFG::Node::hasArrayMode):
(JSC::DFG::Node::hasECMAMode):
(JSC::DFG::Node::ecmaMode):
* Source/JavaScriptCore/dfg/DFGNodeType.h:
* Source/JavaScriptCore/dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* Source/JavaScriptCore/dfg/DFGOperations.h:
* Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp:
* Source/JavaScriptCore/dfg/DFGSSALoweringPhase.cpp:
(JSC::DFG::SSALoweringPhase::handleNode):
* Source/JavaScriptCore/dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h:
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
(JSC::DFG::SpeculativeJIT::compileEnumeratorPutByVal):
* Source/JavaScriptCore/dfg/DFGStoreBarrierInsertionPhase.cpp:
* Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp:
(JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
(JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
* Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h:
* Source/JavaScriptCore/ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
* Source/JavaScriptCore/jit/BaselineJITRegisters.h:
* Source/JavaScriptCore/jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
* Source/JavaScriptCore/jit/JIT.h:
* Source/JavaScriptCore/jit/JITPropertyAccess.cpp:
(JSC::JIT::generatePutByValSlowCase):
(JSC::JIT::emitSlow_op_put_by_val):
(JSC::JIT::emit_op_enumerator_put_by_val):
(JSC::JIT::emitSlow_op_enumerator_put_by_val):
* Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm:
* Source/JavaScriptCore/llint/LowLevelInterpreter64.asm:
* Source/JavaScriptCore/runtime/CommonSlowPaths.cpp:
(JSC::JSC_DEFINE_COMMON_SLOW_PATH):
* Source/JavaScriptCore/runtime/CommonSlowPaths.h:
* Source/JavaScriptCore/runtime/CommonSlowPathsInlines.h:
(JSC::CommonSlowPaths::opEnumeratorPutByVal):
* Source/JavaScriptCore/runtime/JSObject.cpp:
(JSC::JSObject::putOwnDataPropertyBatching):
* Source/JavaScriptCore/runtime/PropertySlot.h:
* Source/JavaScriptCore/runtime/Structure.cpp:
(JSC::Structure::ensurePropertyReplacementWatchpointSet):
* Source/JavaScriptCore/runtime/Structure.h:
(JSC::Structure::bitFieldOffset):
* Source/JavaScriptCore/runtime/StructureInlines.h:
(JSC::Structure::didReplaceProperty):
* Source/JavaScriptCore/runtime/StructureTransitionTable.h:

Canonical link: https://commits.webkit.org/263056@main
https://bugs.webkit.org/show_bug.cgi?id=255570
rdar://108171748

Reviewed by Justin Michaud.

StructureAlignedMemoryAllocator ensures that we can compose Structure* with StructureID with BitOr operation.
This patch changes add64 to or64 since or64 can encode bits more nicely in imm field, removing one unnecessary `mov`.

* Source/JavaScriptCore/jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::emitNonNullDecodeZeroExtendedStructureID):

Canonical link: https://commits.webkit.org/263057@main
https://bugs.webkit.org/show_bug.cgi?id=255578

Reviewed by Chris Dumez.

Fix the typo in the specialization I introduced. Verified that using the
new downcast on a WeakPtr builds fine.

* Source/WTF/wtf/WeakPtr.h:
(WTF::downcast):

Canonical link: https://commits.webkit.org/263058@main
…* __cdecl WebCore::Document::view(void) const

https://bugs.webkit.org/show_bug.cgi?id=255581

Unreviewed build fix for Windows Release clang-cl build.

* Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp:
Include "LocalFrame.h".

Canonical link: https://commits.webkit.org/263059@main
https://bugs.webkit.org/show_bug.cgi?id=255506
rdar://problem/108124823

Reviewed by Dean Jackson.

Add WebKit specific files that include conditional compiled code files
with the conditions. The per file conditions will be removed from the
individual files in upstream.

Make the build system define ANGLE_ENABLE_EAGL and the new, to be used define
ANGLE_ENABLE_CGL.

The defines are defined as follows:
  - All ANGLE_ENABLE_METAL
  - macOS ANGLE_ENABLE_CGL
  - macOS x86_64 Catalyst ANGLE_ENABLE_CGL
  - macOS ARM Catalyst ANGLE_ENABLE_CGL ANGLE_ENABLE_EAGL
  - iOS family ANGLE_ENABLE_EAGL

* Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj:
* Source/ThirdParty/ANGLE/Configurations/ANGLE-dynamic.xcconfig:
* Source/ThirdParty/ANGLE/WebKit/SourcesCGL-mm.mm: Added.
* Source/ThirdParty/ANGLE/WebKit/SourcesCGL.cpp: Added.
* Source/ThirdParty/ANGLE/WebKit/SourcesEAGL.cpp: Added.
* Source/ThirdParty/ANGLE/WebKit/SourcesEAGL1-mm.mm: Added.
* Source/ThirdParty/ANGLE/WebKit/SourcesEAGL2-mm.mm: Added.
* Source/ThirdParty/ANGLE/WebKit/SourcesGL.cpp: Added.
* Source/ThirdParty/ANGLE/WebKit/SourcesPlatform-mm.mm: Added.
* Source/ThirdParty/ANGLE/WebKit/SourcesPlatform.cpp: Added.
* Source/ThirdParty/ANGLE/src/common/platform.h:
* Source/ThirdParty/ANGLE/src/libANGLE/Display.cpp:
* Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/apple/DisplayApple_api.cpp:

Canonical link: https://commits.webkit.org/263060@main
https://bugs.webkit.org/show_bug.cgi?id=254807

Reviewed by Ε½an DoberΕ‘ek.

This might happen in systems with multiple GPUs enabled. The problem is that
we might end up using a different GPU than the one used by the
application in the UI process. This is because both GBMDevice and mesa
surfaceless platform use always the first device having a render node
returned by drmGetDevices2(). To make sure we use the right GPU
everywhere we need to get the GPU used by the UI process and send it
to the web process. Mesa surfaceless platform doesn't allow to change the
device, so we need to use GBM platform that receives the device as the
native display when initializing the EGL display. Surfaceless platform
is still used for swrast, because GBM requires a GPU device.

* Source/WebCore/PlatformGTK.cmake:
* Source/WebCore/SourcesGTK.txt:
* Source/WebCore/platform/graphics/PlatformDisplay.cpp:
(WebCore::PlatformDisplay::~PlatformDisplay):
(WebCore::PlatformDisplay::eglDevice):
(WebCore::PlatformDisplay::drmDeviceFile):
(WebCore::drmRenderNodeFromPrimaryDeviceFile):
(WebCore::PlatformDisplay::drmRenderNodeFile):
(WebCore::PlatformDisplay::gbmDevice):
* Source/WebCore/platform/graphics/PlatformDisplay.h:
* Source/WebCore/platform/graphics/egl/GLContext.cpp:
(WebCore::GLContext::getEGLConfig):
(WebCore::GLContext::createWindowContext):
(WebCore::GLContext::create):
(WebCore::GLContext::createSharing):
* Source/WebCore/platform/graphics/egl/PlatformDisplaySurfaceless.cpp: Renamed from Source/WebCore/platform/graphics/egl/PlatformDisplayHeadless.cpp.
* Source/WebCore/platform/graphics/egl/PlatformDisplaySurfaceless.h: Renamed from Source/WebCore/platform/graphics/egl/PlatformDisplayHeadless.h.
* Source/WebCore/platform/graphics/gbm/PlatformDisplayGBM.cpp: Added.
(WebCore::PlatformDisplayGBM::create):
(WebCore::PlatformDisplayGBM::PlatformDisplayGBM):
(WebCore::PlatformDisplayGBM::~PlatformDisplayGBM):
* Source/WebCore/platform/graphics/gbm/PlatformDisplayGBM.h: Added.
* Source/WebKit/Shared/WebProcessCreationParameters.cpp:
(WebKit::WebProcessCreationParameters::encode const):
(WebKit::WebProcessCreationParameters::decode):
* Source/WebKit/Shared/WebProcessCreationParameters.h:
* Source/WebKit/UIProcess/API/glib/WebKitProtocolHandler.cpp:
(WebKit::WebKitProtocolHandler::handleGPU):
* Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp:
(WebKit::WebProcessPool::platformInitializeWebProcess):
* Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreDMABuf.cpp:
(WebKit::AcceleratedBackingStoreDMABuf::Surface::Surface):
* Source/WebKit/WebProcess/WebPage/AcceleratedSurface.cpp:
(WebKit::AcceleratedSurface::create):
* Source/WebKit/WebProcess/WebPage/gtk/AcceleratedSurfaceDMABuf.cpp:
(WebKit::AcceleratedSurfaceDMABuf::AcceleratedSurfaceDMABuf):
(WebKit::AcceleratedSurfaceDMABuf::RenderTargetEGLImage::create):
* Source/WebKit/WebProcess/glib/WebProcessGLib.cpp:
(WebKit::WebProcess::platformInitializeWebProcess):

Canonical link: https://commits.webkit.org/263061@main
https://bugs.webkit.org/show_bug.cgi?id=255515
rdar://108134621

Reviewed by Mike Wyrzykowski.

The global variable rewriter visitor overrides the Variable visitor, as it needs to record
variable definitions that may shadow globals, but it fails to visit the variable initializer
(if there is one), which means that globals used in the initializer are undetected. To fix
that we simply call the base visitor's visit method on the variable declaration.

* Source/WebGPU/WGSL/GlobalVariableRewriter.cpp:
(WGSL::RewriteGlobalVariables::visit):

Canonical link: https://commits.webkit.org/263062@main
https://bugs.webkit.org/show_bug.cgi?id=255523
rdar://108139235

Reviewed by Mike Wyrzykowski.

The implementation assumed a single unsigned literal would be passed into the
`@workgroup_size` annotation, but it takes 3 arguments, a required `x` and
optionals `y` and `z`. They must also be (const) expressions, so we can't assume
literals will be passed in.

* Source/WebGPU/WGSL/AST/ASTStringDumper.cpp:
(WGSL::AST::StringDumper::visit):
* Source/WebGPU/WGSL/AST/ASTVisitor.cpp:
(WGSL::AST::Visitor::visit):
* Source/WebGPU/WGSL/AST/ASTWorkgroupSizeAttribute.h:
* Source/WebGPU/WGSL/Parser.cpp:
(WGSL::Parser<Lexer>::parseAttribute):

Canonical link: https://commits.webkit.org/263063@main
https://bugs.webkit.org/show_bug.cgi?id=255513
rdar://108134231

Reviewed by Mike Wyrzykowski.

Add type declarations for the 3 functions from section 17.3 (Logical Built-in Functions) of the spec[1].

[1]: https://www.w3.org/TR/WGSL/#logical-builtin-functions

* Source/WebGPU/WGSL/TypeDeclarations.rb:
* Source/WebGPU/WGSL/tests/valid/overload.wgsl:

Canonical link: https://commits.webkit.org/263064@main
https://bugs.webkit.org/show_bug.cgi?id=255206

Reviewed by Kimmo Kinnunen.

WebGL tests were randomly failing thread creation due to thread
starvation for Windows port. StreamClientConnection was leaking. Use
adoptRef to fix the leakage.

* Source/WebKit/Platform/IPC/StreamClientConnection.cpp:
(IPC::StreamClientConnection::create):

Canonical link: https://commits.webkit.org/263065@main
https://bugs.webkit.org/show_bug.cgi?id=255572

Reviewed by Alex Christensen and Chris Dumez.

So that we don't store raw pointers, we should use CheckedRef where
applicable.

* Source/WebKit/UIProcess/ProvisionalFrameProxy.cpp:
(WebKit::ProvisionalFrameProxy::ProvisionalFrameProxy):
(WebKit::ProvisionalFrameProxy::~ProvisionalFrameProxy):
(WebKit::ProvisionalFrameProxy::didReceiveMessage):
(WebKit::ProvisionalFrameProxy::messageSenderDestinationID const):
* Source/WebKit/UIProcess/ProvisionalFrameProxy.h:
* Source/WebKit/UIProcess/ProvisionalPageProxy.cpp:
(WebKit::ProvisionalPageProxy::ProvisionalPageProxy):
(WebKit::ProvisionalPageProxy::~ProvisionalPageProxy):
(WebKit::ProvisionalPageProxy::processDidTerminate):
(WebKit::ProvisionalPageProxy::initializeWebPage):
(WebKit::ProvisionalPageProxy::loadData):
(WebKit::ProvisionalPageProxy::loadRequest):
(WebKit::ProvisionalPageProxy::goToBackForwardItem):
(WebKit::ProvisionalPageProxy::didCreateMainFrame):
(WebKit::ProvisionalPageProxy::didPerformClientRedirect):
(WebKit::ProvisionalPageProxy::didStartProvisionalLoadForFrame):
(WebKit::ProvisionalPageProxy::didFailProvisionalLoadForFrame):
(WebKit::ProvisionalPageProxy::didCommitLoadForFrame):
(WebKit::ProvisionalPageProxy::didNavigateWithNavigationData):
(WebKit::ProvisionalPageProxy::didChangeProvisionalURLForFrame):
(WebKit::ProvisionalPageProxy::decidePolicyForNavigationActionAsync):
(WebKit::ProvisionalPageProxy::decidePolicyForResponse):
(WebKit::ProvisionalPageProxy::didPerformServerRedirect):
(WebKit::ProvisionalPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame):
(WebKit::ProvisionalPageProxy::startURLSchemeTask):
(WebKit::ProvisionalPageProxy::backForwardGoToItem):
(WebKit::ProvisionalPageProxy::decidePolicyForNavigationActionSync):
(WebKit::ProvisionalPageProxy::logDiagnosticMessageFromWebProcess):
(WebKit::ProvisionalPageProxy::logDiagnosticMessageWithEnhancedPrivacyFromWebProcess):
(WebKit::ProvisionalPageProxy::logDiagnosticMessageWithValueDictionaryFromWebProcess):
(WebKit::ProvisionalPageProxy::backForwardAddItem):
(WebKit::ProvisionalPageProxy::requestPasswordForQuickLookDocumentInMainFrame):
(WebKit::ProvisionalPageProxy::contentFilterDidBlockLoadForFrame):
(WebKit::ProvisionalPageProxy::didReceiveMessage):
(WebKit::ProvisionalPageProxy::didReceiveSyncMessage):
* Source/WebKit/UIProcess/ProvisionalPageProxy.h:
(WebKit::ProvisionalPageProxy::page):
(WebKit::ProvisionalPageProxy::page const):
* Source/WebKit/UIProcess/WebFrameProxy.h:
* Source/WebKit/UIProcess/WebPageProxy.h:

Canonical link: https://commits.webkit.org/263066@main
…ization

https://bugs.webkit.org/show_bug.cgi?id=255516
rdar://108135679

Reviewed by Mike Wyrzykowski.

In https://commits.webkit.org/262528@main we started using the inferred type for
call expressions' targets when serializing. That was necessary when constructing
parameterized without explicitly providing the content type, since that relies on
type inference. However, the type of CallExpression::target is a bit misleading,
since it claims to be a type, but isn't always a type. In order to solve that, we
check if target is a valid type name, otherwise we write out the string value of
the target as is.

* Source/WebGPU/WGSL/Metal/MetalFunctionWriter.cpp:
(WGSL::Metal::FunctionDefinitionWriter::visit):

Canonical link: https://commits.webkit.org/263067@main
https://bugs.webkit.org/show_bug.cgi?id=255514
rdar://108134362

Reviewed by Mike Wyrzykowski.

Add type declarations for all the functions from section 17.5 (Numeric Built-in Functions) of the spec[1].

[1]: https://www.w3.org/TR/WGSL/#numeric-builtin-functions

* Source/WebGPU/WGSL/TypeDeclarations.rb:
* Source/WebGPU/WGSL/tests/valid/overload.wgsl:

Canonical link: https://commits.webkit.org/263068@main
https://bugs.webkit.org/show_bug.cgi?id=255588

Reviewed by Ε½an DoberΕ‘ek.

GTK exposes both, but WPE only USE(LIBGBM), let's use just one.

* Source/WebCore/PlatformGTK.cmake:
* Source/WebCore/PlatformWPE.cmake:
* Source/WebCore/platform/TextureMapper.cmake:
* Source/WebCore/platform/graphics/gbm/GBMBufferSwapchain.cpp:
* Source/WebCore/platform/graphics/gbm/GBMBufferSwapchain.h:
* Source/WebCore/platform/graphics/gbm/GBMDevice.cpp:
* Source/WebCore/platform/graphics/gbm/GBMDevice.h:
* Source/WebCore/platform/graphics/gbm/GraphicsContextGLGBM.cpp:
* Source/WebCore/platform/graphics/gbm/GraphicsContextGLGBM.h:
* Source/WebCore/platform/graphics/gbm/GraphicsContextGLGBMTextureMapper.cpp:
* Source/WebCore/platform/graphics/gbm/GraphicsContextGLGBMTextureMapper.h:
* Source/WebCore/platform/graphics/gstreamer/DMABufVideoSinkGStreamer.cpp:
(webKitDMABufVideoSinkIsEnabled):
* Source/WebCore/platform/graphics/nicosia/texmap/NicosiaGCGLANGLELayer.cpp:
* Source/WebCore/platform/graphics/nicosia/texmap/NicosiaGCGLANGLELayer.h:
* Source/WebKit/GPUProcess/graphics/RemoteGraphicsContextGL.cpp:
* Source/WebKit/GPUProcess/graphics/RemoteGraphicsContextGL.h:
* Source/WebKit/GPUProcess/graphics/RemoteGraphicsContextGL.messages.in:
* Source/WebKit/GPUProcess/graphics/RemoteGraphicsContextGLGBM.cpp:
* Source/WebKit/PlatformGTK.cmake:
* Source/WebKit/WebProcess/GPU/graphics/gbm/RemoteGraphicsContextGLProxyGBM.cpp:
* Source/cmake/OptionsGTK.cmake:
* Source/cmake/OptionsWPE.cmake:
* Tools/Scripts/generate-gpup-webgl:

Canonical link: https://commits.webkit.org/263069@main
…atch the spell check attributes of the object's full range.

https://bugs.webkit.org/show_bug.cgi?id=255574
<rdar://problem/108174222>

Reviewed by Chris Fleizach.

We were caching the attributed string for an isolated object range with spell check attributes and using it for any subrange. However, the spell check attributes of the full range may not match the spell check attributes of a subrange. For instance, if the object's range text is "hello world", there is no misspellings in it. But if a subrange with offset 1 and length 9 is requested, this would contains the text "ello worl" which contains two misspelled words. For this reason, it is necessary to perform the spell check upon request of subranges.

Covered by test accessibility/content-editable-as-textarea.html.

* Source/WebCore/accessibility/AccessibilityObject.h:
* Source/WebCore/accessibility/isolatedtree/mac/AXIsolatedObjectMac.mm:
(WebCore::AXIsolatedObject::initializePlatformProperties):
(WebCore::AXIsolatedObject::cachedAttributedStringForTextMarkerRange const):
* Source/WebCore/accessibility/mac/AccessibilityObjectMac.mm:
(WebCore::attributedStringSetSpelling):
* Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperBase.h:

Canonical link: https://commits.webkit.org/263070@main
@whsieh whsieh added the merge-queue Applied to send a pull request to merge-queue label Apr 18, 2023
…te 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
@webkit-commit-queue
Copy link
Collaborator

Committed 263071@main (939e8d4): https://commits.webkit.org/263071@main

Reviewed commits have been landed. Closing PR #12777 and removing active labels.

@webkit-commit-queue webkit-commit-queue removed the merge-queue Applied to send a pull request to merge-queue label Apr 18, 2023
@webkit-commit-queue webkit-commit-queue merged commit 939e8d4 into WebKit:main Apr 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Scrolling Bugs related to main thread and off-main thread scrolling
Projects
None yet