Skip to content

Commit 01ef22d

Browse files
BohdanBohdan
authored andcommitted
Fixed caps lock symbol ghosting
1 parent 028f8ad commit 01ef22d

File tree

3 files changed

+22
-8
lines changed

3 files changed

+22
-8
lines changed

LanguageFlag/Application/AppDelegate.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ class AppDelegate: NSObject, NSApplicationDelegate {
2121
// MARK: - Initialization
2222
override init() {
2323
self.screenManager = ScreenManager()
24-
self.notificationManager = NotificationManager()
2524
self.capsLockManager = CapsLockManager()
25+
self.notificationManager = NotificationManager(capsLockManager: capsLockManager)
2626

2727
super.init()
2828
}

LanguageFlag/Helpers/CapsLockManager.swift

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ class CapsLockManager {
77
private(set) var isCapsLockEnabled: Bool = false
88
private var globalEventMonitor: Any?
99
private var localEventMonitor: Any?
10+
private var debounceTask: DispatchWorkItem?
1011

1112
// MARK: - Init
1213
init() {
@@ -47,14 +48,24 @@ extension CapsLockManager {
4748
}
4849
}
4950

50-
/// Handles Caps Lock state changes.
51+
/// Handles Caps Lock state changes using a debounce mechanism to ignore
52+
/// fast, transient layout-switching toggles created by macOS.
5153
private func handleCapsLockStateChange(event: NSEvent) {
52-
let capsLockEnabled = event.modifierFlags.contains(.capsLock)
54+
debounceTask?.cancel()
5355

54-
if isCapsLockEnabled != capsLockEnabled {
55-
isCapsLockEnabled = capsLockEnabled
56-
notifyCapsLockStateChanged(newCapsLockEnabled: capsLockEnabled)
56+
let task = DispatchWorkItem { [weak self] in
57+
guard let self else { return }
58+
59+
let capsLockEnabled = CGEventSource.flagsState(.combinedSessionState).contains(.maskAlphaShift)
60+
61+
if isCapsLockEnabled != capsLockEnabled {
62+
isCapsLockEnabled = capsLockEnabled
63+
notifyCapsLockStateChanged(newCapsLockEnabled: capsLockEnabled)
64+
}
5765
}
66+
67+
debounceTask = task
68+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.08, execute: task)
5869
}
5970

6071
/// Notifies observers about the Caps Lock state change.

LanguageFlag/Helpers/NotificationManager.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ import Combine
44

55
class NotificationManager {
66

7+
private let capsLockManager: CapsLockManager
8+
79
// MARK: - Init
8-
init() {
10+
init(capsLockManager: CapsLockManager) {
11+
self.capsLockManager = capsLockManager
912
setupObservers()
1013
}
1114
}
@@ -27,7 +30,7 @@ extension NotificationManager {
2730
@objc
2831
private func handleInputSourceChange() {
2932
let currentLayout = TISCopyCurrentKeyboardInputSource().takeUnretainedValue()
30-
let isCapsLockOn = CGEventSource.flagsState(.combinedSessionState).contains(.maskAlphaShift)
33+
let isCapsLockOn = capsLockManager.isCapsLockEnabled
3134
let model = KeyboardLayoutNotification(keyboardLayout: currentLayout.name,
3235
isCapsLockEnabled: isCapsLockOn,
3336
iconRef: currentLayout.iconRef)

0 commit comments

Comments
 (0)