How do I prevent accidental [Caps Lock] hits, by enforcing a mandatory hold delay of a second or more?
This can indeed be done with an AHK timer-script. This script will register when Caps Lock is pressed and intercept Capslock Up, allowing it to fire only if a certain number of milliseconds has passed. The default timeout is 0.2 sec, this can be configured in the system tray.
; AutoHotKey - Suppress CapsLock
; This is a modified version of a scrpt by Lexikos, taken from:
; http://www.autohotkey.com/board/topic/82509-software-fix-for-double-clicking-mouse/
RegRead minDelay, HKCU, Software\LongCapsLock, MinDelay
if ErrorLevel
minDelay := 200 ; Default setting.
#NoTrayIcon ; Hide initial icon.
Menu Tray, Icon, %A_WinDir%\System32\main.cpl ; Set icon.
Menu Tray, Icon ; Show icon.
Menu Tray, NoStandard
Menu Tray, Add, &Configure, TrayConfigure
Menu Tray, Add, E&xit, TrayExit
Menu Tray, Default, &Configure
Menu Tray, Click, 1 ; Single-click to configure.
Menu Tray, Tip, Long CapsLock
global _starttime
global timing := 0
CapsLock::
if (timing = 0) {
timing := 1
_startTime := A_TickCount
}
return
CapsLock Up::
if (timing = 1) {
_timeDiff := A_TickCount - _startTime
;MsgBox diff: %_timeDiff%
if (_timeDiff > minDelay) {
Send {CapsLock down}
}
timing := 0
}
return
TrayConfigure:
prompt := "Enter minimum duration needed to hold Caps Lock`n"
. "before it is toggled. The unit is milliseconds."
Loop {
InputBox newMinDelay, Long CapsLock, %prompt%,,,,,,,, %minDelay%
if ErrorLevel ; Cancelled?
return
if (newMinDelay+0 >= 150 && newMinDelay <= 10000) ; Valid?
break
if (A_Index = 1)
prompt .= "`n`nPlease enter a number between 150 and 10000."
}
minDelay := newMinDelay
if (minDelay = 200)
RegDelete HKCU, Software\LongCapsLock
else
RegWrite REG_DWORD, HKCU, Software\LongCapsLock, MinDelay, %minDelay%
return
TrayExit:
ExitApp
I've got two AHK scripts here. If you want me to explain further than what I've commented in the scripts, please add a comment below.
The first one is more complex and probably prone to failure, but it sends CapsLock as a literal keypress after holding for one second.
The second one toggles the state of "Caps Lock", which may not be desirable if the reason you want the delay is for some other program's CapsLock hotkey.
You can configure the delay by changing the Delay
variable in the second line.
Sends a literal "CapsLock" keypress
; Time to wait in milliseconds
Delay = 1000
; Variable used to ignore key repeats
; (Windows sends them when a key is held down)...
CapsLockHeld = 0
; This starts the timer on key *down*.
; Time is measured in milliseconds.
; Timer resolution should be approximately 20 ms.
; The negative time means run only once.
; It will reset the timer if it is already running.
CapsLock::CapsLockDown()
; This stops the timer on key *up*.
CapsLock Up::CapsLockUp()
; This sends a CapsLock keypress when the timer runs out.
SendCapsLock:
SetTimer, SendCapsLock, Off
HotKey, CapsLock, Off
HotKey, CapsLock Up, Off
SendInput, {CapsLock}
HotKey, CapsLock Up, On
HotKey, CapsLock, On
Return
; Using functions because otherwise global variables die
CapsLockDown() {
global CapsLockHeld
global Delay
If (CapsLockHeld == 1) {
Return
}
CapsLockHeld = 1
SetTimer, SendCapsLock, %Delay%
Return
}
CapsLockUp() {
global CapsLockHeld
CapsLockHeld = 0
SetTimer, SendCapsLock, Off
Return
}
Toggles "Caps Lock" state:
; Time to wait in milliseconds
Delay = 1000
; Variable used to ignore key repeats
; (Windows sends them when a key is held down)...
CapsLockHeld = 0
; This starts the timer on key *down*.
; Time is measured in milliseconds.
; Timer resolution should be approximately 20 ms.
; The negative time means run only once.
; It will reset the timer if it is already running.
CapsLock::CapsLockDown()
; This stops the timer on key *up*.
CapsLock Up::CapsLockUp()
; This sends a CapsLock keypress when the timer runs out.
SendCapsLock:
SetTimer, SendCapsLock, Off
If (GetKeyState("CapsLock", "T"))
SetCapsLockState, Off
Else
SetCapsLockState, On
Return
; Using functions because otherwise global variables die
CapsLockDown() {
global CapsLockHeld
global Delay
If (CapsLockHeld == 1) {
Return
}
CapsLockHeld = 1
SetTimer, SendCapsLock, %Delay%
Return
}
CapsLockUp() {
global CapsLockHeld
CapsLockHeld = 0
SetTimer, SendCapsLock, Off
Return
}
A google search gave me this link to http://chuchuva.com/software/capslockdelay/. The first of the three download links still works.
I don't know about the AutoHotKey script. Maybe google for AutoHotKey and caplock delay.