
之前写了一个注册快捷键(写死在代码里)的 mac 工具,用来调用 AppleScript,实在不熟悉 swift,所以后来写了一个 Electronjs 版本的。
但是,但是,但是 mac 升级到 10.14 后,nodejs 里调用 AppleScript 变得非常慢!会有 2~3 秒的延迟,泪目。
今天尝试了一下 swift 版本,貌似延迟小了很多,但是我不懂如何实现像 nodejs 那样加载一个配置文件,然后在代码里动态注册好所有快捷键。
google 了很久,都是些如何注册快捷键的问题。
swift 大神,看了我的代码之后,劳烦指引个方向。
// // AppDelegate.swift // hotkey-watcher // // Created by MistKafka on 2018/5/5. // Copyright 2018 MistKafka. All rights reserved. // struct Keycode { // Layout-independent Keys // eg.These key codes are always the same key on all layouts. static let returnKey : UInt16 = 0x24 static let enter : UInt16 = 0x4C static let tab : UInt16 = 0x30 static let space : UInt16 = 0x31 static let delete : UInt16 = 0x33 static let escape : UInt16 = 0x35 static let command : UInt16 = 0x37 static let shift : UInt16 = 0x38 static let capsLock : UInt16 = 0x39 static let option : UInt16 = 0x3A static let control : UInt16 = 0x3B static let rightShift : UInt16 = 0x3C static let rightOption : UInt16 = 0x3D static let rightControl : UInt16 = 0x3E static let leftArrow : UInt16 = 0x7B static let rightArrow : UInt16 = 0x7C static let downArrow : UInt16 = 0x7D static let upArrow : UInt16 = 0x7E static let volumeUp : UInt16 = 0x48 static let volumeDown : UInt16 = 0x49 static let mute : UInt16 = 0x4A static let help : UInt16 = 0x72 static let home : UInt16 = 0x73 static let pageUp : UInt16 = 0x74 static let forwardDelete : UInt16 = 0x75 static let end : UInt16 = 0x77 static let pageDown : UInt16 = 0x79 static let function : UInt16 = 0x3F static let f1 : UInt16 = 0x7A static let f2 : UInt16 = 0x78 static let f4 : UInt16 = 0x76 static let f5 : UInt16 = 0x60 static let f6 : UInt16 = 0x61 static let f7 : UInt16 = 0x62 static let f3 : UInt16 = 0x63 static let f8 : UInt16 = 0x64 static let f9 : UInt16 = 0x65 static let f10 : UInt16 = 0x6D static let f11 : UInt16 = 0x67 static let f12 : UInt16 = 0x6F static let f13 : UInt16 = 0x69 static let f14 : UInt16 = 0x6B static let f15 : UInt16 = 0x71 static let f16 : UInt16 = 0x6A static let f17 : UInt16 = 0x40 static let f18 : UInt16 = 0x4F static let f19 : UInt16 = 0x50 static let f20 : UInt16 = 0x5A // US-ANSI Keyboard Positions // eg. These key codes are for the physical key (in any keyboard layout) // at the location of the named key in the US-ANSI layout. static let a : UInt16 = 0x00 static let b : UInt16 = 0x0B static let c : UInt16 = 0x08 static let d : UInt16 = 0x02 static let e : UInt16 = 0x0E static let f : UInt16 = 0x03 static let g : UInt16 = 0x05 static let h : UInt16 = 0x04 static let i : UInt16 = 0x22 static let j : UInt16 = 0x26 static let k : UInt16 = 0x28 static let l : UInt16 = 0x25 static let m : UInt16 = 0x2E static let n : UInt16 = 0x2D static let o : UInt16 = 0x1F static let p : UInt16 = 0x23 static let q : UInt16 = 0x0C static let r : UInt16 = 0x0F static let s : UInt16 = 0x01 static let t : UInt16 = 0x11 static let u : UInt16 = 0x20 static let v : UInt16 = 0x09 static let w : UInt16 = 0x0D static let x : UInt16 = 0x07 static let y : UInt16 = 0x10 static let z : UInt16 = 0x06 static let zero : UInt16 = 0x1D static let one : UInt16 = 0x12 static let two : UInt16 = 0x13 static let three : UInt16 = 0x14 static let four : UInt16 = 0x15 static let five : UInt16 = 0x17 static let six : UInt16 = 0x16 static let seven : UInt16 = 0x1A static let eight : UInt16 = 0x1C static let nine : UInt16 = 0x19 static let equals : UInt16 = 0x18 static let minus : UInt16 = 0x1B static let semicolon : UInt16 = 0x29 static let apostrophe : UInt16 = 0x27 static let comma : UInt16 = 0x2B static let period : UInt16 = 0x2F static let forwardSlash : UInt16 = 0x2C static let backslash : UInt16 = 0x2A static let grave : UInt16 = 0x32 static let leftBracket : UInt16 = 0x21 static let rightBracket : UInt16 = 0x1E static let keypadDecimal : UInt16 = 0x41 static let keypadMultiply : UInt16 = 0x43 static let keypadPlus : UInt16 = 0x45 static let keypadClear : UInt16 = 0x47 static let keypadDivide : UInt16 = 0x4B static let keypadEnter : UInt16 = 0x4C static let keypadMinus : UInt16 = 0x4E static let keypadEquals : UInt16 = 0x51 static let keypad0 : UInt16 = 0x52 static let keypad1 : UInt16 = 0x53 static let keypad2 : UInt16 = 0x54 static let keypad3 : UInt16 = 0x55 static let keypad4 : UInt16 = 0x56 static let keypad5 : UInt16 = 0x57 static let keypad6 : UInt16 = 0x58 static let keypad7 : UInt16 = 0x59 static let keypad8 : UInt16 = 0x5B static let keypad9 : UInt16 = 0x5C } import Cocoa import Magnet @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { @IBOutlet weak var window: NSWindow! let switchToSafariScript = NSAppleScript(source: "tell application \"Safari\" to activate") let switchToTerminalScript = NSAppleScript(source: "tell application \"Terminal\" to activate") let switchToChromeScript = NSAppleScript(source: "tell application \"Google Chrome\" to activate") let switchToEmacsScript = NSAppleScript(source: "tell application \"Emacs\" to activate") let switchToEmacsGitScript = NSAppleScript(source: "tell application \"Emacs-for-Git\" to activate") let switchToPycharmScript = NSAppleScript(source: "tell application \"PyCharm\" to activate") func applicationDidFinishLaunching(_ aNotification: Notification) { guard let keyCombo1 = KeyCombo(keyCode: Int(Keycode.s), cocoaModifiers: [.shift, .control, .command, .option]) else { return } let hotKey1 = HotKey(identifier: "switch-to-safari", keyCombo: keyCombo1, target: self, action: #selector(AppDelegate.switchToSafari)) hotKey1.register() guard let keyCombo2 = KeyCombo(keyCode: Int(Keycode.t), cocoaModifiers: [.shift, .control, .command, .option]) else { return } let hotKey2 = HotKey(identifier: "switch-to-terminal", keyCombo: keyCombo2, target: self, action: #selector(AppDelegate.switchToTerminal)) hotKey2.register() guard let keyCombo3 = KeyCombo(keyCode: Int(Keycode.c), cocoaModifiers: [.shift, .control, .command, .option]) else { return } let hotKey3 = HotKey(identifier: "switch-to-chrome", keyCombo: keyCombo3, target: self, action: #selector(AppDelegate.switchToChrome)) hotKey3.register() guard let keyCombo5 = KeyCombo(keyCode: Int(Keycode.e), cocoaModifiers: [.shift, .control, .command, .option]) else { return } let hotKey5 = HotKey(identifier: "switch-to-emacs", keyCombo: keyCombo5, target: self, action: #selector(AppDelegate.switchToEmacs)) hotKey5.register() guard let keyCombo6 = KeyCombo(keyCode: Int(Keycode.g), cocoaModifiers: [.shift, .control, .command, .option]) else { return } let hotKey6 = HotKey(identifier: "switch-to-emacs-git", keyCombo: keyCombo6, target: self, action: #selector(AppDelegate.switchToEmacsGit)) hotKey6.register() guard let keyCombo7 = KeyCombo(keyCode: Int(Keycode.p), cocoaModifiers: [.shift, .control, .command, .option]) else { return } let hotKey7 = HotKey(identifier: "switch-to-pycharm", keyCombo: keyCombo7, target: self, action: #selector(AppDelegate.switchToPycharm)) hotKey7.register() } func applicationWillTerminate(_ aNotification: Notification) { // Insert code here to tear down your application } @objc func switchToSafari() { self.switchTo(script: self.switchToSafariScript!) } @objc func switchToTerminal() { self.switchTo(script: self.switchToTerminalScript!) } @objc func switchToChrome() { self.switchTo(script: self.switchToChromeScript!) } @objc func switchToEmacs() { self.switchTo(script: self.switchToEmacsScript!) } @objc func switchToEmacsGit() { self.switchTo(script: self.switchToEmacsGitScript!) } @objc func switchToPycharm() { self.switchTo(script: self.switchToPycharmScript!) } func switchTo(script: NSAppleScript) { var error: NSDictionary? if let output: NSAppleEventDescriptor = script.executeAndReturnError(&error) { print(output.stringValue ?? "success!") } else { print("error: \(String(describing: error))") } } }