@@ -143,21 +143,30 @@ func getMappedModifierUsage(_ usage: UInt32, _ device: IOHIDDevice) -> UInt32 {
143143 return usage
144144}
145145
146- // MARK: - Etc
146+ // MARK: - 물리 키보드 Caps Lock 상태
147147
148- /**
149- 연결된 모든 HID 키보드에 대해 Caps Lock 상태와 LED 조정
150- @see https://github.com/busyloop/maclight
151- */
152- private var block = DispatchWorkItem { }
148+ private var state : Bool = false
149+ private var block1 = DispatchWorkItem { }
150+ private var block2 = DispatchWorkItem { }
153151func setKeyboardCapsLock( enabled: Bool ) {
154- debug ( " \( enabled) " )
152+ debug ( " enabled: \( enabled) (state: \( state ) ) " )
155153
156- block. cancel ( )
157- block = DispatchWorkItem {
158- let hid = IOHIDManagerCreate ( kCFAllocatorDefault, 0 )
154+ /** HIS_XPC: Caps Lock 상태는 늘 false */
155+ block1. cancel ( )
156+ block1 = DispatchWorkItem {
157+ debug ( " HIS_XPC_SetCapsLockModifierState " )
158+ HIS_XPC_SetCapsLockModifierState ( false )
159+ }
159160
160- /** HID 키보드 찾기 */
161+ /** HIS_XPC: Sonoma 이후 커서 밑에 생기는 "버블"/HUD/Indicator/Accessory 방지 */
162+ for delay in stride ( from: 0 , to: 200 , by: 20 ) {
163+ DispatchQueue . main. asyncAfter ( deadline: . now( ) + . milliseconds( delay) , execute: block1)
164+ }
165+
166+ block2. cancel ( )
167+ block2 = DispatchWorkItem {
168+ /** HID: 키보드 찾기 */
169+ let hid = IOHIDManagerCreate ( kCFAllocatorDefault, 0 )
161170 IOHIDManagerSetDeviceMatching ( hid, [
162171 kIOHIDDeviceUsagePageKey: kHIDPage_GenericDesktop, // Generic Desktop Page (0x01)
163172 kIOHIDDeviceUsageKey: kHIDUsage_GD_Keyboard // Keyboard (0x06, Collection Application)
@@ -174,7 +183,7 @@ func setKeyboardCapsLock(enabled: Bool) {
174183 }
175184
176185 for dev in devs {
177- /** Caps Lock 상태 */
186+ /** HID: Caps Lock 상태는 늘 false */
178187 let serv = IOHIDDeviceGetService ( dev)
179188 var conn = io_connect_t ( )
180189
@@ -184,14 +193,14 @@ func setKeyboardCapsLock(enabled: Bool) {
184193 }
185194 defer { IOServiceClose ( conn) }
186195
187- guard IOHIDSetModifierLockState ( conn, Int32 ( kIOHIDCapsLockState) , enabled ) == KERN_SUCCESS else {
196+ guard IOHIDSetModifierLockState ( conn, Int32 ( kIOHIDCapsLockState) , false ) == KERN_SUCCESS else {
188197 warning ( " IOHIDSetModifierLockState 실패: \( conn) " )
189198 continue
190199 }
191200
192201 debug ( " IOHIDSetModifierLockState 성공: \( dev) " )
193202
194- /** Caps Lock LED */
203+ /** HID: Caps Lock LED */
195204 guard let elems = IOHIDDeviceCopyMatchingElements ( dev, [
196205 kIOHIDElementUsagePageKey: kHIDPage_LEDs, // LED Page (0x08)
197206 kIOHIDElementUsageKey: kHIDUsage_LED_CapsLock // Caps Lock (0x02)
@@ -212,30 +221,13 @@ func setKeyboardCapsLock(enabled: Bool) {
212221 debug ( " IOHIDDeviceSetValue 성공: \( dev) " )
213222 }
214223 }
224+ DispatchQueue . main. asyncAfter ( deadline: . now( ) + . milliseconds( 100 ) , execute: block2)
215225
216- DispatchQueue . main. asyncAfter ( deadline: . now( ) + . milliseconds( 200 ) , execute: block)
217- DispatchQueue . main. asyncAfter ( deadline: . now( ) + . milliseconds( 300 ) , execute: block)
226+ state = enabled
218227}
219228
220229func getKeyboardCapsLock( ) -> Bool {
221- debug ( )
222-
223- var conn = io_connect_t ( )
224- let serv = IOServiceGetMatchingService ( kIOMainPortDefault, IOServiceMatching ( kIOHIDSystemClass) )
225-
226- guard IOServiceOpen ( serv, mach_task_self_, UInt32 ( kIOHIDParamConnectType) , & conn) == KERN_SUCCESS else {
227- warning ( " IOServiceOpen 실패: \( serv) " )
228- return false
229- }
230- defer { IOServiceClose ( conn) }
231-
232- var enabled = false
233- guard IOHIDGetModifierLockState ( conn, Int32 ( kIOHIDCapsLockState) , & enabled) == KERN_SUCCESS else {
234- warning ( " IOHIDGetModifierLockState 실패: \( conn) " )
235- return false
236- }
237-
238- debug ( " IOHIDGetModifierLockState 성공: \( conn) \( enabled) " )
230+ debug ( " state: \( state) " )
239231
240- return enabled
232+ return state
241233}
0 commit comments