Toggle AppsKey

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Renfro
Posts: 64
Joined: 15 Oct 2020, 10:19

Toggle AppsKey

31 Mar 2021, 19:34

If I accidentally press AppsKey, then in order to cancel the AppsKey context menu I have to go to the other side of the Keyboard to press the Esc key. Instead I would like to be able to just press AppsKey again to cancel it.

I would try to do this myself using GetKeyState, but my attempts so far just broke AppsKey functionality completely, and seeing how important this key is, I don't want to end up with a script that seems like it's working, but it ends up doing strange things under certain circumstances that takes me days to discover.

What's the best (safest) way to allow AppsKey to toggle on and off without interfering with its normal function?
User avatar
boiler
Posts: 16949
Joined: 21 Dec 2014, 02:44

Re: Toggle AppsKey

31 Mar 2021, 19:46

This will have the AppsKey act as Esc if it's pressed again within 2 seconds, which allows you to press it again to dismiss the menu while allowing it to retain its usual function when pressed more than 2 seconds since it has last been pressed:

Code: Select all

$AppsKey::
	if (A_PriorHotkey = "$AppsKey") && (A_TimeSincePriorHotkey < 2000)
		Send, {Esc}
	else
		Send, {AppsKey}
return
Or more compact:

Code: Select all

$AppsKey::Send, % ((A_PriorHotkey = "$AppsKey") && (A_TimeSincePriorHotkey < 2000)) ? "{Esc}" : "{AppsKey}"
Renfro
Posts: 64
Joined: 15 Oct 2020, 10:19

Re: Toggle AppsKey

31 Mar 2021, 23:20

Thanks, but is there a way to do this based on key state instead of using a timeout?

I'd rather not use a timeout approach because it affects how quickly you can re-engage the key as well as disengage it. If you double-click accidentally then you can't just press again to activate Appskey, you have to wait for 2 seconds to switch it on (as well as off).

On a normal toggle key you can just press on and off as much as you like with no time restriction.
User avatar
boiler
Posts: 16949
Joined: 21 Dec 2014, 02:44

Re: Toggle AppsKey

01 Apr 2021, 00:00

A true toggle would make every other press to be AppsKey or Esc. Like it toggled back and forth each time no matter what. But is that really how you would want it to operate? What if you purposely press the AppsKey, and it acts as an AppsKey but now is toggled to act as an Esc key next time. Then next time you try to purposely press the AppsKey, you would have to press it twice because the first time it would act as Esc.

Here it is where it simply toggles between the two with no delay before you can use it again but always as the opposite of the last press. There is an indicator that lasts for a second, but that doesn't slow it down if you immediately want to do the other. See what happens when you want to do purposely pressed AppsKey presses in a row. Make sure to try it with at least a couple purposely pressed AppsKey presses in a row. Now the toggled Esc just gets in the way.

Code: Select all

$AppsKey::Send, % AppsEscToggle()

AppsEscToggle() {
	static toggle
	ToolTip, % key := (toggle := !toggle) ? "AppsKey" : "Esc"
	SetTimer, ToolTipOff, -1000
	return "{" key "}"

	ToolTipOff:
		ToolTip
	return
}
Renfro
Posts: 64
Joined: 15 Oct 2020, 10:19

Re: Toggle AppsKey

15 Apr 2021, 11:21

Thank you very much for your explanation and for the code sample.

I think part of my problem is that I'm not doing a very good job of explaining what I want to achieve. I'm totally unfamiliar with coding, so I tend to phrase things in terms of simple observable outcomes rather than logically setting out how the action should operate, under what circumstances, and when (or whether) there should be any exceptions to the rule. Determining possible unintended consequences beforehand is not easy for a beginner.

In your latest code example, the toggling action works exactly as I want it to when nothing else is selected (i.e. no menu option was chosen from the Appskey context menu), no other key was pressed in between Appskey presses, and no other key was pressed while Appskey was being held down (required because I use some code that allows the use of Appskey as a modifier key under certain circumstances).

So, thanks to your real-world code example, perhaps a clearer explanation of what I'm trying to achieve (although I may still be missing something out) would be something like this ...

Your existing toggle code (that you provided in the post above) should only activate if the following are not true:

1. Another key is pressed while Appskey is being held down (i.e. Appskey is being used as a modifier key)
2. Another key was pressed after Appskey was last pressed and released (i.e. the key prior to current Appskey press was not Appskey)
3. Something from the Appskey context menu was selected by mouse (i.e. a mouse button was clicked prior to current Appskey press)

If any of those three things above does occur, then the toggle function should not happen. Or, to put it another way, the toggle happens only if Appskey is pressed two times in a row with no other key press or mouse click in between, and no other key held down at the same time as Appskey.

I guess the mouse-click part does not need to be specific to clicking on the Appskey context menu; clicking the mouse anywhere should be sufficient reason to cancel the toggle.

I have a vague idea how these exceptions could be achieved individually by using things like KeyWait, A_PriorKey (or maybe even something like this) and by using mouse-click detection, but I wouldn't know how to combine them without things breaking, or whether it's even possible to do so.

It does seem as if it should be possible, but then again I'm not sure of the unintended consequences that may arise when these rules interact with each other.

Hopefully the above is a bit clearer.
User avatar
boiler
Posts: 16949
Joined: 21 Dec 2014, 02:44

Re: Toggle AppsKey

15 Apr 2021, 12:16

My view on each of the critera:
Renfro wrote: 1. Another key is pressed while Appskey is being held down (i.e. Appskey is being used as a modifier key)
Difficult to accomplish. Would have to monitor for any other keystrokes from the time the Apps key is pressed down until when it's released.

Renfro wrote: 2. Another key was pressed after Appskey was last pressed and released (i.e. the key prior to current Appskey press was not Appskey)
Also difficult to accomplish as you would again have to monitor all keystrokes.

Renfro wrote: 3. Something from the Appskey context menu was selected by mouse (i.e. a mouse button was clicked prior to current Appskey press)
Not too difficult as both Apps key and mouse button clicks could be monitored by setting them as hotkeys. In the case of the mouse button hotkey, the associated subroutine would only note that it was pressed (resetting the variable that captures this event occurring since the last Apps keypress) and pass through the click itself.


In summary, the problem becomes monitoring all the potential keypresses that could occur at all times. Perhaps someone else knows a good way of doing so without being disruptive to your regular use of the keyboard and mouse, especially the keyboard, by causing a lag in typing and requiring a lot of code.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Panaku, Rohwedder, roysubs and 307 guests