diff --git a/App/Sources/Core/MachPort/MachPortCoordinator.swift b/App/Sources/Core/MachPort/MachPortCoordinator.swift index 863c5553..48c97198 100644 --- a/App/Sources/Core/MachPort/MachPortCoordinator.swift +++ b/App/Sources/Core/MachPort/MachPortCoordinator.swift @@ -153,9 +153,18 @@ final class MachPortCoordinator: @unchecked Sendable, ObservableObject { if handleEscapeKeyDownEvent(machPortEvent) { return } case .keyUp: if let workflow = previousExactMatch, workflow.machPortConditions.shouldRunOnKeyUp { - machPortEvent.result = nil - Task.detached { [workflowRunner] in - await workflowRunner.run(workflow, machPortEvent: machPortEvent, repeatingEvent: false) + if let previousKeyDownMachPortEvent = PeekApplicationPlugin.peekEvent { + let pressDurtion = timeElapsedInSeconds( + start: previousKeyDownMachPortEvent.event.timestamp, + end: machPortEvent.event.timestamp + ) + if pressDurtion < 0.75 { + Task.detached { [workflowRunner] in + await workflowRunner.run(workflow, machPortEvent: machPortEvent, repeatingEvent: false) + } + } + PeekApplicationPlugin.peekEvent = nil + return } } else if case .captureKeyDown(let keyCode) = scheduledAction, keyCode == machPortKeyCode { scheduledAction = nil @@ -254,6 +263,13 @@ final class MachPortCoordinator: @unchecked Sendable, ObservableObject { notifications.notifyBundles(partialMatch) } + func timeElapsedInSeconds(start: CGEventTimestamp, end: CGEventTimestamp) -> Double { + var timebaseInfo = mach_timebase_info_data_t() + mach_timebase_info(&timebaseInfo) + let elapsedTicks = end - start + return Double(elapsedTicks) / 1_000_000_000 + } + @MainActor private func handleExtactMatch(_ workflow: Workflow, machPortEvent: MachPortEvent, isRepeatingEvent: Bool) { if workflow.machPortConditions.isPassthrough == true { diff --git a/App/Sources/Core/Runners/Applications/ApplicationCommandRunner.swift b/App/Sources/Core/Runners/Applications/ApplicationCommandRunner.swift index 04c733d5..25b97e21 100644 --- a/App/Sources/Core/Runners/Applications/ApplicationCommandRunner.swift +++ b/App/Sources/Core/Runners/Applications/ApplicationCommandRunner.swift @@ -61,6 +61,8 @@ final class ApplicationCommandRunner: @unchecked Sendable { case .peek: guard let machPortEvent else { return } + await PeekApplicationPlugin.set(machPortEvent) + if machPortEvent.type == .keyDown { try await openApplication(command, checkCancellation: checkCancellation) } else if machPortEvent.type == .keyUp { diff --git a/App/Sources/Core/Runners/Applications/Plugins/PeekApplicationPlugin.swift b/App/Sources/Core/Runners/Applications/Plugins/PeekApplicationPlugin.swift new file mode 100644 index 00000000..33e86e14 --- /dev/null +++ b/App/Sources/Core/Runners/Applications/Plugins/PeekApplicationPlugin.swift @@ -0,0 +1,10 @@ +import Foundation +import MachPort + +final class PeekApplicationPlugin: @unchecked Sendable { + @MainActor static var peekEvent: MachPortEvent? + + @MainActor static func set(_ peekEvent: MachPortEvent) { + Self.peekEvent = peekEvent + } +}