-
-
Notifications
You must be signed in to change notification settings - Fork 569
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Migrate hotkey to sindresorhus/KeyboardShortcuts
Replaces the global hotkey library from combination of KeyHolder, Magnet and Sauce to KeyboardShortcuts. The package has few benefits: 1. More native-like UI. 2. Better non-US keyboard support (fixes #108). 3. Built-in storage via UserDefaults. The package has few limitations: 1. Storage key and type is hardcoded. This requires us to migrate from old "hotKey" string preference to "KeyboardShortcuts_popup" JSON preference. 2. There is no way to initialize KeyboardShortcuts.Key with character string. This is needed for migration. To workaround the limitation, Sauce package is left and is used to construct the key from string, retrieve key code from it and construct KeyboardShortcuts.Key with it. 3. There is no support for default shortcuts. This is addressed in sindresorhus/KeyboardShortcuts#13, which is why forked branch is used. 4. Recorder view cannot be previewed in Interface Builder: sindresorhus/KeyboardShortcuts#14. 5. It's impossible to register the same shortcut twice: sindresorhus/KeyboardShortcuts#15. The package is great even with all these limitations. The most important piece is of course better non-US keyboard support. DVORAK is supported as well.
- Loading branch information
Showing
65 changed files
with
3,142 additions
and
2,915 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,69 +1,20 @@ | ||
import Magnet | ||
import Sauce | ||
import KeyboardShortcuts | ||
|
||
class GlobalHotKey { | ||
typealias Handler = () -> Void | ||
|
||
static public var key: Key? | ||
static public var modifierFlags: NSEvent.ModifierFlags? | ||
static public var key: KeyboardShortcuts.Key? { KeyboardShortcuts.Shortcut(name: .popup)?.key } | ||
static public var modifierFlags: NSEvent.ModifierFlags? { KeyboardShortcuts.Shortcut(name: .popup)?.modifiers } | ||
|
||
private var hotKey: HotKey! | ||
private var handler: Handler | ||
private var hotKeyPrefObserver: NSKeyValueObservation? | ||
|
||
init(_ handler: @escaping Handler) { | ||
UserDefaults.standard.register(defaults: [UserDefaults.Keys.hotKey: UserDefaults.Values.hotKey]) | ||
|
||
self.handler = handler | ||
hotKeyPrefObserver = UserDefaults.standard.observe(\.hotKey, options: [.initial, .new], changeHandler: { _, _ in | ||
// Ensure old shortcut stops working. | ||
self.hotKey?.unregister() | ||
|
||
if let (key, modifiers) = self.parseHotKey() { | ||
if let keyCombo = KeyCombo(key: key, cocoaModifiers: modifiers) { | ||
self.hotKey = HotKey(identifier: UserDefaults.standard.hotKey, keyCombo: keyCombo) { hotKey in | ||
hotKey.unregister() | ||
self.handler() | ||
hotKey.register() | ||
} | ||
self.hotKey.register() | ||
} | ||
} | ||
}) | ||
} | ||
|
||
deinit { | ||
hotKeyPrefObserver?.invalidate() | ||
} | ||
|
||
private func parseHotKey() -> (Key, NSEvent.ModifierFlags)? { | ||
var keysList = UserDefaults.standard.hotKey.split(separator: "+") | ||
|
||
guard let keyString = keysList.popLast() else { | ||
return nil | ||
KeyboardShortcuts.onKeyDown(for: .popup) { | ||
KeyboardShortcuts.disable(.popup) | ||
handler() | ||
KeyboardShortcuts.enable(.popup) | ||
} | ||
guard let key = Key(character: String(keyString), virtualKeyCode: nil) else { | ||
return nil | ||
} | ||
|
||
var modifiers: NSEvent.ModifierFlags = [] | ||
for keyString in keysList { | ||
switch keyString { | ||
case "command": | ||
modifiers.insert(.command) | ||
case "control": | ||
modifiers.insert(.control) | ||
case "option": | ||
modifiers.insert(.option) | ||
case "shift": | ||
modifiers.insert(.shift) | ||
default: () | ||
} | ||
} | ||
|
||
GlobalHotKey.key = key | ||
GlobalHotKey.modifierFlags = modifiers | ||
|
||
return (key, modifiers) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import KeyboardShortcuts | ||
|
||
extension KeyboardShortcuts.Name { | ||
static let popup = Name("popup", default: Shortcut(.c, modifiers: [.command, .shift])) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.