Waits for a key or mouse/joystick button to be released or pressed down.

KeyWait KeyName , Options



Type: String

This can be just about any single character from the keyboard or one of the key names from the key list, such as a mouse/joystick button. Joystick attributes other than buttons are not supported.

An explicit virtual key code such as vkFF may also be specified. This is useful in the rare case where a key has no name and produces no visible character when pressed. Its virtual key code can be determined by following the steps at the bottom of the key list page.


Type: String

If this parameter is blank, the function will wait indefinitely for the specified key or mouse/joystick button to be physically released by the user. However, if the keyboard hook is not installed and KeyName is a keyboard key released artificially by means such as the Send function, the key will be seen as having been physically released. The same is true for mouse buttons when the mouse hook is not installed.

Options: A string of one or more of the following letters (in any order, with optional spaces in between):

D: Wait for the key to be pushed down.

L: Check the logical state of the key, which is the state that the OS and the active window believe the key to be in (not necessarily the same as the physical state). This option is ignored for joystick buttons.

T: Timeout (e.g. T3). The number of seconds to wait before timing out and returning 0. If the key or button achieves the specified state, the function will not wait for the timeout to expire. Instead, it will immediately return 1.

The timeout value can be a floating point number such as 2.5, but it should not be a hexadecimal value such as 0x03.

Return Value

Type: Integer (boolean)

This function returns 0 (false) if the function timed out or 1 (true) otherwise.


The physical state of a key or mouse button will usually be the same as the logical state unless the keyboard and/or mouse hooks are installed, in which case it will accurately reflect whether or not the user is physically holding down the key. You can determine if your script is using the hooks via the KeyHistory function or menu item. You can force either or both of the hooks to be installed by adding the InstallKeybdHook and InstallMouseHook functions to the script.

While the function is in a waiting state, new threads can be launched via hotkey, custom menu item, or timer.

To wait for two or more keys to be released, use KeyWait consecutively. For example:

KeyWait "Control"  ; Wait for both Control and Alt to be released.
KeyWait "Alt"

To wait for any one key among a set of keys to be pressed down, see the examples section of the InputHook function.

GetKeyState, Key List, InputHook, KeyHistory, InstallKeybdHook, InstallMouseHook, ClipWait, WinWait


Waits for the A key to be released.

KeyWait "a"

Waits for the left mouse button to be pressed down.

KeyWait "LButton", "D"

Waits up to 3 seconds for the first joystick button to be pressed down.

KeyWait "Joy1", "D T3"

Waits for the left Alt key to be logically released.

KeyWait "LAlt", "L"

When pressing this hotkey, KeyWait waits for the user to physically release the CapsLock key. As a result, subsequent statements are performed on release instead of press. This behavior is similar to ~CapsLock up::.

    KeyWait "CapsLock"  ; Wait for user to physically release it.
    MsgBox "You pressed and released the CapsLock key."

Remaps a key or mouse button (this is only for illustration because it would be easier to use the built-in remapping feature). The left mouse button is kept held down while NumpadAdd is down, which effectively transforms NumpadAdd into the left mouse button.

    MouseClick "left",,, 1, 0, "D"  ; Hold down the left mouse button.
    KeyWait "NumpadAdd"  ; Wait for the key to be released.
    MouseClick "left",,, 1, 0, "U"  ; Release the mouse button.

Detects when a key has been double-pressed (similar to double-click). KeyWait is used to stop the keyboard's auto-repeat feature from creating an unwanted double-press when you hold down the RControl key to modify another key. It does this by keeping the hotkey's thread running, which blocks the auto-repeats by relying upon #MaxThreadsPerHotkey being at its default setting of 1. Note: There is a more elaborate script to distinguish between single, double, and triple-presses at the bottom of the SetTimer page.

    if (A_PriorHotkey != "~RControl" or A_TimeSincePriorHotkey > 400)
        ; Too much time between presses, so this isn't a double-press.
        KeyWait "RControl"
    MsgBox "You double-pressed the right control key."