-
Notifications
You must be signed in to change notification settings - Fork 42
Expand file tree
/
Copy pathInputSourceManager.swift
More file actions
114 lines (96 loc) · 2.81 KB
/
InputSourceManager.swift
File metadata and controls
114 lines (96 loc) · 2.81 KB
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
import Cocoa
import Foundation
import Carbon
class InputSource: Equatable {
static func == (
lhs: InputSource,
rhs: InputSource
) -> Bool {
return lhs.id == rhs.id
}
let tisInputSource: TISInputSource
var id: String {
return tisInputSource.id
}
var isCJKV: Bool {
if let lang = tisInputSource.sourceLanguages.first {
return lang == "ko" ||
lang == "ja" ||
lang == "vi" ||
lang.hasPrefix("zh")
}
return false
}
init(tisInputSource: TISInputSource) {
self.tisInputSource = tisInputSource
}
func select() {
let currentSource = InputSourceManager.getCurrentSource()
if currentSource.id == self.id {
return
}
// fcitx and non-CJKV don't need special treat
if !self.isCJKV {
TISSelectInputSource(tisInputSource)
return
}
TISSelectInputSource(tisInputSource)
showTemporaryInputWindow(
waitTimeMs: InputSourceManager.waitTimeMs
)
}
}
class InputSourceManager {
static var inputSources: [InputSource] = []
static var waitTimeMs: Int = -1 // less than 0 means using default
static var level: Int = 1
static func initialize() {
let inputSourceList = TISCreateInputSourceList(
nil, false
).takeRetainedValue() as! [TISInputSource]
inputSources = inputSourceList
.filter {
$0.isSelectable
}
.map { InputSource(tisInputSource: $0) }
}
static func getCurrentSource() -> InputSource {
return InputSource(
tisInputSource:
TISCopyCurrentKeyboardInputSource()
.takeRetainedValue()
)
}
static func getInputSource(name: String) -> InputSource? {
return inputSources.first { $0.id == name }
}
}
extension TISInputSource {
enum Category {
static var keyboardInputSource: String {
return kTISCategoryKeyboardInputSource as String
}
}
private func getProperty(_ key: CFString) -> AnyObject? {
if let cfType = TISGetInputSourceProperty(self, key) {
return Unmanaged<AnyObject>
.fromOpaque(cfType)
.takeUnretainedValue()
}
return nil
}
var id: String {
return getProperty(kTISPropertyInputSourceID) as! String
}
var category: String {
return getProperty(kTISPropertyInputSourceCategory) as! String
}
var isSelectable: Bool {
return getProperty(
kTISPropertyInputSourceIsSelectCapable
) as! Bool
}
var sourceLanguages: [String] {
return getProperty(kTISPropertyInputSourceLanguages) as! [String]
}
}