Global "anykey" hotkey for raw processing Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
sirksel
Posts: 222
Joined: 12 Nov 2013, 23:48

Global "anykey" hotkey for raw processing

07 Oct 2016, 12:37

I'm prototyping input for an app that requires chorded input with non-standard modifiers -- literally hundreds of chords.

Because this experiment involves sometimes pressing two or three or four LETTER keys down simultaneously or near-simultaneously, my initial tests with the X & Y:: method of custom modifiers results in a lot of misfires during fast typing. It also creates a lot of key-state-checking overhead to find the second, third, etc. modifiers, since they are not the usual ones and there are literally hundreds of modifier possibilities (basically, any other keys). I think I'm going to have to literally record timestamps of key-up and key-down events and compare them with certain tolerances, key-down orders, etc. to determine whether a particular sequence is in fact a chord, or just rapid typing.

My proposed solution is to use an "anykey down or up global hotstring" (or the best approximation thereof), log the key down and key up event time in an object. On the side, I'd keep a collection of (a) currently-down keys and (b) recently-down-but-now-up keys mapped back to the object with timestamps -- and then do some quick comparisons to see whether the last key event was a chord or a letter. I'll then pass the name of the determined chord or letter to a keyed-object {unique_chord_string : function_object, ...} and let that determine what to do with the key event.

I know you all are busy, but I'm hoping someone could give me pointers on two topics:

1. Global AnyKey Hotkey. In my search of the forums, I've seen lots of requests for a way to do a global anykey hotkey. In many cases, it's because people want to manage something offline that could be managed better by AHK. In my case, because I have to check millisecond tolerances of both key-up and key-down events to determine the difference between fast typing and slightly non-simultaneous chording, I don't think I have a choice. Is there a global anykey hotkey, apart from stacking labels or looping a hotkey command to auto-create the labels? I've seen someone recommend using Input but I'm thinking that won't work because I have to log key UP and down events to compare timestamps, and I'd also prefer not to have anything looping/racing when the keyboard is otherwise idle. Any suggestions?

2. Raw Access to Key List. Is there any undocumented or raw programmatic access to the key list, which it appears AHK is already creating for itself? That might be better and more efficient than logging a bunch of ups/downs that have already been logged. I know you can see the last hotkey and the prior hotkey, but is there something with more history than that?

In case it helps, I'm writing this in v2, but any advice would be appreciated, either from v1 or v2 experts... Thanks!
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Global "anykey" hotkey for raw processing

07 Oct 2016, 14:55

I'm not sure I get what your asking here, but if you're interested in something like hotkeys of type a & b & c &... I have made such a script (class actually) but it has not been very well tested, initial testing seemed fine though. If you want to try it out I'll be happy to send it to you. I did lose interest and motivation to finish it properly. Anyhow, I might not have access to my computer for a while, so if you are in a hurry you'll have to hope that someone else here helps you out. Cheers.
User avatar
Exaskryz
Posts: 2882
Joined: 17 Oct 2015, 20:28

Re: Global "anykey" hotkey for raw processing

07 Oct 2016, 15:31

You talk about chording, and how that is different from normal typing. It may be helpful to explain what chording is and how that differs from normal typing for people to give you an idea.

You already seemed to have rejected my idea where you create all hotkeys. The first code block is below in case someone stumbles on this topic and likes that idea anyhow. If you come to accept it, I would suggest recording the time goes down (in a variable?) and then getting the time when the key is released after a KeyWait. The trouble is with threading though, as I'm not sure how pressing 4 hotkeys down and releasing them affects how the KeyWait is done. In other words, if I press ABCD all down but release in the order ABCD, because the D hotkey may have interrupted the C hotkey, which may have interrupted the B hotkey, which may have interrupted the A hotkey, AHK may not detect my release of the A, B, and C keys until my D key is released and the chain of interruption is undone. Hmm, it seems that keywait alone is not enough because of the issue I expected with threading (though I couldn't get a rhyme or reason to it in my testing; probably a poor testing method). But the second code block demonstrates a proof of concept for timing keystrokes.

