Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: c963a9e4decec5946b7b9587c49c042100aa2635
https://github.com/WebKit/WebKit/commit/c963a9e4decec5946b7b9587c49c042100aa2635
Author: Chris Dumez <[email protected]>
Date: 2026-09-19 (Sat, 19 Sep 2026)
Changed paths:
M Source/WebCore/bindings/js/ScriptController.cpp
M Source/WebCore/page/LocalDOMWindow.h
M Tools/TestWebKitAPI/Tests/WebKit/WKWebView/AsyncFunction.mm
Log Message:
-----------
Regression(316338@main) “Copy to clipboard” button on some sites sometimes
does not copy the first time
https://bugs.webkit.org/show_bug.cgi?id=324512
rdar://186521201
Reviewed by Ryosuke Niwa and Abrar Rahman Protyasha.
Script evaluated on behalf of the client (e.g. WKWebView's evaluateJavaScript:)
runs as if it were
triggered by a user gesture. Since 265168@main the transient activation this
grants is taken back
when the gesture ends by calling LocalDOMWindow::consumeTransientActivation(),
which sets the last
activation timestamp of every window in the frame tree to -infinity. That does
not merely undo the
forced activation, it also discards transient activation the user had genuinely
given the page.
Safari evaluates JavaScript in the page a few milliseconds after a click, so a
page calling an API
gated on transient activation from its click handler can find that activation
already gone. This
went unnoticed until 316338@main made the async clipboard API require transient
activation instead
of UserGestureIndicator::processingUserGesture(), which is neither consumable
nor scoped to a
window: writes from a click handler now intermittently reject with
NotAllowedError, leaving the
previous pasteboard contents in place. Nothing about this is clipboard
specific; any API gated on
transient activation was affected.
Remember the activation each window had before the forced gesture grants its
own, and take back only
what was granted. If a window's activation has changed since, because of a real
user gesture or
because the script consumed it, that takes precedence. Ancestor frames in other
processes can only
be told to consume their activation, so those keep the previous behavior for
now.
Test: AsyncFunction.TransientActivationFromUserGestureIsPreserved
* Source/WebCore/bindings/js/ScriptController.cpp:
(WebCore::ForcedUserGestureScope::ForcedUserGestureScope):
(WebCore::ForcedUserGestureScope::previousActivations):
(WebCore::ScriptController::executeScriptInWorld):
* Source/WebCore/page/LocalDOMWindow.h:
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/AsyncFunction.mm:
(TestWebKitAPI::hasTransientActivation):
(TestWebKitAPI::simulateUserGesture):
(TestWebKitAPI::TEST(AsyncFunction,
TransientActivationFromUserGestureIsPreserved)):
Canonical link: https://commits.webkit.org/321448@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications