Search code examples
variablesautomationscopeautohotkeyhotkeys

autohotkey variables not updating on keypresses


I have a number of hotkeys which go through various processes and sleep for certain periods of time to allow animations to be shown. I want to setup a variable to allow only 1 to activate at a time...so if I hit the first and then the second....the second doesn't do anything until the first completes. Similarly I don't want to double activate any of them by mashing the same key right after I first press it.

F4:ExitApp
#IfWinActive ahk_class notepad

a::
if (work:=true){
work:=false
soundbeep
;do something
sleep 1000
work:=true
}
return

b::
if (work:=true){
work:=false
soundbeep
;do something else
sleep 2000
work:=true
}
return

i.e. if I hit 'a'....'b' cannot activate until the sleep of 'a' ends. Nor should 'a' be able to activate a second time...at least not until its sleep ends and work=true again.

This leaves 2 problems. I need to first somehow specify the initial value of 'work=true'. I do not know how to do this in the traditional sense. Simply putting it at the top of the code doesn't work. Second problem, putting this in another key...like enter:: work:=true return....and pressing that key initially...this doesn't work as it allows b to beep while a is still in its sleep phase. So maybe the code above is flawed to begin with as well. Individual keys seem to respect themselves and not re-initialize until after the first instance has completed...so the beeps work if I just mash 1 key. Also I don't want to have to press enter to get the code to work after loading the script.

Is there an easy cheat here? Like in lua undeclared variables are automatically false... so I could just swap to if (work=false){...., I can't find any such behaviour with autohotkey though.


Solution

  • As requested, here is a different solution that uses variable logic to allow or prevent hotkey commands from executing:

    #IfWinActive ahk_class Notepad
    work:=true
    a::
    if(work){
        work:=false
        soundbeep
        ;do something
        sleep 1000
        work:=true
    }
    return
    
    b::
    if(work){
        work:=false
        soundbeep
        ;do something else
        sleep 2000
        work:=true
    }
    return
    

    Update: Breakdown of how it works

    First, the script begins in the auto-execute section. As summarized elegently by maul-esel

    When an AutoHotkey script launches, it just starts execution from the first line of your script. It continues from there line by line until it hits an end point. This is called the auto-execute section.

    As such, by including work:=true in this section of the script, not only are we initializing the value of the variable before any hotkeys are triggered, we set the scope of work to be a global variable, accessible across different hotkeys.

    The rest of the script is a bit more straightforward, where each hotkey is essentially (in pseudocode):

    • When the hotkey is triggered
    • if work is true
      • set work to false
      • Beep and etc.
      • Wait for some amount of time
      • Then set work back to true so that another command can be run
    • End the hotkey