Code: Select all

#Persistent
Loop, 255
Hotkey, % "~" Format("vk{:x}",A_Index), pressed, On
return

pressed:
Tooltip % "You pressed "  GetKeyName(SubStr(A_ThisHotkey,2))
return

Code: Select all

a::
b::
c::
d::
time_down_%A_thishotkey%:=A_TickCount
KeyWAit, %A_ThisHotkey%
return

a up::
b up::
c up::
d up::
prefix:=SubStr(A_ThisHotkey,1,-3)
Tooltip % A_TickCount-time_down_%prefix%
return
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Global "anykey" hotkey for raw processing

08 Oct 2016, 05:09

Exaskryz wrote:getting the time when the key is released after a KeyWait. The trouble is with threading though, as I'm not sure how pressing 4 hotkeys down and releasing them affects how the KeyWait is done.
The main idea of my multi-key hotkey Implementation is very simple, the down events of the keys adds a point for the sequence, any up event puts the score back to zero. Then, on full score, call some function. No timing, getkeystate or keywaiting required. It's just a matter of organising it.
sirksel
Posts: 222
Joined: 12 Nov 2013, 23:48

Re: Global "anykey" hotkey for raw processing

08 Oct 2016, 06:33

Thank you both for the thoughts on this topic. I was kind of hoping there was some undocumented view into the key events processed under the hood. Absent that, your thought Exaskryz, about stacking labels was the best that I had come up with too. I'm basically implementing something very close to what you propose, but as Helgef points out, without the keywait line.

I'm still polishing the code, but the way I've got it working now is as follows... the firing of the keydown events store a tickcount in the timedown[key] place in the object, but only if it didn't previously exist. When the key up event comes, the delta is calculated and the object key is removed, allowing for recording time down for a future key down of that key. Basically, I have to protect against the repetitive fires of the keydown event while a key is being held down, but without using keywait. The checking for the blank object element seems to do the trick for that... at least so far.

Thank you both again for your help!
sirksel
Posts: 222
Joined: 12 Nov 2013, 23:48

Re: Global "anykey" hotkey for raw processing  Topic is solved

10 Oct 2016, 03:17

Lexikos, if you read this, is there any undocumented programmatic access to the key list that one can see in the "Ctrl-K List" in the AHK window? I've implemented a solution to my particular chorded-input problem (assisted by the kind folks above in this post) that logs a lot info that duplicates whatever is already in that key list data structure... Is there any way to read the key list already tracked by AHK? If not, no big deal, but I was hoping there might be some little-known way to access it... Thanks!

Btw... I'm talking about this list:

Code: Select all

VK  SC	Type	Up/Dn	Elapsed	Key		Window
-------------------------------------------------------------------------------------------------------------
72  03D	 	u	0.08	F3             	
A2  01D	 	d	5.66	LControl       	
46  021	 	d	0.11	f              	
46  021	 	u	0.11	f              	Find and Replace
A2  01D	 	u	0.89	LControl       	
1B  001	 	d	0.22	Escape         	
1B  001	 	u	0.06	Escape         	Microsoft Excel
lexikos
Posts: 9621
Joined: 30 Sep 2013, 04:07
Contact:

Re: Global "anykey" hotkey for raw processing

10 Oct 2016, 21:55

See ScriptInfo().

Altenratively: Most of the information in the KeyHistory entries comes from the keyboard hook. You can install your own (SetWindowsHookEx, WH_KEYBOARD_LL) and use GetKeyName to get the key names.
sirksel
Posts: 222
Joined: 12 Nov 2013, 23:48

Re: Global "anykey" hotkey for raw processing

12 Oct 2016, 18:47

Thanks. ScriptInfo() is just what I was looking for but didn't find in my initial search. I appreciate the help, everyone!

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Google [Bot], RussF, ymnaren and 152 guests