Активировать нативный черновик до записи

This commit is contained in:
2026-07-29 15:26:31 +06:00
parent 6bc0f7c311
commit af2525b335
2 changed files with 44 additions and 4 deletions
@@ -42,7 +42,9 @@ final class NativeCompositionBridge: NSObject {
name: Message.ready,
object: nil
)
registerInstalledInputMethod()
if inputSource(withID: Self.inputSourceID) == nil {
registerInstalledInputMethod()
}
launchInputMethod()
ping()
}
@@ -50,7 +52,6 @@ final class NativeCompositionBridge: NSObject {
func activateForDictation() -> Bool {
restoreWorkItem?.cancel()
restoreWorkItem = nil
registerInstalledInputMethod()
launchInputMethod()
guard let source = inputSource(withID: Self.inputSourceID) else { return false }
@@ -58,11 +59,11 @@ final class NativeCompositionBridge: NSObject {
if currentID != Self.inputSourceID {
previousInputSourceID = currentID
}
guard TISEnableInputSource(source) == noErr,
TISSelectInputSource(source) == noErr else {
guard TISSelectInputSource(source) == noErr else {
restoreInputSource()
return false
}
wakeInputMethod()
ping()
return true
}
@@ -146,6 +147,29 @@ final class NativeCompositionBridge: NSObject {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: work)
}
private func wakeInputMethod() {
guard let source = CGEventSource(stateID: .hidSystemState) else { return }
let flags: CGEventFlags = [
.maskCommand,
.maskAlternate,
.maskControl,
.maskShift,
]
guard let keyDown = CGEvent(
keyboardEventSource: source,
virtualKey: CGKeyCode(kVK_F20),
keyDown: true
), let keyUp = CGEvent(
keyboardEventSource: source,
virtualKey: CGKeyCode(kVK_F20),
keyDown: false
) else { return }
keyDown.flags = flags
keyUp.flags = flags
keyDown.post(tap: .cghidEventTap)
keyUp.post(tap: .cghidEventTap)
}
private func inputSource(withID identifier: String) -> TISInputSource? {
guard let sources = TISCreateInputSourceList(nil, true)?.takeRetainedValue()
as? [TISInputSource] else {
+16
View File
@@ -87,6 +87,12 @@ private final class CompositionCoordinator: @unchecked Sendable {
@objc(WhisperKeyInputController)
final class WhisperKeyInputController: IMKInputController {
private var draft = ""
private static let wakeModifiers: NSEvent.ModifierFlags = [
.command,
.option,
.control,
.shift,
]
override init!(server: IMKServer!, delegate: Any!, client inputClient: Any!) {
super.init(server: server, delegate: delegate, client: inputClient)
@@ -118,6 +124,16 @@ final class WhisperKeyInputController: IMKInputController {
super.inputControllerWillClose()
}
override func handle(_ event: NSEvent!, client sender: Any!) -> Bool {
let isWakeEvent = event.type == .keyDown
&& event.keyCode == UInt16(kVK_F20)
&& event.modifierFlags.contains(Self.wakeModifiers)
if isWakeEvent {
inputLog.notice("wake event consumed")
}
return isWakeEvent
}
func setDraft(_ text: String) {
inputLog.notice(
"setting marked text for \(self.client().bundleIdentifier(), privacy: .public)"