#HotIf

Creates context-sensitive hotkeys and hotstrings. They perform a different action (or none at all) depending on any condition (an expression).

#HotIf Expression

Parameters

Expression

Type: Boolean

If omitted, subsequently-created hotkeys and hotstrings are not context-sensitive. Otherwise, specify any valid expression. This becomes the return value of an implicit function which has one parameter (ThisHotkey). The function cannot modify global variables directly (as it is assume-local as usual, and cannot contain declarations), but can call other functions which do.

Basic Operation

The #HotIf directive sets the expression which will be used by subsequently created hotkeys and hotstrings to determine whether they should activate. This expression is evaluated when the hotkey's key, mouse button or combination is pressed, when the hotstring's abbreviation is typed, or at other times when the program needs to know whether the hotkey or hotstring is active.

To make context-sensitive hotkeys and hotstrings, simply precede them with the #HotIf directive. For example:

#HotIf WinActive("ahk_class Notepad") or WinActive(MyWindowTitle)
#Space::MsgBox "You pressed Win+Spacebar in Notepad or " MyWindowTitle
:X:btw::MsgBox "You typed btw in Notepad or " MyWindowTitle

The #HotIf directive is positional: it affects all hotkeys and hotstrings physically beneath it in the script, until the next #HotIf directive.

Note: Unlike if statements, braces have no effect with the #HotIf directive.

The #HotIf directive only affects hotkeys and hotstrings created via the double-colon syntax, such as ^!c:: or ::btw::. For hotkeys and hotstrings created via the Hotkey or Hotstring function, use the HotIf function.

To turn off context sensitivity, specify #HotIf without any expression. For example:

#HotIf

Like other directives, #HotIf cannot be executed conditionally.

When a mouse or keyboard hotkey is disabled via #HotIf, it performs its native function; that is, it passes through to the active window as though there is no such hotkey. There is one exception: Controller hotkeys: although #HotIf works, it never prevents other programs from seeing the press of a button.

#HotIf can also be used to alter the behavior of an ordinary key like Enter or Space. This is useful when a particular window ignores that key or performs some action you find undesirable. For example:

#HotIf WinActive("Reminders ahk_class #32770")  ; The "reminders" window in Outlook.
Enter::Send "!o"  ; Have an "Enter" keystroke open the selected reminder rather than snoozing it.
#HotIf

Variants (Duplicates)

A particular hotkey or hotstring can be defined more than once in the script if each definition has different HotIf criteria. These are known as hotkey variants or hotstring variants. For example:

#HotIf WinActive("ahk_class Notepad")
^!c::MsgBox "You pressed Control+Alt+C in Notepad."
#HotIf WinActive("ahk_class WordPadClass")
^!c::MsgBox "You pressed Control+Alt+C in WordPad."
#HotIf
^!c::MsgBox "You pressed Control+Alt+C in a window other than Notepad/WordPad."

If more than one variant is eligible to fire, only the one closest to the top of the script will fire. The exception to this is the global variant (the one with no HotIf criteria): It always has the lowest precedence; therefore, it will fire only if no other variant is eligible (this exception does not apply to hotstrings).

When creating duplicate hotkeys, the order of modifier symbols such as ^!+# does not matter. For example, ^!c is the same as !^c. However, keys must be spelled consistently. For example, Esc is not the same as Escape for this purpose (though the case does not matter). Also, any hotkey with a wildcard prefix (*) is entirely separate from a non-wildcard one; for example, *F1 and F1 would each have their own set of variants.

A window group can be used to make a hotkey or hotstring execute for a group of windows. For example:

GroupAdd "MyGroup", "ahk_class Notepad"
GroupAdd "MyGroup", "ahk_class WordPadClass"

#HotIf WinActive("ahk_group MyGroup")
#z::MsgBox "You pressed Win+Z in either Notepad or WordPad."

To create hotkey or hotstring variants dynamically (while the script is running), see HotIf.

Expression Evaluation

When the hotkey's key, mouse or controller button combination is pressed or the hotstring's abbreviation is typed, the #HotIf expression is evaluated to determine if the hotkey or hotstring should activate.

Note: Scripts should not assume that the expression is only evaluated when the hotkey's key is pressed (see below).

