-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathrun.swift
119 lines (104 loc) · 3.52 KB
/
run.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import AppKit
import Carbon
import Foundation
func getInputMethodList() -> [String] {
let list = TISCreateInputSourceList(nil, false).takeRetainedValue() as! [TISInputSource]
var inputMethodList = [String]()
for source in list {
if let name = TISGetInputSourceProperty(source, kTISPropertyInputSourceID) {
let sourceName = Unmanaged<CFString>.fromOpaque(name).takeUnretainedValue() as String
inputMethodList.append(sourceName)
}
}
return inputMethodList
}
func getSelectedInputMethod() -> String {
let currentSource = TISCopyCurrentKeyboardInputSource().takeRetainedValue()
let name = TISGetInputSourceProperty(currentSource, kTISPropertyInputSourceID)
let sourceName = Unmanaged<CFString>.fromOpaque(name!).takeUnretainedValue() as String
return sourceName
}
func switchInputMethod(to inputMethod: String) {
let inputSources = TISCreateInputSourceList(nil, false).takeRetainedValue() as! [TISInputSource]
for inputSource in inputSources {
if let inputSourceID = TISGetInputSourceProperty(inputSource, kTISPropertyInputSourceID) {
let inputSourceIDString =
Unmanaged<CFString>.fromOpaque(inputSourceID).takeUnretainedValue() as String
if inputSourceIDString.range(of: inputMethod, options: .caseInsensitive) != nil {
print("Switching to \(inputSourceIDString)")
TISSelectInputSource(inputSource)
return
}
}
}
print("Not found \(inputMethod), maybe not installed?")
}
// Check if config.json file exists
let fileManager = FileManager.default
let configFilePath =
"\(ProcessInfo.processInfo.environment["HOME"]!)/.quiet_input_method/.quiet.json"
var configData: Data?
if fileManager.fileExists(atPath: configFilePath) {
configData = fileManager.contents(atPath: configFilePath)
}
// Default config
var DEFAULT_CONFIG = """
{
"default": "abc",
"appConfig": {
"Shuangpin": [
"Telegram",
"WeChat"
],
"abc": [
"Code"
]
}
}
"""
// Convert json to dict
func jsonToDict(jsonData: Data) -> [String: Any] {
let dict =
try? JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers) as! [String: Any]
return dict ?? [:]
}
// Load config from file or use default config
var config = jsonToDict(jsonData: configData ?? DEFAULT_CONFIG.data(using: .utf8)!)
func getInputMethodByConfig(appName: String) -> String {
for (key, value) in config["appConfig"] as! [String: [String]] {
let appList = value
if appList.contains(appName) {
return key
}
}
// if default config exists, use it
if let defaultInputMethod = config["default"] as? String {
return defaultInputMethod
}
return "Unknown"
}
// Listen for app switch events and print the current app
let workspace = NSWorkspace.shared
var currentApp: NSRunningApplication?
workspace.notificationCenter.addObserver(
forName: NSWorkspace.didActivateApplicationNotification, object: nil, queue: nil
) { notification in
if let app = notification.userInfo?[NSWorkspace.applicationUserInfoKey] as? NSRunningApplication {
if app != currentApp {
currentApp = app
let appName = app.localizedName ?? "Unknown"
let inputMethod = getInputMethodByConfig(appName: appName)
if inputMethod == "Unknown" {
return
}
print("Current app: \(app.localizedName ?? "Unknown") to \(inputMethod)")
switchInputMethod(to: inputMethod)
}
}
}
print("Listening for app switch events...")
// list all input methods
for inputMethod in getInputMethodList() {
print(inputMethod)
}
RunLoop.main.run()