-
Notifications
You must be signed in to change notification settings - Fork 28
/
Hotkeys.tq
96 lines (86 loc) · 3.61 KB
/
Hotkeys.tq
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
import "Carbon/HIToolbox"
@HotkeyManager {
accessor: #eventHandlerInstalled
- init {
@hotkeyRefs = []
@hotkeyHandlers = []
@specialKeycodes = {
#leftArrow => 123, #rightArrow => 124,
#downArrow => 125, #upArrow => 126,
#home => 115, #end => 119,
#pageDown => 121, #pageUp => 116,
#delete => 117, #insert => 114,
#backspace => 51, #return => 36,
#tab => 48, #capsLock => 57
}
@modifierMasks = {
#option => 1 lshift: 11,
#command => 1 lshift: 8,
#control => 1 lshift: 12,
#shift => 1 lshift: 9
}
self installEventHandler
^self
}
- installEventHandler {
^nil if @eventHandlerRef
eventSpec = TQPointer withType: "{?=II}" count: 1
eventSpec[0] = [KEventClassKeyboard, KEventHotKeyReleased]
err = InstallEventHandler(GetApplicationEventTarget(), { nextHandler, event |
GetEventParameter(event, KEventParamDirectObject,
TypeEventHotKeyID, nil, 8, \ sizeof(EventHotKeyID) == 8
nil, hotkeyIdPtr = TQPointer withType:"{__EventHotKeyID=II}")
hotkeyId = (hotkeyIdPtr value)[1]
@hotkeyHandlers[hotkeyId-1] call
^nil
}, 1, eventSpec, nil, @eventHandlerRef = TQPointer toVoid)
^err == 0
}
- registerHotkey: key withModifiers: modifiers handler: lambda {
keycode = self characterToKeycode: key
modifierMask = 0
modifiers each: `mod| modifierMask = modifierMask bitOr: @modifierMasks[mod]`
err = RegisterEventHotKey(keycode, modifierMask,
[1414676814, @hotkeyRefs count + 1], \ 'TRAN' == 1414676814
GetEventDispatcherTarget(), 0,
hotkeyRef = TQPointer withType: "^v")
^nil if err ~= 0
@hotkeyRefs push: hotkeyRef value
@hotkeyHandlers push: lambda
^@hotkeyRefs count
}
- unregisterHotkey: key `UnregisterEventHotKey(@hotkeyRefs[key-1]) == 0`
- stringForKeycode: keyCode {
keyboard = TISCopyCurrentASCIICapableKeyboardLayoutInputSource()
layoutData = TISGetInputSourceProperty(keyboard, KTISPropertyUnicodeKeyLayoutData) addressAsObject \ Returns a CFDataRef
if layoutData == nil {
"Couldn't determine keyboard layout" print
^nil
}
err = UCKeyTranslate(CFDataGetBytePtr(layoutData),
keyCode, KUCKeyActionDisplay,
0, LMGetKbdType(),
KUCKeyTranslateNoDeadKeysBit,
keysDown = TQPointer toInt,
4, realLength = TQPointer toLong,
chars = TQPointer toChars:8)
CFRelease(keyboard)
^err == 0 ? (NSString stringWithCharacters:chars length: 1) ! nil
}
- characterToKeycode: char {
if @specialKeycodes[char] then
^@specialKeycodes[char]
else if @charcodeTranslationTable == nil {
@charcodeTranslationTable = {}
(0 to: 127) each: { code |
str = self stringForKeycode: code
@charcodeTranslationTable[str] ||= code
}
}
^@charcodeTranslationTable[char]
}
- dealloc {
@hotkeyRefs each: `key| self unregisterHotkey: key`
RemoveEventHandler(@eventHandlerRef) unless @eventHandlerRef == nil
}
}