@@ -34,15 +34,15 @@ class KeyboardEvents {
34
34
removeHandlerIfNeeded ( )
35
35
}
36
36
37
- private static func unregisterHotKeyIfNeeded( _ controlId: String , _ shortcut: Shortcut ) {
38
- if shortcut. keyCode != . none {
37
+ static func unregisterHotKeyIfNeeded( _ controlId: String , _ shortcut: Shortcut ) {
38
+ if shortcut. keyCode != . none, eventHotKeyRefs [ controlId ] != nil {
39
39
UnregisterEventHotKey ( eventHotKeyRefs [ controlId] !)
40
40
eventHotKeyRefs [ controlId] = nil
41
41
}
42
42
}
43
43
44
44
static func registerHotKeyIfNeeded( _ controlId: String , _ shortcut: Shortcut ) {
45
- if shortcut. keyCode != . none {
45
+ if shortcut. keyCode != . none, eventHotKeyRefs [ controlId ] == nil {
46
46
let id = globalShortcutsIds [ controlId] !
47
47
let hotkeyId = EventHotKeyID ( signature: signature, id: UInt32 ( id) )
48
48
let key = shortcut. carbonKeyCode
@@ -74,7 +74,7 @@ class KeyboardEvents {
74
74
75
75
private static func addLocalMonitorForKeyDownAndKeyUp( ) {
76
76
localMonitor = NSEvent . addLocalMonitorForEvents ( matching: [ . keyDown, . keyUp] ) { ( event: NSEvent ) in
77
- let someShortcutTriggered = handleEvent ( nil , nil , event. type == . keyDown ? UInt32 ( event. keyCode) : nil , cocoaToCarbonFlags ( event. modifierFlags) , event. type == . keyDown ? event. isARepeat : false )
77
+ let someShortcutTriggered = handleEvent ( nil , nil , event. type == . keyDown ? UInt32 ( event. keyCode) : nil , cocoaToCarbonFlags ( event. modifierFlags) , event. type == . keyDown ? event. isARepeat : false , . local )
78
78
return someShortcutTriggered ? nil : event
79
79
}
80
80
}
@@ -104,7 +104,7 @@ class KeyboardEvents {
104
104
InstallEventHandler ( shortcutEventTarget, { ( _: EventHandlerCallRef ? , event: EventRef ? , _: UnsafeMutableRawPointer ? ) -> OSStatus in
105
105
var id = EventHotKeyID ( )
106
106
GetEventParameter ( event, EventParamName ( kEventParamDirectObject) , EventParamType ( typeEventHotKeyID) , nil , MemoryLayout< EventHotKeyID> . size, nil , & id)
107
- handleEvent ( id, . down, nil , nil , false )
107
+ handleEvent ( id, . down, nil , nil , false , . global )
108
108
return noErr
109
109
} , eventTypes. count, & eventTypes, nil , & hotKeyPressedEventHandler)
110
110
}
@@ -113,7 +113,7 @@ class KeyboardEvents {
113
113
InstallEventHandler ( shortcutEventTarget, { ( _: EventHandlerCallRef ? , event: EventRef ? , _: UnsafeMutableRawPointer ? ) -> OSStatus in
114
114
var id = EventHotKeyID ( )
115
115
GetEventParameter ( event, EventParamName ( kEventParamDirectObject) , EventParamType ( typeEventHotKeyID) , nil , MemoryLayout< EventHotKeyID> . size, nil , & id)
116
- handleEvent ( id, . up, nil , nil , false )
116
+ handleEvent ( id, . up, nil , nil , false , . global )
117
117
return noErr
118
118
} , eventTypes. count, & eventTypes, nil , & hotKeyReleasedEventHandler)
119
119
}
@@ -131,11 +131,58 @@ class KeyboardEvents {
131
131
}
132
132
}
133
133
134
+ fileprivate func handleShortcutModifierSide( _ modifiers: NSEvent . ModifierFlags ) {
135
+ let sideModifiers : [ ( any: NSEvent . ModifierFlags , left : NSEvent . ModifierFlags , right : NSEvent . ModifierFlags ) ] = [
136
+ ( . shift, . leftShift, . rightShift) ,
137
+ ( . control, . leftControl, . rightControl) ,
138
+ ( . option, . leftOption, . rightOption) ,
139
+ ( . command, . leftCommand, . rightCommand)
140
+ ]
141
+ for shortcutIndex in 0 ... 4 {
142
+ let shortcutModifierSide = Preferences . shortcutModifierSide [ shortcutIndex]
143
+ let shortcutIds = [
144
+ Preferences . indexToName ( " holdShortcut " , shortcutIndex) ,
145
+ Preferences . indexToName ( " nextWindowShortcut " , shortcutIndex)
146
+ ]
147
+ var register = true
148
+ if shortcutModifierSide != . any {
149
+ let shortcutModifiers = shortcutIds. reduce ( into: NSEvent . ModifierFlags ( ) ) {
150
+ guard let shortcut = ControlsTab . shortcuts [ $1] else {
151
+ return
152
+ }
153
+ $0. formUnion ( shortcut. shortcut. modifierFlags)
154
+ }
155
+ if
156
+ ( sideModifiers. contains {
157
+ shortcutModifiers. contains ( $0. any) &&
158
+ !modifiers. contains ( shortcutModifierSide == . left ? $0. left : $0. right) &&
159
+ modifiers. contains ( shortcutModifierSide == . left ? $0. right : $0. left)
160
+ } )
161
+ {
162
+ register = false
163
+ }
164
+ }
165
+ shortcutIds. forEach {
166
+ guard let shortcut = ControlsTab . shortcuts [ $0] else {
167
+ return
168
+ }
169
+ if register {
170
+ KeyboardEvents . registerHotKeyIfNeeded ( $0, shortcut. shortcut)
171
+ } else {
172
+ KeyboardEvents . unregisterHotKeyIfNeeded ( $0, shortcut. shortcut)
173
+ }
174
+ }
175
+ if !register && App . app. shortcutIndex == shortcutIndex && App . app. appIsBeingUsed {
176
+ App . app. hideUi ( )
177
+ }
178
+ }
179
+ }
180
+
134
181
@discardableResult
135
- fileprivate func handleEvent( _ id: EventHotKeyID ? , _ shortcutState: ShortcutState ? , _ keyCode: UInt32 ? , _ modifiers: UInt32 ? , _ isARepeat: Bool ) -> Bool {
182
+ fileprivate func handleEvent( _ id: EventHotKeyID ? , _ shortcutState: ShortcutState ? , _ keyCode: UInt32 ? , _ modifiers: UInt32 ? , _ isARepeat: Bool , _ shortcutScope : ShortcutScope ) -> Bool {
136
183
var someShortcutTriggered = false
137
184
for shortcut in ControlsTab . shortcuts. values {
138
- if shortcut. matches ( id, shortcutState, keyCode, modifiers, isARepeat) && shortcut. shouldTrigger ( ) {
185
+ if shortcut. matches ( id, shortcutState, keyCode, modifiers, isARepeat, shortcutScope ) && shortcut. shouldTrigger ( ) {
139
186
shortcut. executeAction ( isARepeat)
140
187
someShortcutTriggered = true
141
188
}
@@ -145,8 +192,9 @@ fileprivate func handleEvent(_ id: EventHotKeyID?, _ shortcutState: ShortcutStat
145
192
146
193
fileprivate func cgEventFlagsChangedHandler( proxy: CGEventTapProxy , type: CGEventType , cgEvent: CGEvent , userInfo: UnsafeMutableRawPointer ? ) -> Unmanaged < CGEvent > ? {
147
194
if type == . flagsChanged {
148
- let modifiers = cocoaToCarbonFlags ( NSEvent . ModifierFlags ( rawValue: UInt ( cgEvent. flags. rawValue) ) )
149
- handleEvent ( nil , nil , nil , modifiers, false )
195
+ let modifiers = NSEvent . ModifierFlags ( rawValue: UInt ( cgEvent. flags. rawValue) )
196
+ handleShortcutModifierSide ( modifiers)
197
+ handleEvent ( nil , nil , nil , cocoaToCarbonFlags ( modifiers) , false , . global)
150
198
} else if ( type == . tapDisabledByUserInput || type == . tapDisabledByTimeout) {
151
199
CGEvent . tapEnable ( tap: eventTap!, enable: true )
152
200
}
0 commit comments