; Functions for holding and repeating keys ; ; Private Methods ; _HoldRepeat_IsActive := Map() _HoldRepeat_Handler(IsHold, TargetKey, CancelKeys:=[], HoldKey:="") { global _HoldRepeat_IsActive global HoldRepeat_BlindMode global HoldRepeat_TimerPeriod if (_HoldRepeat_IsActive.Has(TargetKey) AND _HoldRepeat_IsActive[TargetKey]) { return } _HoldRepeat_IsActive[TargetKey] := true if (CancelKeys.Length == 0 AND !HoldKey) { if IsHold { CancelKeys:=[TargetKey] } else { HoldKey:=TargetKey } } if IsHold { Send HoldRepeat_BlindMode "{" TargetKey " down}" } else { Send HoldRepeat_BlindMode "{" TargetKey "}" } SetTimer _HoldRepeat_Loop.Bind(IsHold, TargetKey, CancelKeys, HoldKey), HoldRepeat_TimerPeriod } _HoldRepeat_Loop(IsHold, TargetKey, CancelKeys, HoldKey) { global _HoldRepeat_LoopState global _HoldRepeat_IsActive global HoldRepeat_BlindMode endLoop := false for index,key in CancelKeys { if GetKeyState(key,"P") { endLoop := true break } } if (HoldKey AND !GetKeyState(HoldKey,"P")) { endLoop := true } if endLoop { SetTimer , 0 if (IsHold AND !GetKeyState(TargetKey,"P")) { Send HoldRepeat_BlindMode "{" TargetKey " up}" } _HoldRepeat_IsActive[TargetKey] := false return } if !IsHold { Send HoldRepeat_BlindMode "{" TargetKey "}" } } ; ; Public Methods ; ; Make BlindMode a public variable so it doesn't have to be passed as an input to every function ; plus it's highly unlikely we will want different modes in different hotkeys for the same script HoldRepeat_BlindMode := "{Blind}" HoldRepeat_TimerPeriod := 100 Hold := _HoldRepeat_Handler.Bind(true) Repeat := _HoldRepeat_Handler.Bind(false) ; Sets key to hold if single tap, or repeat if double tap HoldOrRepeat(TargetKey, CancelKeys:=[]) { global HoldRepeat_BlindMode Send HoldRepeat_BlindMode "{" TargetKey " down}" if KeyWait(TargetKey, "D T0.2") { isHold := false } else { isHold := true } if (CancelKeys.Length == 0) { CancelKeys := [TargetKey] } _HoldRepeat_Handler(isHold, TargetKey, CancelKeys) }