Make CAPSLOCK work properly when single-, double-, and combo-pressed - autohotkey

I want to write an AutoHotKey script on Windows 10 that gives CAPSLOCK more functionality. My goals with CAPSLOCK are three-fold:
When single-pressed, CAPSLOCK works as usual.
When double-pressed (pressed twice in a short time), CAPSLOCK fires an ESC key. The status/light of CAPSLOCK should remain the same as before, but I am okay if the light went on and off, or off and on.
When CAPSLOCK are held down, in combination with JKLI, CAPSLOCK + JKLI will function as arrow keys (left, down, right, up). Like in goal 2, the status/light of CAPSLOCK should remain the same as before. (I am okay if the light went on and off in the process, so long the terminal status is correct).
If I only needed goal #1 and goal #3, the following script would work just fine.
CapsLock & J::Send {Left}
CapsLock & K::Send {Down}
CapsLock & L::Send {Right}
CapsLock & I::Send {Up}
However, now I want to achieve goal #2 as well, and added some more lines before it, as follows
~CapsLock::
KeyWait, CapsLock
KeyWait, CapsLock, D T0.2
if not ErrorLevel
Send {Escape}
Return
CapsLock & J::Send {Left}
CapsLock & K::Send {Down}
CapsLock & L::Send {Right}
CapsLock & I::Send {Up}
Now I am having the problem: goal #1 and goal #2 are achieved, but goal #3 is not. The status/light of CAPSLOCK would change after say I pressed CAPSLOCK + L. This is not what I want -- I want holding down CAPSLOCK and pressing L to move cursor to the right, and I want this behavior to have no effect on the status of CAPSLOCK.
Please let me know how to achieve my three goals with CAPSLOCK using AutoHotKey. Any help is much appreciated!
By the way, I am working on a Lenovo Thinkpad T model produced in 2016.

You need a timer to restore the CapsLock state after it has been changed in a combination:
Capslock::
If (A_PriorHotKey = "~Capslock Up" AND A_TimeSincePriorHotkey < 400 AND A_TimeSincePriorHotkey > 50) ; double-press
Send, {Esc}
SetTimer, RestoreCapslockState, 50
return
~Capslock Up:: return ; The tilde prefix (~) prevents AHK from blocking the key-down/up events
CapsLock & J::Send {Left}
CapsLock & K::Send {Down}
CapsLock & L::Send {Right}
CapsLock & I::Send {Up}
RestoreCapslockState:
KeyWait, Capslock ; wait for Capslock to be released
SetTimer, RestoreCapslockState, OFF
If (A_PriorKey != "Capslock")
SetCapsLockState % !GetKeyState("CapsLock", "T") ; Toggles CapsLock to its opposite state, requires [v1.1.30+]
return
https://www.autohotkey.com/docs/commands/SetTimer.htm
https://www.autohotkey.com/docs/commands/SetNumScrollCapsLockState.htm#ex2

Related

Invalid hotkey: Ctrl & CapsLock & L

To map CapsLock to Esc if pressed alone, and use it as a modifier key otherwise, I use this script:
#InstallKeybdHook
SetCapsLockState AlwaysOff
CapsLock::Send {esc}
CapsLock & h::Left
CapsLock & j::Down
CapsLock & k::Up
CapsLock & l::Right
return
To move around virtual desktops in Windows, I wanted to now map Ctrl & CapsLock & l::^#Right. Unfortunately this is not possible and gives an error: Invalid hotkey. Does anybody know why?
Instead of remapping I'd use the Send command to define new hotkeys.
A remapping is not a hotkey. A remapping is two hotkeys (key-down and key-up) with each having the wildcard modifier, as shown in the documentation.
Combinations of three or more keys (Ctrl & CapsLock & l) are not supported.
Or try it this way:
#InstallKeybdHook
SetCapsLockState AlwaysOff
CapsLock::Send {esc}
CapsLock & h::Send {Left}
CapsLock & j::Send {Down}
CapsLock & k::Send {Up}
CapsLock & l::
If GetKeyState("Ctrl", "P")
SendEvent {LWin down}{LCtrl down}{Right down}{LWin up}{LCtrl up}{Right up} ; switch to next virtual desktop
else
Send {Right}
return

Capslock Shift Modifier

