From a0f88c89d101d3cff9866e61a21bd11c478398dc Mon Sep 17 00:00:00 2001 From: Kai Azim <68963405+MrKai77@users.noreply.github.com> Date: Thu, 23 May 2024 20:16:35 -0600 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20#314=20Improve=20key=20passthrough?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Loop/Managers/KeybindMonitor.swift | 74 +++++++++++++-------------- Loop/Managers/LoopManager.swift | 15 ++---- Loop/Managers/WindowDragManager.swift | 2 +- 3 files changed, 40 insertions(+), 51 deletions(-) diff --git a/Loop/Managers/KeybindMonitor.swift b/Loop/Managers/KeybindMonitor.swift index 9fa82ae1..86b639e5 100644 --- a/Loop/Managers/KeybindMonitor.swift +++ b/Loop/Managers/KeybindMonitor.swift @@ -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 @@ -75,7 +79,7 @@ class KeybindMonitor { self.performKeybind(event: event) } - return Unmanaged.passRetained(cgEvent) + return Unmanaged.passUnretained(cgEvent) } self.eventMonitor!.start() @@ -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 @@ -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) { diff --git a/Loop/Managers/LoopManager.swift b/Loop/Managers/LoopManager.swift index 8fd277b1..721873df 100644 --- a/Loop/Managers/LoopManager.swift +++ b/Loop/Managers/LoopManager.swift @@ -272,7 +272,7 @@ class LoopManager: ObservableObject { closeLoop() } } - return Unmanaged.passRetained(cgEvent) + return Unmanaged.passUnretained(cgEvent) } private func handleTriggerDelay() { @@ -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 } diff --git a/Loop/Managers/WindowDragManager.swift b/Loop/Managers/WindowDragManager.swift index 88e5dd3a..1fce60bc 100644 --- a/Loop/Managers/WindowDragManager.swift +++ b/Loop/Managers/WindowDragManager.swift @@ -46,7 +46,7 @@ class WindowDragManager { } } - return Unmanaged.passRetained(cgEvent) + return Unmanaged.passUnretained(cgEvent) } self.leftMouseUpMonitor = NSEventMonitor(scope: .global, eventMask: .leftMouseUp) { _ in