Strange issue with key remapping WASD keys.

Ask gaming related questions (AHK v1.1 and older)
User avatar
Shadrach
Posts: 18
Joined: 18 Nov 2017, 08:02

Strange issue with key remapping WASD keys.

19 Nov 2017, 15:11

Hi,
relative AHK newbie here, but I know my way around the docs and have made a simple script to remap WASD keys and some others in a game.

The script is below.

It worked fine testing earlier, but now the A key for some reason locks to full, i.e. it doesn't register key release and scrolls to the left continuously.

I think the issue is my rebind of Shift+A to 'itself' - I had to do this since otherwise it would be Shift+LeftArrow obviously.
When commenting this map out or changing it to Shift+Ctrl+A it works but it's not what I want and Shift+A worked earlier... :shock:

Any ideas?

Script:

Code: Select all

#If WinActive("The Operational Art of War") and WinActive("ahk_exe Opart 4.exe")

w::Up
a::Left
s::Down
d::Right
+w::w       ;Shift+W, Weather Report
^a::a       ;Ctrl+A, Air Unit Report
+a::+a      ;Shift+A, Air Briefing
+d::d       ;Shift+D, Dig In
x::Numpad5	;X, Center map on unit
q::u        ;U, Unit Report
e::p        ;E, Plan Attack
+e::e       ;Shift+E, End Turn

#IfWinActive
Last edited by Shadrach on 19 Nov 2017, 15:41, edited 1 time in total.
User avatar
Shadrach
Posts: 18
Joined: 18 Nov 2017, 08:02

Re: Strange issue with keyremaps and monitors

19 Nov 2017, 15:38

Ok so tested on other original monitor, and now it doesn't work there either - so now I am maybe even more confused... edited the first post to reflect this.
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Strange issue with key remapping WASD keys.

20 Nov 2017, 12:21

I think the issue is my rebind of Shift+A to 'itself' - I had to do this since otherwise it would be Shift+LeftArrow obviously.
I think you have misunderstood how AHK hotkeys work. It will always fire the "longest" hotkey before "shorter" hotkeys

Code: Select all

a::
	MsgBox YOU HIT A
	return

+a::
	MsgBox YOU HIT SHIFT A
	return
Are you trying to make it so that the a::Left binding still works if shift is held?

To do that:
*a::Left
However, this suffers from the issue that if you hold shift and hit A, then AHK will RELEASE shift, send lowercase a, then RE-HOLD shift.

To avoid this:

Code: Select all

*a::
	Send {Blind}{Left down}
	return

*a up::
	Send {Blind}{Left up}
	return
User avatar
Shadrach
Posts: 18
Joined: 18 Nov 2017, 08:02

Re: Strange issue with key remapping WASD keys.

20 Nov 2017, 13:45

Hey thanks for the reply!
I think you have misunderstood how AHK hotkeys work. It will always fire the "longest" hotkey before "shorter" hotkeys
Well, I am a total nub to this, I admit. Not actually sure what you mean by the above, by 'longest' you mean the shifted one right?
Your code example makes total sense, that's what I would expect to happen.

However for the Remap code it seemed to cause strange issues.

Like I described above, when I used the remap syntax so like this:

Code: Select all

a::Left
+a::+a
It would scroll constantly to the left when just holding A... I found it somehow seemed to matter what *order* the keys were mapped in the script - which seemed to me to be very strange - order of the mappings should not matter right?

And stranger, I could for instance comment out +e::e and magically the script would work as expected again :eh: Either there is something strange with the application and how it does things, or my understanding of this is seriously flawed. Probably the latter :D
Are you trying to make it so that the a::Left binding still works if shift is held?
Actually the opposite, I would prefer Shift+A to still work like before, but just A to send a LeftArrow - while held down. However with the remap function it seemed I had to remap the shifted keys too.
To avoid this:
Basically the code you quote below here is the code from the remap documentation right? I tried to avoid this by using the remap shorthand which apparently uses the same syntax with the {Blind} keyword in the background, which I've not really understood yet.

So I decided to move away from the Remap code and do it the long-winded way, and for the WASD-keys I have this:

Code: Select all

w::
   Send,{Up down}
   KeyWait, w
   Send,{Up up}
   Return
I need the extra logic there to make the scrolling work, it seems? While for the regular remaps I have this simpler version:

Code: Select all

+a:: ;Shift+A - Air Unit Report
   Send a 
   Return