The expression may also be evaluated whenever the program needs to know whether the hotkey is active. For example, the #HotIf expression for a custom combination like a & b:: might be evaluated when the prefix key (a in this example) is pressed, to determine whether it should act as a custom modifier key.

Note: Use of #HotIf in an unresponsive script may cause input lag or break hotkeys and hotstrings (see below).

There are several more caveats to the #HotIf directive:

ThisHotkey, A_ThisHotkey and A_TimeSinceThisHotkey are set based on the hotkey or non-auto-replace hotstring for which the current #HotIf expression is being evaluated.

A_PriorHotkey and A_TimeSincePriorHotkey temporarily contain the previous values of the corresponding "This" variables.

Optimization

#HotIf is optimized to avoid expression evaluation for simple calls to WinActive or WinExist, thereby reducing the risk of lag or other issues in such cases. Specifically:

If the expression meets these criteria, it is evaluated directly by the program and does not appear in ListLines.

Before the Hotkey or Hotstring function is used to modify an existing hotkey or hotstring variant, typically the HotIf function must be used with the original expression text. However, the first unique expression with a given combination of criteria can also be referenced by that criteria. For example:

HotIfWinExist "ahk_class Notepad"
Hotkey "#n", "Off"  ; Turn the hotkey off.
HotIf 'WinExist("ahk_class Notepad")'
Hotkey "#n", "On"   ; Turn the same hotkey back on.

#HotIf WinExist("ahk_class Notepad")
#n::WinActivate

Note that any use of variables will disqualify the expression. If the variable's value never changes after the hotkey or hotstring is created, there are two strategies for minimizing the risk of lag or other issues inherent to #HotIf:

General Remarks

#HotIf also restores prefix keys to their native function when appropriate (a prefix key is A in a hotkey such as a & b). This occurs whenever there are no enabled hotkeys for a given prefix.

When a hotkey is currently disabled via #HotIf, its key or mouse button will appear with a "#" character in KeyHistory's "Type" column. This can help debug a script.

Alt-tab hotkeys are not affected by #HotIf: they are in effect for all windows.

The Last Found Window can be set by #HotIf. For example:

#HotIf WinExist("ahk_class Notepad")
#n::WinActivate  ; Activates the window found by WinExist().

#HotIfTimeout may be used to override the default timeout value.

Hotkey function, Hotkeys, Hotstring function, Hotstrings, Suspend, WinActive, WinExist, SetTitleMatchMode, DetectHiddenWindows

Examples

Creates two hotkeys and one hotstring which only work when Notepad is active, and one hotkey which works for any window except Notepad.

#HotIf WinActive("ahk_class Notepad")
^!a::MsgBox "You pressed Ctrl-Alt-A while Notepad is active."
#c::MsgBox "You pressed Win-C while Notepad is active."
::btw::This replacement text for "btw" will occur only in Notepad.
#HotIf
#c::MsgBox "You pressed Win-C in a window other than Notepad."

Allows the volume to be adjusted by scrolling the mouse wheel over the taskbar.

#HotIf MouseIsOver("ahk_class Shell_TrayWnd")
WheelUp::Send "{Volume_Up}"
WheelDown::Send "{Volume_Down}"

MouseIsOver(WinTitle) {
    MouseGetPos ,, &Win
    return WinExist(WinTitle " ahk_id " Win)
}

Simple word-delete shortcuts for all Edit controls.

#HotIf ActiveControlIsOfClass("Edit")
^BS::Send "^+{Left}{Del}"
^Del::Send "^+{Right}{Del}"

ActiveControlIsOfClass(Cls) {
    FocusedControl := 0
    try FocusedControl := ControlGetFocus("A")
    FocusedControlClass := ""
    try FocusedControlClass := WinGetClass(FocusedControl)
    return (FocusedControlClass=Cls)
}

Context-insensitive Hotkey.

#HotIf
Esc::ExitApp

Dynamic Hotkeys. This example should be combined with example #2 before running it.

NumpadAdd::
{
    static toggle := false
    HotIf 'MouseIsOver("ahk_class Shell_TrayWnd")'
    if (toggle := !toggle)
        Hotkey "WheelUp", DoubleUp
    else
        Hotkey "WheelUp", "WheelUp"
    return
    ; Nested function:	
    DoubleUp(ThisHotkey) => Send("{Volume_Up 2}")
}