Keywait can not detect long press for ctrl key at AutoHotkey V2

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
ninjawisdom
Posts: 3
Joined: 15 May 2024, 23:19

Keywait can not detect long press for ctrl key at AutoHotkey V2

Post by ninjawisdom » 15 May 2024, 23:35

Based on the following URL, I tried implementing a command to detect long key presses using Keywait at AutoHotkey V2.
viewtopic.php?style=19&t=86626

However, it seems that the Keywait detection does not work for certain keys, such as the Ctrl key and function keys above F13 that have been swapped with other keys.

The following code works:

Code: Select all

p::{
  if (KeyWait("p", "T0.2")){ ; Long press)
    msgbox(1)
  } else { ; Single press
    msgbox(2)
  }
}
The following code does not work:

Code: Select all

LCtrl::{
  if (KeyWait("LCtrl", "T0.2")){ ; Long press)
    msgbox(1)
  } else { ; Single press
    msgbox(2)
  }
}
The following code also does not work:

Code: Select all

F14::{
  if (KeyWait("F14", "T0.2")){ ; Long press)
    msgbox(1)
  } else { ; Single press
    msgbox(2)
  }
}
Is this a bug? If so, I would appreciate it if you could fix it.
Thank you for your attention.
lexikos
Posts: 9780
Joined: 30 Sep 2013, 04:07
Contact:

Re: Keywait can not detect long press for ctrl key at AutoHotkey V2

Post by lexikos » 16 May 2024, 03:14

If you must ask "is this a bug?", it likely isn't. Please post in Ask for Help in future. I have moved the topic.

When you omit the L option, KeyWait will wait until the key is not being physically pressed down. You are not physically pressing down LCtrl or F14, so it does not wait.

If you use the L option, KeyWait will wait until the key's logical state is "up". If you are suppressing the key with a hotkey such as F14::, it will not wait because the key is always "up".

KeyWait cannot be used to wait for a key which is neither physically nor logically pressed down. This is not a bug.

You can instead use key-up hotkeys such as F14 up::.
ninjawisdom
Posts: 3
Joined: 15 May 2024, 23:19

Re: Keywait can not detect long press for ctrl key at AutoHotkey V2

Post by ninjawisdom » 16 May 2024, 04:11

Thank you for your comment. Could you explain why the behavior is different for the 'p' key and the LCtrl/F14 keys? Alternatively, could you provide an example of correct code that produces the same result?
ninjawisdom
Posts: 3
Joined: 15 May 2024, 23:19

Re: Keywait can not detect long press for ctrl key at AutoHotkey V2

Post by ninjawisdom » 16 May 2024, 23:11

After some trial and error, I found the cause of the long press not being detected, so I would like to provide additional information.

The following code fails to detect a long press of the RCtrl key:

Code: Select all

; Coommand using ctrl key
Ctrl & a::{
  MsgBox "Ctrl + A was pressed."
}

; Test of long press of RCtrl
RCtrl::{  
  if KeyWait("RCtrl","T0.5"){
    MsgBox "RCtrl was released!"
  } else {
    MsgBox "RCtrl was not released!"
  }
}
The reason is that the Ctrl of "Ctrl & a" command conflicts with RCtrl.

If you change the code as follows, the long press detection for RCtrl works well:

Code: Select all

; Coommand using ctrl key
^a::{
  MsgBox "Ctrl + A was pressed."
}

; Test of long press of RCtrl
RCtrl::{  
  if KeyWait("RCtrl","T0.5"){
    MsgBox "RCtrl was released!"
  } else {
    MsgBox "RCtrl was not released!"
  }
}
I only changed Ctrl to ^.

Similarly, if you change the code as follows, the long press detection for RCtrl works well:

Code: Select all

; Coommand using ctrl key
LCtrl & a::{
  MsgBox "Ctrl + A was pressed."
}

; Test of long press of RCtrl
RCtrl::{  
  if KeyWait("RCtrl","T0.5"){
    MsgBox "RCtrl was released!"
  } else {
    MsgBox "RCtrl was not released!"
  }
}
I only changed Ctrl to LCtrl.

In the world of AutoHotkey, I remember that Ctrl and ^ have the same meaning. This phenomenon seems puzzling to interpret as a feature rather than a bug, but I am noting it here as a temporary workaround.

However, regarding the F14 key, it is difficult to express it differently. If you are using the F14 key as a modifier key in another part of the script, this workaround cannot be used.
lexikos
Posts: 9780
Joined: 30 Sep 2013, 04:07
Contact:

Re: Keywait can not detect long press for ctrl key at AutoHotkey V2

Post by lexikos » 23 May 2024, 22:25

ninjawisdom wrote:
16 May 2024, 04:11
Could you explain why the behavior is different for the 'p' key and the LCtrl/F14 keys?
I did already, based on the information you gave in your first post:
However, it seems that the Keywait detection does not work for certain keys, such as the Ctrl key and function keys above F13 that have been swapped with other keys.
If you are physically holding down p, LCtrl or F14 and using only the code you originally posted, they will work. If you are physically holding down some other key which sends p, LCtrl or F14, they will not work. There is no difference between p, LCtrl and F14 in this regard.

When "p" is swapped with "o", the latter can only perform a "single press".

Code: Select all

p::{
  if (KeyWait("p", "T0.2")){ ; Single press
    msgbox(1)
  } else { ; Long press
    msgbox(2)
  }
}

#InputLevel 1
o::p
Btw, the comments in your original p:: were around the wrong way.

ninjawisdom wrote:After some trial and error, I found the cause of the long press not being detected,
You found another issue which is in no way represented in your original examples or description of the conditions.
The reason is that the Ctrl of "Ctrl & a" command conflicts with RCtrl.
It does not "conflict"; the use of a Custom Combination affects the behaviour of the prefix key by design.
A custom combination of two keys (including mouse but not controller buttons) can be defined by using " & " between them. Because they are intended for use with prefix keys that are not normally used as such, custom combinations have the following special behavior:
  • The prefix key loses its native function, unless it is a standard modifier key or toggleable key such as CapsLock.
  • If the prefix key is also used as a suffix in another hotkey, by default that hotkey is fired upon release, and is not fired at all if it was used to activate a custom combination. If there is both a key-down hotkey and a key-up hotkey, both hotkeys are fired at once. The fire-on-release effect is disabled if the tilde prefix is applied to the prefix key in at least one active custom combination or the suffix hotkey itself.
Source: Hotkeys - Definition & Usage | AutoHotkey v2
To be clear, the behaviour described above means that you do not call KeyWait until after the key is released.

ninjawisdom wrote:In the world of AutoHotkey, I remember that Ctrl and ^ have the same meaning.
The association only goes one way, and only in a limited context. a := b ^ c is bitwise exclusive-OR. Send "{^}" is Shift+6 on the US layout. If Ctrl had the same meaning as ^, Ctrla:: and would be valid and ^ & a:: would be the same as Ctrl & a:: (it's actually the same as 6 & a:: on the US layout).

However, regarding the F14 key, it is difficult to express it differently. If you are using the F14 key as a modifier key in another part of the script, this workaround cannot be used.
As I said, you can use F14 up:: to detect when F14 is "released".
Post Reply

Return to “Ask for Help (v2)”