It works fine now, but seems a lot less elegant than using the Remap functions, which would be preferable.

But I really don't want to 'hard' remap the keys, I want to just send different keys when pressed or held down, while still retaining the keys for Shift or Ctrl.

Maybe I'm just going about this in a strange and convoluted way, so any tips or pointers from those with experience appreciated :salute:
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Strange issue with key remapping WASD keys.

20 Nov 2017, 14:06

Actually the opposite, I would prefer Shift+A to still work like before, but just A to send a LeftArrow - while held down. However with the remap function it seemed I had to remap the shifted keys too
a:: triggers if A is held, it will NOT trigger if you hold shift and hit a.

What is possibly happening is your Send commands are triggering your hotkeys.
for example, this code suffers from this issue if you hold Shift and hit A

Code: Select all

a::Left
+a:: ;Shift+A - Air Unit Report
   Send a 	; Triggers the a:: hotkey, because it is not prefixed by $
   Return
Shift+A sends A, which then triggers the A:: hotkey.
To stop this, do (Notice the $ before A::):

Code: Select all

$a::Left
+a:: ;Shift+A - Air Unit Report
   Send a  ; Does NOT trigger the a:: hotkey, as it is prefixed by $
   Return
User avatar
Shadrach
Posts: 18
Joined: 18 Nov 2017, 08:02

Re: Strange issue with key remapping WASD keys.

20 Nov 2017, 15:14

Thanks - Ok so I had a look at the docs at:
https://autohotkey.com/docs/Hotkeys.htm

According to it:
"This is usually only necessary if the script uses the Send command to send the keys that comprise the hotkey itself, which might otherwise cause it to trigger itself."

Fine, so by that logic, I should use $ to prefix the keys where I use a hotkey to send the same key, right? So I should prefix the shifted (Ctrl/Shift) keys.

But first I wanted to test from the example you gave:

Code: Select all

$w::Up
$a::Left
$s::Down
$d::Right
; Other keys
+w::w       ;Shift+W, Weather Report
+a::+a      ;Shift+A, Air Briefing
^a::a       ;Ctrl+A, Air Unit Report
+d::d       ;Shift+D, Dig In
It works fine - but apparently this also works without the $... So the other way around then, according to the docs:

Code: Select all

w::Up
a::Left
s::Down
d::Right
; Other keys
$+w::w       ;Shift+W, Weather Report
$+a::+a      ;Shift+A, Air Briefing
$^a::a       ;Ctrl+A, Air Unit Report
$+d::d       ;Shift+D, Dig In
Also works fine. But this was only a small test, I want to add more keys to the end:

Code: Select all

x::Numpad5  ;X, Center map on unit
q::u        ;Q, Unit Report
e::n        ;E, Next Unit
+e::-       ;Shift+E, Previous unit
$^e::e       ;Ctrl+E, End Turn
Space::p    ;Space, Plan Attack
v::Space    ;V, Toggle view units
Notice I've also put $ in front of the ^e mapping since it calls itself.

