Skip to content

Commit

Permalink
#314 Improve key passthrough
Browse files Browse the repository at this point in the history
  • Loading branch information
MrKai77 committed May 24, 2024
1 parent 6e8ad0b commit a0f88c8
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 51 deletions.
74 changes: 36 additions & 38 deletions Loop/Managers/KeybindMonitor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,37 +31,41 @@ class KeybindMonitor {
}

self.eventMonitor = CGEventMonitor(eventMask: [.keyDown, .keyUp]) { cgEvent in
if cgEvent.type == .keyDown || cgEvent.type == .keyUp,
let event = NSEvent(cgEvent: cgEvent) {
if event.type == .keyUp {
KeybindMonitor.shared.pressedKeys.remove(event.keyCode.baseKey)
} else if event.type == .keyDown {
KeybindMonitor.shared.pressedKeys.insert(event.keyCode.baseKey)
}
guard
cgEvent.type == .keyDown || cgEvent.type == .keyUp,
let event = NSEvent(cgEvent: cgEvent)
else {
return Unmanaged.passUnretained(cgEvent)
}

// Special events such as the emoji key
if self.specialEvents.contains(event.keyCode.baseKey) {
if self.canPassthroughSpecialEvents {
return Unmanaged.passRetained(cgEvent)
}
return nil
}
if event.type == .keyUp {
KeybindMonitor.shared.pressedKeys.remove(event.keyCode.baseKey)
} else if event.type == .keyDown {
KeybindMonitor.shared.pressedKeys.insert(event.keyCode.baseKey)
}

// If this is a valid event, don't passthrough
if self.performKeybind(event: event) {
return nil
// Special events such as the emoji key
if self.specialEvents.contains(event.keyCode.baseKey) {
if self.canPassthroughSpecialEvents {
return Unmanaged.passUnretained(cgEvent)
}
return nil
}

// If this wasn't, check if it was a system keybind (ex. screenshot), and
// in that case, passthrough and foce-close Loop
if CGKeyCode.systemKeybinds.contains(self.pressedKeys) {
Notification.Name.forceCloseLoop.post()
print("Detected system keybind, closing!")
return Unmanaged.passRetained(cgEvent)
}
// If this is a valid event, don't passthrough
if self.performKeybind(event: event) {
return nil
}

return Unmanaged.passRetained(cgEvent)
// If this wasn't, check if it was a system keybind (ex. screenshot), and
// in that case, passthrough and foce-close Loop
if CGKeyCode.systemKeybinds.contains(self.pressedKeys) {
Notification.Name.forceCloseLoop.post()
print("Detected system keybind, closing!")
return Unmanaged.passUnretained(cgEvent)
}

return Unmanaged.passUnretained(cgEvent)
}

self.flagsEventMonitor = CGEventMonitor(eventMask: .flagsChanged) { cgEvent in
Expand All @@ -75,7 +79,7 @@ class KeybindMonitor {

self.performKeybind(event: event)
}
return Unmanaged.passRetained(cgEvent)
return Unmanaged.passUnretained(cgEvent)
}

self.eventMonitor!.start()
Expand All @@ -86,11 +90,6 @@ class KeybindMonitor {
self.resetPressedKeys()
self.canPassthroughSpecialEvents = true

guard self.eventMonitor != nil &&
self.flagsEventMonitor != nil else {
return
}

self.eventMonitor?.stop()
self.eventMonitor = nil

Expand All @@ -100,17 +99,16 @@ class KeybindMonitor {

@discardableResult
private func performKeybind(event: NSEvent) -> Bool {
// If the current key up event is within 100 ms of the last key up event, return.
// This is used when the user is pressing 2+ keys so that it doesn't switch back
// to the one key direction when they're letting go of the keys.
if event.type == .keyUp ||
(event.type == .flagsChanged &&
!event.modifierFlags.intersection(.deviceIndependentFlagsMask).contains(.shift)) {
if (abs(lastKeyReleaseTime.timeIntervalSinceNow)) > 0.1 {
if event.type == .keyUp {
// If the current key up event is within 100 ms of the last key up event, return.
// This is used when the user is pressing 2+ keys so that it doesn't switch back
// to the one key direction when they're letting go of the keys.
if abs(lastKeyReleaseTime.timeIntervalSinceNow) < 0.1 {
print("performKeybind: returning true due to key release")
return true
}
lastKeyReleaseTime = Date.now
return false
}

if pressedKeys.contains(.kVK_Escape) {
Expand Down
15 changes: 3 additions & 12 deletions Loop/Managers/LoopManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ class LoopManager: ObservableObject {
closeLoop()
}
}
return Unmanaged.passRetained(cgEvent)
return Unmanaged.passUnretained(cgEvent)
}

private func handleTriggerDelay() {
Expand Down Expand Up @@ -304,18 +304,9 @@ class LoopManager: ObservableObject {

let triggerKey = Defaults[.triggerKey]
let wasKeyDown = (event.type == .keyDown || currentlyPressedModifiers.count > previousModifiers.count)
let keybindIsValid = (
Defaults[.triggerKey].contains(event.keyCode) ||
Defaults[.keybinds].contains {
$0.keybind.contains(event.keyCode)
}
)

if wasKeyDown, keybindIsValid, triggerKey.isSubset(of: currentlyPressedModifiers) {
guard
!isLoopActive,
currentlyPressedModifiers.count <= triggerKey.count
else {
if wasKeyDown, triggerKey.isSubset(of: currentlyPressedModifiers) {
guard !isLoopActive else {
return
}

Expand Down
2 changes: 1 addition & 1 deletion Loop/Managers/WindowDragManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class WindowDragManager {
}
}

return Unmanaged.passRetained(cgEvent)
return Unmanaged.passUnretained(cgEvent)
}

self.leftMouseUpMonitor = NSEventMonitor(scope: .global, eventMask: .leftMouseUp) { _ in
Expand Down

0 comments on commit a0f88c8

Please sign in to comment.