Repeating key presses with swapped modifier keys

Report problems with documented functionality
keith_y
Posts: 2
Joined: 04 Mar 2017, 01:24

Repeating key presses with swapped modifier keys

04 Mar 2017, 02:06

AutoHotkey 1.1.24.05
Windows 10

I used the following script to swap Win and Ctrl. I held LWin and pressed Left twice. I got Home and Left. I would expect to get Home twice.

Code: Select all

LWin::LCtrl
LCtrl::LWin
RWin::RCtrl
RCtrl::RWin
!Left::^Left
!Right::^Right
^Left::Send {Home}
^Right::Send {End}
Then I tested the following script. I held LWin and pressed Left twice. I only got one Home. It seemed that subsequent GetKeyState returned false.

Code: Select all

LWin::LCtrl
LCtrl::LWin
RWin::RCtrl
RCtrl::RWin

*Left::
if GetKeyState("Ctrl")
{
	SendInput {Home}
}
I tested the following script. I held LCtrl and pressed Left twice. I got two Home.

Code: Select all

*Left::
if GetKeyState("Ctrl")
{
	SendInput {Home}
}
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: Repeating key presses with swapped modifier keys

04 Mar 2017, 02:25

It is by design.
When a script is launched, each remapping is translated into a pair of hotkeys. For example, a script containing a::b actually contains the following two hotkeys instead:

Code: Select all

*a::
SetKeyDelay -1   ; If the destination key is a mouse button, SetMouseDelay is used instead.
Send {Blind}{b DownTemp}  ; DownTemp is like Down except that other Send commands in the script won't assume "b" should stay down during their Send.
return

*a up::
SetKeyDelay -1  ; See note below for why press-duration is not specified with either of these SetKeyDelays.
Send {Blind}{b Up}
return
Source: Remapping Keys and Buttons
Notice DownTemp.

Normally, Send {b Down} would cause subsequent Send commands to leave b down. So for instance, if b is Ctrl, Send {Home} would result in Ctrl+Home instead of just the expected Home. DownTemp is used to prevent this, so Send will automatically release the key before-hand, as it would if you were physically holding the key. However, because the key isn't physically down, Send doesn't restore it to the "pressed" state afterward. (Generally, if a key had been physically released during Send, it would be bad to automatically put it back in the pressed state.)

There are probably better ways to implement remapping, but this is what we have. I have no plan to improve on it, but anyone is welcome to try.
!Left::^Left
!Right::^Right
This is equivalent to the below, again by design (see {Blind} above).

Code: Select all

!Left::!^Left
!Right::!^Right
That's probably not what you want.
keith_y
Posts: 2
Joined: 04 Mar 2017, 01:24

Re: Repeating key presses with swapped modifier keys

20 Jun 2018, 06:01

The original code now works because of the introduction of DownR in 1.1.27

Code: Select all

LWin::LCtrl
LCtrl::LWin
RWin::RCtrl
RCtrl::RWin
!Left::^Left
!Right::^Right
^Left::Send {Home}
^Right::Send {End}
However, the following SendInput still produce the old result. Is it a feature or a bug? I can't find documents saying SendInput different from Send in this case.

Code: Select all

LWin::LCtrl
LCtrl::LWin
RWin::RCtrl
RCtrl::RWin
!Left::^Left
!Right::^Right
^Left::SendInput {Home}
^Right::SendInput {End}
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: Repeating key presses with swapped modifier keys

21 Jun 2018, 03:57

It's a bug and will be fixed in the next update.

SendInput and SendPlay use a different (simpler) code path for restoring modifiers than SendEvent, because all events for that call are determined at the beginning, before the user has any chance to interfere with the modifier state. DownR was only implemented for the SendEvent code path.

Return to “Bug Reports”

Who is online

Users browsing this forum: No registered users and 22 guests