How to ISOLATE single and double keypresses?

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
alphaomega
Posts: 15
Joined: 20 Feb 2024, 23:50

How to ISOLATE single and double keypresses?

27 Feb 2024, 13:00

Hello.
Tried to search forum and google but didn't find my question so I am making it here.
The question is how to separate SINGLE and DOUBLE keypress?

I tried to write a code to determine double click and succeeded, but... it fires both - single and then double (if double pressed) events.
I need CTRL+ALT+Y for single press and CTRL+ALT+SHIFT+Y for double press, but I don't want script to send CTRL+ALT+Y additionaly prior doing doublepress... It should be EITHER/OR condition. Maybe some kind of timer? But will not it interfere with double check?... Got my mind blown )))

Code: Select all

Numpad0::
{
if (A_PriorHotkey != A_ThisHotkey) || (A_TimeSincePriorHotkey > 400)
 Send '^!y'
Else
 Send '+^!y'
}
What should I change to make script differ single and double press?
alphaomega
Posts: 15
Joined: 20 Feb 2024, 23:50

Re: How to ISOLATE single and double keypresses?

27 Feb 2024, 13:14

I tried another way around

Code: Select all

*Numpad0:: {
    KeyWait('Numpad0')
    if KeyWait('Numpad0', 'd t0.1')
        Send '+^!y'
    else Send '^!y'
}
It works, but 100ms delay before activating CTRL+ALT+Y is way too long. Looks like keyboard lagging that is incovenient to use.
If I cut dt0.1 in half, CTRL+ALT+Y works fine, but to get double press I should become Flash )))) so it almost not possible.

So... maybe there is another technique I can apply? For example a SHORT vs LONG press?
Answers to that query lead to strange scripts that are way to big for just one key (I need almost 25% of keyboard to remap using either single/double or short/long press).

Any hints please?
teadrinker
Posts: 4358
Joined: 29 Mar 2015, 09:41
Contact:

Re: How to ISOLATE single and double keypresses?

27 Feb 2024, 19:25

Or like this:

Code: Select all

#Requires AutoHotkey v2

Numpad0:: {
    KeyWait(key := RegExReplace(A_ThisHotkey, '.*?(\w+)$', '$1'))
    if KeyWait(key, 'DT.3')
        MsgBox 'Double press', ' ', 'T.6'
    else
        MsgBox 'Single press', ' ', 'T.6'
}
alphaomega
Posts: 15
Joined: 20 Feb 2024, 23:50

Re: How to ISOLATE single and double keypresses?

06 Mar 2024, 10:10

Hi, thankx for help, I decided to use SHORT/LONG press method instead (to remove time gap/delay for single press).
Anyway, now I have a bit of a problem. Maybe I read documentation incorrectly, but currently if I want some keys to be triggered in specific application, I need to define #IfWinActive ahk_exe AfterEffects.exe but it looks to be either a separate script or separate block...

But what should I CHANGE HERE if I want "q" key long press to send text input, but short press to be variable defined by ACTIVE program?

Code: Select all

q::{
    waitvar := (Keywait(A_ThisHotkey, "T" longpress)) 
    if waitvar
	     ; IfWinActive ahk_exe  AfterEffects.exe then Send '{Blind}^!{VK43}'
	     ; IfWinActive ahk_exe  then Send '{Blind}^{F11}'
	     ; else Send '{Blind}^{F10}'
    else
        SendInput "имя:*.wav OR имя:*.mp3"
	    Send '{VK0D}'
    KeyWait A_ThisHotkey  ; stops key repeat from retriggering
}
alphaomega
Posts: 15
Joined: 20 Feb 2024, 23:50

Re: How to ISOLATE single and double keypresses?

06 Mar 2024, 10:23

p.s.: that part of the code is curently placed between "#HotIf cm1.IsActive" and "#HotIf" (like context example script has)
User avatar
mikeyww
Posts: 27143
Joined: 09 Sep 2014, 18:38

Re: How to ISOLATE single and double keypresses?

06 Mar 2024, 11:08

