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.