之前写了一个注册快捷键(写死在代码里)的 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))")
}
}
}