I would like an AHK script that will disable Capslock except when used with arrow keys as a shortcut for Home and End (with and without text selection). I believe it would look something like this, but I can't get figure out how to include the Shift key as a modifier so I may select text as well.
Capslock::Return
Capslock & Right::End
Capslock & Left::Home
Capslock & Right & Shift::End (with Selection)
Capslock & Left & Shift::Home (with Selection)
This AutoHotkey script should do what you want to achieve:
Note: on some keyboards it is difficult or even impossible to get certain key combinations to act as a hotkey, especially when there is more than one non-modifier key, e.g. CapsLock and Right are not modifiers, whereas Shift/Ctrl/Win/Alt are.
Note: I could not get !CapsLock::CapsLock to work. A long time ago, after a lot of trial and error at the time, I found some working code to assign a different key combination for CapsLock that I include below.
Capslock::Return
Capslock & Right::
if GetKeyState("Shift", "p")
SendInput +{End}
else
SendInput {End}
Return
Capslock & Left::
if GetKeyState("Shift", "p")
SendInput +{Home}
else
SendInput {Home}
Return
;!CapsLock::CapsLock
!CapsLock::
SetStoreCapslockMode, Off
SendInput {CapsLock}
SetStoreCapslockMode, On
Return
Copy pasted and trialed and horrored from many, unfortunately forgotten, places is my solution here.
As you can se I have mapped alt-Capslock to normal Capslock
and Capslock by itself to Esc.
Following the same pattern I tried to grab shift-Capslock and alt-Capslock with a +CapsLock & h::Send {Backspace} but AHK complained about bad syntax.
You can also see that ; happens to have a special annotation and that is because I change keyboard and that key is sometimes ; and sometimes ö.
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
SetCapsLockState AlwaysOff
; Toggle Capslock with alt-Capslock.
!CapsLock::CapsLock
; Esc.
CapsLock::Send {Esc}
; Arrows.
CapsLock & j::Send {Left}
CapsLock & k::Send {Right}
CapsLock & SC027::Send {Down} ; or CapsLock & `;::Send {Down}
CapsLock & l::Send {Up}
CapsLock & u::Send ^{Left}
CapsLock & i::Send ^{Right}
; Backspace and Del.
CapsLock & h::Send {Backspace}
; Home and End.
CapsLock & m::Send {Home}
CapsLock & ,::Send {End}
; Mark word left.
CapsLock & y::Send ^+{Left}

Bind one key to three modifier keys autohotkey

i wannna be able to press Alt+Middle Button for simulating Shift+Ctrl+Right Button with AutoHotkey. I did it for simulating two keys. And it worked but it is not working for three keys.
so i wrote that:
LAlt & MButton::Send {Ctrl Down}{Shift Down}{RButton Down}
keywait, LAlt
keywait, MButton
LAlt & MButton Up::Send {Ctrl Up}{Shift Up}{RButton Up}
return
where is the problem?
First thing is that the two keywait lines are never executed as you have your send action on the some line as the hotkey, this will make a one-line hotkey or remap
If you wish to execute multiple lines of code in one hotkey routine you will need to start the routine on the line below the hotkey definition label.
Also try taking a simpler approach be using Autohotkeys remapping capabilities
Can't say this will work for you but give it a shot
!MButton::^+RButton
Hope it helps

Conditionally intercept a mouse click in Autohotkey?

I want to have a script which will intercept a mouse click and send a key press instead, but only when the capslock key is toggled on. I want the mouse click to be sent normally if the capslock key is toggled off.
Currently I have made this:
$LButton::
if GetKeyState("CapsLock", "T") = 1
send, {a}
else
send, {LButton}
return
The problem with this is that when the capslock key is off, the left button can click perfectly normally but it cannot drag.
If I change $ to ~, it is able to drag but it also performs a click when the capslock key is toggled on.
Is there any way to make the script ignore the click completely if the capslock key is toggled off?
AHK_L's #If will give you what you want:
#If GetKeyState("CapsLock", "T")
LButton::Send, a
With this code, you won't have to bother what happens when capslock is off. AHK will intercept the click on a lower level and let it trickle through.
How to use the symbol UP.
SetBatchLines, -1 ; you pretty much have to include this to speed up the execution
LButton::
if( GetKeyState("CapsLock", "T") )
tooltip, ignore left click
else
send, {LButton Down}
return
LButton UP::
send, {LButton Up}
return

Mapping Capslock to Esc and Capslock & C to a function in Autohotkey

I want to configure autohotkey in the following way:
Capslock::Esc
Capslock & C::
Run, www.stackoverflow.com
return
So if I just press Capslock it treated like if I would have pressed Esc. If I on the other hand press both Capslock and c, it call the function that opens the browser with www.stackoverflow.com.
At the moment the remapped seems to break when I have the other function in the script. When I press capslock now it toggles it for a short time, so the key alone does effectively nothing. I don't get my Esc.
Pressing capslocks + A on the other hand activates capslock and produces a real A.
Is there an easy way to fix this?
Check out this code:
inProcess = 0
Capslock::
Gui, 93:+Owner ; prevent display of taskbar button
Gui, 93:Show, y-99999 NA, Enable nav-hotkeys
inProcess = 1
KeyWait, Capslock ; wait until the Capslock button is released
Gui, 93:Cancel
if (inProcess == 1){
Send, {Esc}
}
Return
#IfWinExist, Enable nav-hotkeys
*c::
Run, www.stackoverflow.com
inProcess = 0
return
#IfWinExist, ; end context-sensitive block
I've modified an answer available here: http://www.autohotkey.com/board/topic/56428-problem-rebinding-ctrl-to-capslock-using/