@@ -38,30 +38,74 @@ class InputSource: Equatable {
3838 if self . isCJKV {
3939 switchCJKVSource ( )
4040 } else {
41+ selectWithRetry ( )
42+ }
43+ }
44+
45+ // 添加重试机制的切换方法
46+ private func selectWithRetry( maxAttempts: Int = 2 ) {
47+ for attempt in 1 ... maxAttempts {
4148 TISSelectInputSource ( tisInputSource)
4249 usleep ( InputSourceManager . uSeconds)
50+
51+ // 验证切换是否成功
52+ if InputSourceManager . getCurrentSource ( ) . id == self . id {
53+ // 强制刷新输入上下文以确保立即生效
54+ InputSourceManager . forceRefreshInputContext ( )
55+ return
56+ }
57+
58+ // 如果不是最后一次尝试,多等待一段时间再重试
59+ if attempt < maxAttempts {
60+ usleep ( InputSourceManager . uSeconds)
61+ }
4362 }
63+
64+ // 即使失败也尝试刷新一次
65+ InputSourceManager . forceRefreshInputContext ( )
4466 }
4567
4668 private func switchCJKVSource( ) {
47- // 直接切换到目标输入法
69+ // 尝试直接切换到目标输入法
4870 TISSelectInputSource ( tisInputSource)
4971 usleep ( InputSourceManager . uSeconds)
5072
73+ // 验证切换是否成功
74+ if InputSourceManager . getCurrentSource ( ) . id == self . id {
75+ // 即使切换成功,也强制刷新输入上下文以确保立即生效
76+ InputSourceManager . forceRefreshInputContext ( )
77+ return
78+ }
79+
5180 // 如果切换失败,尝试通过非 CJKV 输入法中转
52- if InputSourceManager . getCurrentSource ( ) . id != self . id,
53- let nonCJKV = InputSourceManager . nonCJKVSource ( ) {
81+ if let nonCJKV = InputSourceManager . nonCJKVSource ( ) {
5482 TISSelectInputSource ( nonCJKV. tisInputSource)
5583 usleep ( InputSourceManager . uSeconds)
5684 TISSelectInputSource ( tisInputSource)
85+ usleep ( InputSourceManager . uSeconds)
86+
87+ // 再次验证
88+ if InputSourceManager . getCurrentSource ( ) . id == self . id {
89+ // 强制刷新输入上下文
90+ InputSourceManager . forceRefreshInputContext ( )
91+ return
92+ }
93+
94+ // 最后一次尝试:等待更长时间再切换
95+ usleep ( InputSourceManager . uSeconds * 2 )
96+ TISSelectInputSource ( tisInputSource)
97+ usleep ( InputSourceManager . uSeconds)
98+
99+ // 最后也强制刷新一次
100+ InputSourceManager . forceRefreshInputContext ( )
57101 }
58102 }
59103}
60104
61105// 修改 InputSourceManager 类
62106class InputSourceManager {
63107 static var inputSources : [ InputSource ] = [ ]
64- static var uSeconds : UInt32 = 12000
108+ static var uSeconds : UInt32 = 20000 // 增加到20ms以提高稳定性
65109 static var keyboardOnly : Bool = true
66110
67111 static func initialize( ) {
@@ -135,6 +179,30 @@ class InputSourceManager {
135179 static func getNonCJKVSource( ) -> InputSource ? {
136180 return nonCJKVSource ( )
137181 }
182+
183+ // 强制刷新输入上下文,确保输入法切换立即生效
184+ // 这个方法模拟用户切换应用的效果,强制macOS刷新当前应用的输入上下文
185+ static func forceRefreshInputContext( ) {
186+ // 方法1: 发送一个空的键盘事件来触发输入上下文刷新
187+ // 使用 flags changed 事件,这是最轻量级的事件
188+ if let event = CGEvent ( keyboardEventSource: nil , virtualKey: 0x3B , keyDown: true ) {
189+ // 0x3B 是 Control 键,我们只发送修饰键变化,不会影响用户输入
190+ event. flags = CGEventFlags ( rawValue: 0x40101 ) // Control键的标志
191+ event. post ( tap: . cghidEventTap)
192+ usleep ( 1000 ) // 1ms延迟
193+
194+ // 立即发送释放事件
195+ if let releaseEvent = CGEvent ( keyboardEventSource: nil , virtualKey: 0x3B , keyDown: false ) {
196+ releaseEvent. flags = CGEventFlags ( rawValue: 0x100 )
197+ releaseEvent. post ( tap: . cghidEventTap)
198+ }
199+ }
200+
201+ // 方法2: 更激进的方式 - 重新选择当前输入法来强制刷新
202+ let current = TISCopyCurrentKeyboardInputSource ( ) . takeRetainedValue ( )
203+ TISSelectInputSource ( current)
204+ usleep ( 5000 ) // 5ms延迟确保刷新完成
205+ }
138206}
139207
140208// 添加 TISInputSource 扩展
@@ -392,10 +460,15 @@ class KeyboardManager {
392460 // 打印当前修饰键的原始值,用于调试
393461 // print("修饰键 flags 原始值: 0x\(String(flags.rawValue, radix: 16))(\(flags.rawValue))")
394462
395- // 只有 Shift 键的 flags 值(0x20102 = 131330)
396- let isShiftKey = flags. rawValue == 0x20102
397- // Shift 键释放的 flags 值(0x100 = 256)
398- let isShiftRelease = flags. rawValue == 0x100
463+ // 检测Shift键状态的改进逻辑:支持左右Shift键
464+ // 左Shift: 0x20102, 右Shift: 0x20104
465+ let currentHasShift = flags. contains ( . maskShift)
466+ let previousHasShift = lastFlags. contains ( . maskShift)
467+
468+ // Shift键按下:当前有Shift但之前没有
469+ let isShiftKey = currentHasShift && !previousHasShift
470+ // Shift键释放:之前有Shift但当前没有
471+ let isShiftRelease = !currentHasShift && previousHasShift
399472
400473 // 检查是否有其他修饰键(当前或之前的状态)
401474 let hasOtherModifiers = flags. contains ( . maskCommand) || flags. contains ( . maskControl) ||
0 commit comments