single/double press for different actions

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
AndrewKun
Posts: 24
Joined: 03 Jun 2015, 12:03

single/double press for different actions

03 Apr 2017, 07:35

Hi guys, I have a simple task of making a single press of a hotkey to perform one action, while double tapping it to perform another action. Searching the forums I found this bit of code

Code: Select all

$#vk4e::
	If (A_ThisHotKey = A_PriorHotkey and A_TimeSincePriorHotkey < 300) {
		; action 1
	}
	else {
		; action 2
	}
return
The problem with this approach is that Action 1 will be performed in either way, even if I just want to perform Action 2. I can't figure out how to make AHK to execute either Action 1 OR Action 2, since I'm not good at programming.
Can you please help?
GEV
Posts: 1005
Joined: 25 Feb 2014, 00:50

Re: single/double press for different actions

03 Apr 2017, 09:39

Code: Select all

<#a::			; <# means LWin
count++   	 	; for each press, increment a counter
If (count=1)
    SetTimer action, -50
return

	action:
KeyWait, LWin, L
If (count=1)
    MsgBox, action 1
If (count=2)
    MsgBox, action 2
; ...
count:=0      	; reset counter
return
Xeno234
Posts: 71
Joined: 24 Mar 2017, 18:14

Re: single/double press for different actions

03 Apr 2017, 10:10

Code: Select all

#vk4e::
	keywait, vk4e ; up first key
	keywait, vk4e, d t0.2 ; 2nd key?
	if errorlevel
		send 1
	else 
		send 2
return
User avatar
evilC
Posts: 4824
Joined: 27 Feb 2014, 12:30

Re: single/double press for different actions

03 Apr 2017, 10:49

AHK is not a time machine :)
If you wish to implement logic like this for a given key, you need to define a timeout period, and take no action until that timeout expires.
If the user presses a second time within the timeout, send action #2, else send action #1

There is no other way to solve this if you only wish to ever send 1 action.
So yeah, Xeno's post appears about on the money.
AndrewKun
Posts: 24
Joined: 03 Jun 2015, 12:03

Re: single/double press for different actions

03 Apr 2017, 11:13

Thank you so much for helping, everyone
evilC wrote:AHK is not a time machine :)
If you wish to implement logic like this for a given key, you need to define a timeout period, and take no action until that timeout expires.
If the user presses a second time within the timeout, send action #2, else send action #1

There is no other way to solve this if you only wish to ever send 1 action.
So yeah, Xeno's post appears about on the money.
But... but... GEV's solution worked perfectly, actually. The logic is that script waits while I release modifier key (Win key in my case), and while waiting, counts the other key presses. This way I can wait for however long between key presses and it still runs either action 1 OR action 2, as long as I don't release the win key between presses, which I have no reason to. This is perfect!

Xeno's approach also works, but for some reason it doesn't work if I use #MaxThreadsPerHotkey limit (regardless of which limit I set).

Thanks again GEV, this would really make running some apps with hotkeys easier.
User avatar
evilC
Posts: 4824
Joined: 27 Feb 2014, 12:30

Re: single/double press for different actions

03 Apr 2017, 11:18

GEV's solution works in the same way.
It starts a timer off for 50ms, and if you trigger the hotkey again within 50ms, it resets the timer.

It takes no action until the timer has expired, and therefore works in the way I mentioned.

There is no other way around this, you cannot look forward in time to know the user's intentions before he enacts them
User avatar
evilC
Posts: 4824
Joined: 27 Feb 2014, 12:30

Re: single/double press for different actions

03 Apr 2017, 11:23

Actually, I am slightly off there.

The 50ms timer in GEV's solution seems pointless, the code will work the same way without the 50ms time:

Code: Select all

<#a::			; <# means LWin
count++   	 	; for each press, increment a counter
SetTimer action, -0	; SetTimer is only used here to cause the code to be jumped to in a psuedo-thread.
return

	action:
KeyWait, LWin, L
If (count=1)
    MsgBox, action 1
If (count=2)
    MsgBox, action 2
; ...
count:=0      	; reset counter
return
But this is a different solution - it is a 2-key hotkey rather than a 1-key hotkey.

Your original code was for a 1-key hotkey, and in that instance, my statement holds true.
Xeno234
Posts: 71
Joined: 24 Mar 2017, 18:14

Re: single/double press for different actions

03 Apr 2017, 11:51

for some reason it doesn't work if I use #MaxThreadsPerHotkey limit (regardless of which limit I set).
It seems to work fine for me. Also keep in mind if you have other parts of your script that need 2+ threads per hotkey you can have several directives for that.

Code: Select all

#MaxThreadsPerHotkey 2

f1::
	sleep 3000
	send a
return

#MaxThreadsPerHotkey 1

#vk4e::
	keywait, vk4e ; up first key
	keywait, vk4e, d t0.2 ; 2nd key?
	if errorlevel
		send 1
	else 
		send 2
return
AndrewKun
Posts: 24
Joined: 03 Jun 2015, 12:03

Re: single/double press for different actions

03 Apr 2017, 15:09

Just let me express my appreciation to everyone once again. I'm always happy to learn new ways of solving stuff, and hopefully can become more experineced to help people like me in the future!

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Bing [Bot], Google [Bot], oktavimark and 372 guests