Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 2b952923a66cd56a0acd48875418f742e995b4fc
https://github.com/WebKit/WebKit/commit/2b952923a66cd56a0acd48875418f742e995b4fc
Author: Ryosuke Niwa <[email protected]>
Date: 2026-05-15 (Fri, 15 May 2026)
Changed paths:
M Source/WebKit/UIProcess/mac/WebViewImpl.h
M Source/WebKit/UIProcess/mac/WebViewImpl.mm
M Tools/Scripts/webkitpy/api_tests/allowlist.txt
M Tools/TestWebKitAPI/Tests/WebKit/WKWebView/mac/WKWebViewMacEditingTests.mm
Log Message:
-----------
REGRESSION(310826@main): "Zhuyin - Traditional" input method stalls for
multiple seconds when composing a mail
https://bugs.webkit.org/show_bug.cgi?id=314888
rdar://177042301
Reviewed by Wenson Hsieh.
WebKit on macOS holds an m_interpretKeyEventHoldingTank to serialize keyboard
events while
a previous handleEventByInputMethod: call is in flight. This was added in
297270@main to ensure
DOM event ordering (keydown before compositionstart/update) for input methods
like Devanagari on
docs.google.com.
There was an unintended consequence, however. While the input method is
processing keydown N,
keydown N+1 is parked in WebKit and never reaches the IM's XPC queue. TCIM
(Traditional Chinese
- Zhuyin) appears to rely on incoming events to nudge its main thread back from
auxiliary work
(menu rebuilds, settings checks). With nothing in its incoming XPC queue,
TCIM's main thread
drifts off and gets wedged for 1–20 seconds — a system-wide input method stall
(other apps also
can't switch input sources during it). Eventually, TCIM "wakes up" with
handled=YES but sends no
commands to WebKit; WebKit then drains the held events as a burst, often
producing visible garbage.
Disabling inputMethodUsesCorrectKeyEventOrder made the hang go away, even
though the state WebKit
reports to the input method was identical in both modes. Through narrowing
experiments (bypassing
command queueing -> still hangs; bypassing concurrency control -> no hang), we
confirmed
the trigger was the holding tank's delay of subsequent keydowns reaching the
input method, not
the per-command queueing.
This PR fixes the bug by immediately sending keydown to input methods, and only
putting keyup events
in the holding tank. More precisely, it implements the following fixes:
- Replaced std::optional<Vector<KeypressCommand>> m_collectedKeypressCommands
with
Deque<Vector<KeypressCommand>> so each in-flight keydown gets its own queue
(a Vector).
The input methods serializes its handleEventByInputMethod: processing on
its main thread,
so its setMarkedText:/insertText:/doCommandBySelector: callbacks for
keydown N arrive before
it moves on to keydown N+1 — the front of the deque is always the queue for
the keydown the
input method is currently processing.
- Keydowns no longer go into the holding tank. They dispatch
handleEventByInputMethod:
immediately, so their handleEvent: lands in the input method's XPC queue
right away - TCIM's
runloop has events to look at and doesn't drift.
- Keyups still go into the tank when a keydown is in flight. Each keydown
completion releases
one keyup from the tank front via takeFirst()(). The released keyup
dispatches
handleEventByInputMethod: directly with an inline completion (bypassing the
tank-check) so
it doesn't re-tank when other keydowns are still in flight. This preserves
the keydown -> keyup
IPC ordering to the web process.
- The 297270@main DOM event ordering invariant (keydown before
compositionstart) is preserved for
every key, including concurrent ones, because each keydown's commands
replay during its own
keydown default handler in the web process.
Test:
TestWebKitAPI.WKWebViewMacEditingTests.ConcurrentInputMethodKeyDownsScopeQueueingPerKey
* Source/WebKit/UIProcess/mac/WebViewImpl.h:
* Source/WebKit/UIProcess/mac/WebViewImpl.mm:
(WebKit::WebViewImpl::collectKeyboardLayoutCommandsForEvent):
(WebKit::WebViewImpl::interpretKeyEvent):
(WebKit::WebViewImpl::doCommandBySelector):
(WebKit::WebViewImpl::insertText):
(WebKit::WebViewImpl::selectedRangeWithCompletionHandler):
(WebKit::WebViewImpl::setMarkedText):
* Tools/Scripts/webkitpy/api_tests/allowlist.txt:
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/mac/WKWebViewMacEditingTests.mm:
(-[MockTextInputContext handleEventByInputMethod:completionHandler:]):
(TestWebKitAPI::TEST(WKWebViewMacEditingTests,
ConcurrentInputMethodKeyDownsScopeQueueingPerKey)):
Canonical link: https://commits.webkit.org/313336@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications