@@ -34,15 +34,15 @@ class KeyboardEvents {
3434 removeHandlerIfNeeded ( )
3535 }
3636
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 {
3939 UnregisterEventHotKey ( eventHotKeyRefs [ controlId] !)
4040 eventHotKeyRefs [ controlId] = nil
4141 }
4242 }
4343
4444 static func registerHotKeyIfNeeded( _ controlId: String , _ shortcut: Shortcut ) {
45- if shortcut. keyCode != . none {
45+ if shortcut. keyCode != . none, eventHotKeyRefs [ controlId ] == nil {
4646 let id = globalShortcutsIds [ controlId] !
4747 let hotkeyId = EventHotKeyID ( signature: signature, id: UInt32 ( id) )
4848 let key = shortcut. carbonKeyCode
@@ -74,7 +74,7 @@ class KeyboardEvents {
7474
7575 private static func addLocalMonitorForKeyDownAndKeyUp( ) {
7676 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 )
7878 return someShortcutTriggered ? nil : event
7979 }
8080 }
@@ -104,7 +104,7 @@ class KeyboardEvents {
104104 InstallEventHandler ( shortcutEventTarget, { ( _: EventHandlerCallRef ? , event: EventRef ? , _: UnsafeMutableRawPointer ? ) -> OSStatus in
105105 var id = EventHotKeyID ( )
106106 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 )
108108 return noErr
109109 } , eventTypes. count, & eventTypes, nil , & hotKeyPressedEventHandler)
110110 }
@@ -113,7 +113,7 @@ class KeyboardEvents {
113113 InstallEventHandler ( shortcutEventTarget, { ( _: EventHandlerCallRef ? , event: EventRef ? , _: UnsafeMutableRawPointer ? ) -> OSStatus in
114114 var id = EventHotKeyID ( )
115115 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 )
117117 return noErr
118118 } , eventTypes. count, & eventTypes, nil , & hotKeyReleasedEventHandler)
119119 }
@@ -131,11 +131,58 @@ class KeyboardEvents {
131131 }
132132}
133133
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+
134181@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 {
136183 var someShortcutTriggered = false
137184 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 ( ) {
139186 shortcut. executeAction ( isARepeat)
140187 someShortcutTriggered = true
141188 }
@@ -145,8 +192,9 @@ fileprivate func handleEvent(_ id: EventHotKeyID?, _ shortcutState: ShortcutStat
145192
146193fileprivate func cgEventFlagsChangedHandler( proxy: CGEventTapProxy , type: CGEventType , cgEvent: CGEvent , userInfo: UnsafeMutableRawPointer ? ) -> Unmanaged < CGEvent > ? {
147194 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)
150198 } else if ( type == . tapDisabledByUserInput || type == . tapDisabledByTimeout) {
151199 CGEvent . tapEnable ( tap: eventTap!, enable: true )
152200 }
0 commit comments