This breaks the script... :(

Why would all the other keys I added make the script break, when they are in no way related to A?

A is the only key behaving like this, so it's definitely this line below, but without the other lines it work?

Code: Select all

$+a::+a      ;Shift+A, Air Briefing
Looking in the script window it seems to behave just like I would expect it to, but in the game, it acts like I'm holding A down even after I release it.

Code: Select all

016: SetKeyDelay,-1
016: Send,{Blind}{Left DownTemp}
016: Return (0.11)
021: SetKeyDelay,-1
021: Send,{Blind}{a Up}
021: Return (2.08)
I am attaching the full script, including at the bottom, my non-Remap way of doing it, which actually works (for what that's worth)...
TOAW4.ahk
(2.33 KiB) Downloaded 37 times
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Strange issue with key remapping WASD keys.

20 Nov 2017, 16:03

Surely ^e::e should not trigger itself?

If you Send e while ctrl is held, then AHK will release ctrl, then send e, then re-hold ctrl. Blind mode turns off this behaviour, and would cause ^e to effectively be sent
c]^e::^e[/c] or ^e::Send {Blind}{e} would self-trigger.

Still not sure why this does not self-trigger though.

Code: Select all

w::Up
$+w::w       ;Shift+W, Weather Report
$ actually means "Use Hooks" - hotkeys not self-triggering is a side-effect of this.
I am not 100% on this, but maybe if you use the $ prefix for a hotkey once in a script, all hotkeys use the hook, and are thus immune to self-triggering.
User avatar
Shadrach
Posts: 18
Joined: 18 Nov 2017, 08:02

Re: Strange issue with key remapping WASD keys.

20 Nov 2017, 17:35

Well, I'm truly confused, either it's a bug in AHK (it's possible...) or I am doing something wonky.

Maybe, a theory, is that the mapping of Arrow Keys is a special case, maybe because for instance the Shift+Arrow function of selecting text?
In fact, I did a test: I removed the #IfWinActive part so it would apply anywhere. Then I tested in Notepad, and for instance the Ctrl+E button made 'n' so that's definitely a double-mapping, and Shift+W moved the cursor Up and selected text. Then I mapped #IfWinActive to only respond to Notepad.exe - and suddenly all keys behaved as expected. Mindblowing :wtf:

I figure possibly it's a bad idea to combine remapping of the Arrow Keys with all those other remappings, causing weird unexplainable behavior.

So what I have now is:

Code: Select all

#IfWinActive ahk_exe Opart 4.exe

; Suspend: Pause
Pause::Suspend

;WASD KEYS
w::Up
a::Left
s::Down
d::Right

; Other remappings
+w:: ; Shift+W - Weather Report
   Send w
   Return
+a:: ;Shift+A - Air Unit Report
   Send a 
   Return
^a:: ;Ctrl+A - Air Briefing
   Send +a
   Return
+d:: ;Shift+D - Dig In
   Send d
   Return
x:: ;X - Center map on unit
   Send {NumPad5}
   Return
q:: ;Q - Unit Report
   Send u
   Return
e:: ;E - Next Unit
   Send n
   Return
+e:: ;Shift+E - Previous unit
   Send -
   Return
^e:: ;Ctrl+E - End Turn
   Send e
   Return
Space:: ;Space - Plan Attack
   Send p
   Return
v:: ;V - Toggle view units
   Send {Space}
   Return

#IfWinActive

This code actually works fine, at least in the game for my use, and that's the point I think. And I avoided the 'hack' of using Send and KeyWait to emulate the same thing that a remapping should do.

I'd be happy if anyone, you or others could try this out, for instance in Notepad and see if you see the same - Like try to remove the #IfWinActive and see if behavior changes?
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Strange issue with key remapping WASD keys.

20 Nov 2017, 17:51

In that script, the Send w in the +w:: hotkey definitely triggers the w::Up hotkey
Note how if you hold shift and hit w, the cursor moves up a line.

Just add #InstallKeybdHook to the start of the script.

https://autohotkey.com/docs/commands/_I ... bdHook.htm
AutoHotkey does not install the keyboard and mouse hooks unconditionally because together they consume at least 500 KB of memory. Therefore, the keyboard hook is normally installed only when the script contains one of the following: 1) hotstrings; 2) one or more hotkeys that require the keyboard hook
So it looks like I was probably right. Using $ for one hotkey installs the hook, which makes all hotkeys use the hook, so even if you put the prefix on the triggerING hotkey instead of the triggerED hotkey, it has the same effect.
Rather than bothering to prefix all your hotkeys, just use the # directive
User avatar
Shadrach
Posts: 18
Joined: 18 Nov 2017, 08:02

Re: Strange issue with key remapping WASD keys.

20 Nov 2017, 18:29

Thanks, I think we're getting somewhere :bravo:

But it does look like it isn't #InstallKeybdHook which is the trick but #UseHook:
https://autohotkey.com/docs/commands/_UseHook.htm

I have no idea on the difference between the two, in fact it would seem they do the same thing, but obviously not. Another quirk of this strange system I guess :D

So you are definitely right that it's the keys overriding each other. Without the hook, Ctrl+E would give 'n' instead of 'e' like I want it to, and Shift+W would move up and select text, i.e. Shift+UpArrow.

But there's more to it: The #IfWinActive is definitely involved somehow.

Because *without* the UseHook, but with #IfWinActive, for instance this:

Code: Select all

#IfWinActive ahk_exe notepad.exe
Then things work in notepad. With no #IfWinActive directive, it start behaving strangely again.

I have not been able to replicate the 'held down' A key in for instance Notepad or other applications, so the game does something as well maybe?

But in effect, setting #UseHook on makes the hook active and saves me having to set $'s in front of every key that might trigger itself twice.

Would be interesting to test this with the original script...

Thanks a lot so far, for great success!

Return to “Gaming Help (v1)”

Who is online

Users browsing this forum: No registered users and 53 guests