@@ -55,7 +55,13 @@ public enum KeyboardShortcuts {
55
55
- Important: Changing this property will not migrate existing shortcuts from the previous `UserDefaults` instance.
56
56
- Note: All keyboard shortcut configurations are stored with the prefix `KeyboardShortcuts_` to avoid conflicts with other app data.
57
57
*/
58
- public static var userDefaults = UserDefaults . standard
58
+ public static var userDefaults = UserDefaults . standard {
59
+ didSet {
60
+ for observer in userDefaultsObservers {
61
+ observer. update ( suite: userDefaults)
62
+ }
63
+ }
64
+ }
59
65
60
66
/**
61
67
When `true`, event handlers will not be called for registered keyboard shortcuts.
@@ -198,6 +204,12 @@ public enum KeyboardShortcuts {
198
204
199
205
legacyKeyDownHandlers = [ : ]
200
206
legacyKeyUpHandlers = [ : ]
207
+
208
+ // invalidate and remove all elements of userDefaultsObservers
209
+ for observation in userDefaultsObservers {
210
+ observation. invalidate ( )
211
+ }
212
+ userDefaultsObservers. removeAll ( )
201
213
}
202
214
203
215
// TODO: Also add `.isEnabled(_ name: Name)`.
@@ -429,7 +441,7 @@ public enum KeyboardShortcuts {
429
441
*/
430
442
public static func onKeyDown( for name: Name , action: @escaping ( ) -> Void ) {
431
443
legacyKeyDownHandlers [ name, default: [ ] ] . append ( action)
432
- startObservingShortcut ( for: name)
444
+ startObservingShortcutIfNeeded ( for: name)
433
445
registerShortcutIfNeeded ( for: name)
434
446
}
435
447
@@ -456,7 +468,7 @@ public enum KeyboardShortcuts {
456
468
*/
457
469
public static func onKeyUp( for name: Name , action: @escaping ( ) -> Void ) {
458
470
legacyKeyUpHandlers [ name, default: [ ] ] . append ( action)
459
- startObservingShortcut ( for: name)
471
+ startObservingShortcutIfNeeded ( for: name)
460
472
registerShortcutIfNeeded ( for: name)
461
473
}
462
474
@@ -468,12 +480,28 @@ public enum KeyboardShortcuts {
468
480
469
481
/**
470
482
Start observing UserDefaults changes for a specific shortcut name.
471
- Only starts observation if the shortcut is not already being observed.
483
+
484
+ This function manages the lifecycle of observations for keyboard shortcuts in the given suite (e.g. UserDefaults):
485
+ - Checks if the shortcut is already being observed
486
+ - If already observed, restarts the observation
487
+ - If not observed, creates a new observation and adds it to the observers list
488
+
489
+ The observation handles changes to the shortcut configuration in the suite:
490
+ - When the shortcut is removed (value becomes nil), unregisters the shortcut
491
+ - When the shortcut is added or modified, registers the new shortcut
492
+
493
+ - Parameter name: The name of the shortcut to observe
472
494
*/
473
- private static func startObservingShortcut ( for name: Name ) {
495
+ private static func startObservingShortcutIfNeeded ( for name: Name ) {
474
496
let key = userDefaultsKey ( for: name)
475
497
476
- let observation = UserDefaultsObservation (
498
+ // check userDefaultsObservers to see if we are already observing this key
499
+ if let observer = userDefaultsObservers. first ( where: { $0. key == key } ) {
500
+ observer. start ( )
501
+ return
502
+ }
503
+
504
+ let observer = UserDefaultsObservation (
477
505
suite: userDefaults,
478
506
key: key
479
507
) { value in
@@ -484,9 +512,9 @@ public enum KeyboardShortcuts {
484
512
}
485
513
}
486
514
487
- observation . start ( )
515
+ observer . start ( )
488
516
489
- userDefaultsObservers. append ( observation )
517
+ userDefaultsObservers. append ( observer )
490
518
}
491
519
492
520
static func userDefaultsDidChange( name: Name ) {
0 commit comments