From 4cfe16a708ecf3c890b731d21acefab29cd76fb3 Mon Sep 17 00:00:00 2001 From: lwouis Date: Sun, 10 Nov 2024 18:33:12 +0100 Subject: [PATCH] fix: potential issues with key repeats due to concurrency --- src/logic/KeyRepeatTimer.swift | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/logic/KeyRepeatTimer.swift b/src/logic/KeyRepeatTimer.swift index 868a124e..1ce83825 100644 --- a/src/logic/KeyRepeatTimer.swift +++ b/src/logic/KeyRepeatTimer.swift @@ -27,19 +27,24 @@ class KeyRepeatTimer { if ((timer == nil || !timer!.isValid) && atShortcut.state != .up) { let repeatRate = ticksToSeconds(defaults.string(forKey: "KeyRepeat") ?? "6") let initialDelay = ticksToSeconds(defaults.string(forKey: "InitialKeyRepeat") ?? "25") - timer = Timer(fire: Date(timeIntervalSinceNow: initialDelay), interval: repeatRate, repeats: true, block: { _ in - if atShortcut.state == .up { - timer?.invalidate() - } else { - DispatchQueue.main.async { - block() - } - } - }) + timer = Timer(fire: Date(timeIntervalSinceNow: initialDelay), interval: repeatRate, repeats: true) { _ in + handleEvent(atShortcut, block) + } + timer!.tolerance = repeatRate * 0.1 CFRunLoopAddTimer(BackgroundWork.repeatingKeyThread.runLoop, timer!, .defaultMode) } } + private static func handleEvent(_ atShortcut: ATShortcut, _ block: @escaping () -> Void) { + DispatchQueue.main.async { + if atShortcut.state == .up { + timer?.invalidate() + } else { + block() + } + } + } + private static func ticksToSeconds(_ appleNumber: String) -> Double { return Double(appleNumber)! / 60 // Apple probably hard-coupled key repeat-rate with 60hz monitors }