mirror of
https://github.com/stablyai/orca.git
synced 2026-11-13 09:27:29 +00:00
61 lines
2.0 KiB
Swift
61 lines
2.0 KiB
Swift
import UIKit
|
|
|
|
@MainActor
|
|
internal enum MobileWebShellKeyboardWarmup {
|
|
enum Preparation {
|
|
case ready(after: TimeInterval)
|
|
case waitingForTextInput
|
|
case failed
|
|
}
|
|
|
|
private static var readyAt: TimeInterval?
|
|
|
|
static func prepare(in window: UIWindow) -> Preparation {
|
|
if let readyAt {
|
|
return .ready(after: max(0, readyAt - ProcessInfo.processInfo.systemUptime))
|
|
}
|
|
for scene in UIApplication.shared.connectedScenes {
|
|
guard let scene = scene as? UIWindowScene else { continue }
|
|
for sceneWindow in scene.windows {
|
|
if let responder = firstResponder(in: sceneWindow), hasActiveTextInput(responder) {
|
|
return .waitingForTextInput
|
|
}
|
|
}
|
|
}
|
|
let previousResponder = firstResponder(in: window)
|
|
let field = UITextField(frame: CGRect(x: -100, y: -100, width: 40, height: 30))
|
|
field.isAccessibilityElement = false
|
|
field.accessibilityElementsHidden = true
|
|
window.addSubview(field)
|
|
var focused = false
|
|
// iOS split-keyplane initialization crashes on first WebKit focus: developer.apple.com/forums/thread/845347.
|
|
UIView.performWithoutAnimation {
|
|
focused = field.becomeFirstResponder()
|
|
if focused {
|
|
field.resignFirstResponder()
|
|
previousResponder?.becomeFirstResponder()
|
|
}
|
|
}
|
|
field.removeFromSuperview()
|
|
guard focused else { return .failed }
|
|
readyAt = ProcessInfo.processInfo.systemUptime + 0.3
|
|
return .ready(after: 0.3)
|
|
}
|
|
|
|
private static func hasActiveTextInput(_ responder: UIView) -> Bool {
|
|
if let field = responder as? UITextField {
|
|
return field.isEditing
|
|
}
|
|
guard let input = responder as? UITextInput else { return false }
|
|
return input.selectedTextRange != nil || input.markedTextRange != nil
|
|
}
|
|
|
|
private static func firstResponder(in view: UIView) -> UIView? {
|
|
if view.isFirstResponder { return view }
|
|
for child in view.subviews {
|
|
if let responder = firstResponder(in: child) { return responder }
|
|
}
|
|
return nil
|
|
}
|
|
}
|