macOS 27 Catalyst: WKWebView text entry impossible, endless keyboard input-view focus loop

Filed as FB24092251.

On macOS 27.0 beta (26A5388g), clicking into any text input inside a WKWebView in a Mac Catalyst app makes focus oscillate forever and typing does nothing. CPU pegs at 100% while the editor is focused. The same binary works fine on macOS 26.

The DOM element never actually loses focus. Only the window does:

window focus -> activeElement=TEXTAREA.inputarea
JS focus     -> activeElement=TEXTAREA.inputarea
window blur  -> activeElement=TEXTAREA.inputarea    <- window loses key status
JS blur      -> activeElement=TEXTAREA.inputarea    <- element did not
...repeats indefinitely...

Pausing during the loop shows why. Focusing the element sends WebKit into UIKit's software-keyboard machinery, on a platform that has no software keyboard:

-[UIKeyboardSceneDelegate containerWindowForViewService:]
-[UIKeyboardSceneDelegate _setKeyWindowSceneInputViews:animationStyle:]
-[UIKeyboardSceneDelegate _reloadInputViewsForResponder:force:fromBecomeFirstResponder:]
-[UIResponder(UIResponderInputViewAdditions) reloadInputViews]
-[WKContentView(WKInteraction) _continueElementDidFocus:...]
-[WKContentView(WKInteraction) _elementDidFocus:...]
WebKit::WebPageProxy::elementDidFocus(...)

Building that container steals key status from the web view. First responder ends up on the enclosing _UIHostingView, so key presses are delivered there and immediately cancelled:

pressesBegan: [...], focusedItem: monacoEditor
firstResponder at keypress: _UIHostingView<...>
pressesCancelled: [...]

The catch: -becomeFirstResponder cannot be used to recover, because it is the trigger. Calling it re-enters _elementDidFocus and re-arms the loop permanently. So there is no app-side way back — the only API that reclaims the keyboard is the one that breaks it.

Minimal repro is just a WKWebView in a UIViewRepresentable inside a SwiftUI hierarchy, with any focusable <textarea>. No Monaco needed.

Partial mitigation, if you hit this: do not echo focus/blur commands back at the web view in response to its own focus events, and treat a blur where document.hasFocus() is false but activeElement is unchanged as a window-level blur rather than an editing-ended event. That stops the runaway loop and keeps your focus state correct — but it does not restore typing.

Has anyone found a way to get first responder back to the web view without calling -becomeFirstResponder? Or a way to stop the keyboard scene delegate engaging on Catalyst in the first place?

If you can reproduce on 27 beta, please file a duplicate referencing FB24092251.

macOS 27 Catalyst: WKWebView text entry impossible, endless keyboard input-view focus loop
 
 
Q