WinActive is a function to get the HWND if a window is active. It's zero otherwise.
alphaomega
Posts: 15
Joined: 20 Feb 2024, 23:50

Re: How to ISOLATE single and double keypresses?

06 Mar 2024, 13:13

Yeah, but how do I change the code block above to make my script work?
User avatar
mikeyww
Posts: 27143
Joined: 09 Sep 2014, 18:38

Re: How to ISOLATE single and double keypresses?

06 Mar 2024, 13:21

Indentation might look nice, but braces define code blocks in AHK.

Code: Select all

#Requires AutoHotkey v2.0

F3:: {
 If KeyWait(ThisHotkey, 'T.3') {  ; Short
  Switch {
   Case WinActive('ahk_exe notepad.exe'):
    MsgBox 'Short 1'
   Default:
    MsgBox 'Short 2'
  }
 } Else {                         ; Long (held)
  MsgBox 'Long'
 }
}
Explained: Code blocks
teadrinker
Posts: 4358
Joined: 29 Mar 2015, 09:41
Contact:

Re: How to ISOLATE single and double keypresses?

06 Mar 2024, 14:14

Or like this:

Code: Select all

F3:: {
    short := KeyWait(ThisHotkey, 'T.3')
    switch {
        case short && WinActive('ahk_exe notepad.exe') : MsgBox 'Short 1'
        case short : MsgBox 'Short 2'
        default    : MsgBox 'Long'
    }
}
alphaomega
Posts: 15
Joined: 20 Feb 2024, 23:50

Re: How to ISOLATE single and double keypresses?

02 Apr 2024, 16:53

Hi again.
Lately noticed weird behavior of longpress (Keywait) code parts. When I use short/long with regular letter keys everything works fine.
But If I use it with Escape, Enter, arrows or even ctrl/alt/shift, then in 75% of cases (or more) it gets stuck with long press blocking next single presses or other keys to be registered.
Is there a solution for that?

Here are sample blocks from my script for "Esc" and "e" keys. They look the same but works differently.
The most likely scenarios with escape are:
a) the second press even after a minute calls long press and blocks input.
b) works fine with a few single presses but after a long press blocks input.

Code: Select all

Esc::{
    waitvar := (Keywait(A_ThisHotkey, "T" longpress)) 
    if waitvar
        Send '{Blind}^!+{VKC0}'
    else
        Send '{Blind}^!+{F12}'
    KeyWait A_ThisHotkey  ; stops key repeat from retriggering
}

e::{
    waitvar := (Keywait(A_ThisHotkey, "T" longpress)) 
    if waitvar
        Send '{Blind}^{VK47}'
    else
        Send '{Blind}!{VK47}'
    KeyWait A_ThisHotkey  ; stops key repeat from retriggering
}
Any ideas?
alphaomega
Posts: 15
Joined: 20 Feb 2024, 23:50

Re: How to ISOLATE single and double keypresses?

02 Apr 2024, 16:55

can the cause be *waitvar* variable? it is the same everywhere... maybe if I change it to *waitvaresc* and *waitvare* accordingly will it work fine?
User avatar
mikeyww
Posts: 27143
Joined: 09 Sep 2014, 18:38

Re: How to ISOLATE single and double keypresses?

02 Apr 2024, 19:37

Comments:
  1. Maybe changing... xyz will work fine? How to know? Test it.
  2. Do you know what the value of A_ThisHotkey is? How do you know? Test it. Find out. Do you believe that A_ThisHotkey and ThisHotkey have the same value? If so, why? Can you use the script to determine whether you are right?
  3. Test one thing at a time. Shorten and simplify your script. Test one hotkey before testing multiple hotkeys. Expand your script gradually. Re-test.
  4. If you wonder what the value of waitvar really is, check it. You do not need to send anything to assess it. Display the value, log it, or inspect it. Some people use OutputDebug. You can do anything that is informative and systematic.
This is the debugging process. It is not about what you think is happening. Use the script to inform you.

Return to “Ask for Help (v2)”

Who is online

Users browsing this forum: hitman, Insaid and 29 guests