Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Loop/Core/LoopManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ final class LoopManager {
windowActionCache: windowActionCache,
changeAction: { [weak self] newAction in
/// If the mouse moved, that means that the keybind trigger should no longer passthrough special events such as the emoji key.
self?.keybindTrigger.canPassthroughSpecialEvents = false
self?.keybindTrigger.canPassthroughNextSpecialEvent = false
self?.changeAction(newAction, canAdvanceCycle: false)
},
selectNextCycleItem: { [weak self] in
Expand Down
30 changes: 15 additions & 15 deletions Loop/Core/Observers/KeybindTrigger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ final class KeybindTrigger {
private let keybindCacheLifetime: ContinuousClock.Duration = .seconds(30)

// Special events only contain the globe key, as it can also be used as an emoji key.
private let specialEvents: [CGKeyCode] = [.kVK_Globe_Emoji]
var canPassthroughSpecialEvents = true // If mouse has been moved
private let specialEventKeys: [CGKeyCode] = [.kVK_Globe_Emoji]

// Will be set to `false` if the mouse has been moved by LoopManager.
var canPassthroughNextSpecialEvent = true

private var useTriggerDelay: Bool { Defaults[.triggerDelay] > 0.1 }
private var doubleClickToTrigger: Bool { Defaults[.doubleClickToTrigger] }
Expand Down Expand Up @@ -97,13 +99,14 @@ final class KeybindTrigger {
}

// Special events such as the emoji key
if specialEvents.contains(keyCode) {
return canPassthroughSpecialEvents ? .forward : .ignore
if specialEventKeys.contains(keyCode) {
let canPassthrough = canPassthroughNextSpecialEvent
canPassthroughNextSpecialEvent = true // reset
return canPassthrough ? .forward : .ignore
}

// If this is a valid event, don't passthrough
let result = performKeybind(
keyCode: keyCode,
type: event.type,
isARepeat: event.getIntegerValueField(.keyboardEventAutorepeat) == 1,
flags: filteredFlags,
Expand All @@ -129,11 +132,12 @@ final class KeybindTrigger {
}

func stop() {
pressedKeys = []
canPassthroughSpecialEvents = true

eventMonitor?.stop()
eventMonitor = nil

// Reset states
pressedKeys = []
canPassthroughNextSpecialEvent = true
}

enum PerformKeybindResult {
Expand All @@ -149,12 +153,12 @@ final class KeybindTrigger {
/// - flags: modifier flags associated with this event.
/// - isLoopOpen: whether Loop is currently open.
/// - Returns: whether this event was processed by Loop.
private func performKeybind(keyCode: CGKeyCode, type: CGEventType, isARepeat: Bool, flags: CGEventFlags, isLoopOpen: Bool) -> PerformKeybindResult {
private func performKeybind(type: CGEventType, isARepeat: Bool, flags: CGEventFlags, isLoopOpen: Bool) -> PerformKeybindResult {
let flagKeys = sideDependentTriggerKey ? flags.keyCodes : flags.keyCodes.baseModifiers
let allPressedKeys: Set<CGKeyCode> = pressedKeys.union(flagKeys)

let actionKeys: Set<CGKeyCode> = Set(allPressedKeys.subtracting(triggerKey).map(\.baseModifier))
let containsTrigger = allPressedKeys.isSuperset(of: triggerKey)
let actionKeys: Set<CGKeyCode> = Set(allPressedKeys.subtracting(triggerKey).map(\.baseModifier))
let allPressedKeysBaseModifiers: Set<CGKeyCode> = Set(allPressedKeys.map(\.baseModifier))

if isLoopOpen {
Expand All @@ -177,9 +181,7 @@ final class KeybindTrigger {
if containsTrigger {
// Try an match directly with the action keys first, then fallback to just the key code.
// This prevents failures when the user is tapping the keys in rapid succession.
let match = windowActionCache.actionsByKeybind[actionKeys] ?? windowActionCache.actionsByKeybind[[keyCode]]

if let action = match {
if let action = windowActionCache.actionsByKeybind[actionKeys] {
if !isARepeat || action.canRepeat {
openLoop(startingAction: action, overrideExistingTriggerDelayTimerAction: true)
}
Expand Down Expand Up @@ -233,8 +235,6 @@ final class KeybindTrigger {
}

private func closeLoop(forceClose: Bool) {
pressedKeys = []
canPassthroughSpecialEvents = true
triggerDelayTimer.cancel()
closeCallback(forceClose)
}
Expand Down