Page 1 of 1
Remapping Alt key is unreliable
Posted: 07 Sep 2023, 11:43
by Federhalter
I use the following script with RAlt as a dead key to type accented letters on a US keyboard. This works, but often, especially when typing fast, in Windows Notepad, the menu is opened. So it seems the Alt key event masking fails sometimes.
Code: Select all
#Requires AutoHotkey v2.0.7+
#Warn All
KeyHistory 500
#SingleInstance Force
Persistent
A_MaxHotkeysPerInterval := 200
;SendMode "Event"
A_MenuMaskKey := "vkE8"
Umlaut := 0
return
#UseHook
#HotIf (Umlaut == 1)
o::
{
global Umlaut
SendText "ö"
Umlaut := 0
}
u::
{
global Umlaut
SendText "ü"
Umlaut := 0
}
#HotIf
RAlt::
{
global Umlaut
Umlaut := 1
}
~*Esc:: ExitApp
If this occurs, the log of the script shows some ignored (i) events of the A_MenuMaskKey and RAlt, which seems unusual.
Code: Select all
VK SC Type Up/Dn Elapsed Key Window
-------------------------------------------------------------------------------------------------------------
...
A5 138 h d 0.09 RAlt
4F 018 h d 0.02 o
4F 018 s u 0.09 o
55 016 u 0.00 u
A5 138 s u 0.01 RAlt
A5 138 h d 0.06 RAlt
55 016 h d 0.01 u
4F 018 h d 0.00 o
55 016 s u 0.52 u
E7 00FC U d 0.00 ü
E8 000 i d 0.00 not found
E8 000 i u 0.00 not found
A5 138 i u 0.00 RAlt
E8 000 i d 0.00 not found
A5 138 i d 0.00 RAlt
E8 000 i u 0.00 not found
55 016 u 0.06 u
4F 018 s u 0.00 o
A5 138 s u 0.02 RAlt
A5 138 h d 0.08 RAlt
4F 018 d 0.00 o
55 016 d 0.02 u
4F 018 u 0.08 o
55 016 u 0.02 u
A5 138 s u 0.01 RAlt
...
What is also strange, the script works much more reliable if a second script has a keyboard hook installed, e.g. if the following script is run concurrently, the problem almost never happens:
Code: Select all
#Requires AutoHotkey v2.0.7+
KeyHistory 500
#SingleInstance force
#Warn All
InstallKeybdHook
#UseHook
Persistent
~*Esc:: ExitApp
I would rather accept a certain delay in typing than the current, unreliable, behaviour.
Also,
SendMode "Event" did not solve the problem.
Re: Remapping Alt key is unreliable
Posted: 10 Sep 2023, 06:58
by lexikos
RAlt::Ctrl is "
remapping" RAlt.
RAlt:: is just a hotkey which blocks RAlt
when not modified by any other modifier key.
What happens if you use
*RAlt::?
Re: Remapping Alt key is unreliable
Posted: 11 Sep 2023, 05:47
by lexikos
The timing in the KeyHistory indicates that the "i" events are being sent by SendText "ü". If you insert a short sleep (perhaps >= 20) after SendText "ü" and the subsequent "i" event still shows 0.00, that would more or less confirm it.
I can't see the reason that these events are sent, though, and can't reproduce it.
Re: Remapping Alt key is unreliable
Posted: 11 Sep 2023, 15:32
by Federhalter
It seems I was somewhat wrong about the problem. It is not related to the Alt key at all, but to two keys being pressed in very quick succession.
The following fails very often (on an old & slow i5 machine). I can provoke it by pressing 3 and 4 at the same time very quickly.
Code: Select all
#Requires AutoHotkey v2.0.7+
#Warn All
KeyHistory 500
#SingleInstance Force
Persistent
A_MaxHotkeysPerInterval := 200
;SendMode "Event"
return
#UseHook
3::
{
Send "1"
Sleep 20
}
4::
{
Send "2"
Sleep 20
}
~*Esc:: ExitApp
In a Notepad window by pressing 3 and 4, I got:
2112232321141212
The 3 3 4 characters shouldn't be there!
The log is:
Code: Select all
VK SC Type Up/Dn Elapsed Key Window
-------------------------------------------------------------------------------------------------------------
34 005 h d 6.64 4 Unbenannt - Editor
32 003 i d 0.00 2
32 003 i u 0.00 2
33 004 h d 0.05 3
31 002 i d 0.00 1
31 002 i u 0.00 1
34 005 s u 0.06 4
33 004 s u 0.01 3
33 004 h d 0.09 3
31 002 i d 0.00 1
31 002 i u 0.00 1
34 005 h d 0.03 4
32 003 i d 0.00 2
32 003 i u 0.00 2
33 004 s u 0.05 3
34 005 s u 0.00 4
34 005 h d 0.11 4
32 003 i d 0.00 2
32 003 i u 0.00 2
34 005 s u 0.05 4
33 004 u 0.00 3
34 005 h d 0.11 4
32 003 i d 0.00 2
32 003 i u 0.00 2
33 004 u 0.05 3
34 005 s u 0.00 4
34 005 h d 0.11 4
32 003 i d 0.00 2
32 003 i u 0.00 2
33 004 h d 0.02 3
31 002 i d 0.00 1
31 002 i u 0.00 1
34 005 s u 0.03 4
33 004 s u 0.00 3
33 004 h d 0.09 3
31 002 i d 0.00 1
31 002 i u 0.00 1
34 005 u 0.05 4
33 004 s u 0.00 3
33 004 h d 0.12 3
34 005 h d 0.00 4
31 002 i d 0.00 1
31 002 i u 0.00 1
32 003 i d 0.02 2
32 003 i u 0.00 2
34 005 s u 0.03 4
33 004 s u 0.00 3
33 004 h d 0.11 3
34 005 h d 0.00 4
31 002 i d 0.00 1
31 002 i u 0.00 1
32 003 i d 0.01 2
32 003 i u 0.00 2
34 005 s u 0.02 4
33 004 s u 0.00 3
Press [F5] to refresh.
There are three entries with no type (3 3 4) which seem to correlate to the failures.
And, if I add SendMode "Event", the problem disappears!
Re: Remapping Alt key is unreliable
Posted: 11 Sep 2023, 21:42
by lexikos
This is by design. SendInput is reliable only if there are no keyboard hooks installed. If there are no other scripts with keyboard hooks running, it will automatically deactivate the script's keyboard hook while the keys are sent. Any user input that is buffered by the system during this are fully handled before the system returns control to AutoHotkey. Only registered ("reg" method) hotkeys work while the hook is inactive.
If you have another script with a keyboard hook, SendInput will fall back to SendEvent.
If a script other than the one executing SendInput has a low-level keyboard hook installed, SendInput automatically reverts to SendEvent (or SendPlay if SendMode "InputThenPlay" is in effect). This is done because the presence of an external hook disables all of SendInput's advantages, making it inferior to both SendPlay and SendEvent. However, since SendInput is unable to detect a low-level hook in programs other than AutoHotkey v1.0.43+, it will not revert in these cases, making it less reliable than SendPlay/Event.
Re: Remapping Alt key is unreliable
Posted: 12 Sep 2023, 03:50
by Federhalter
lexikos wrote: ↑11 Sep 2023, 05:47
The timing in the KeyHistory indicates that the "i" events are being sent by
SendText "ü". If you insert a short sleep (perhaps >= 20) after
SendText "ü" and the subsequent "i" event still shows 0.00, that would more or less confirm it.
I can't see the reason that these events are sent, though, and can't reproduce it.
I reduced the script to reproduce the issue (pressing both RAlt and 1 very quickly and repeatedly) with US layout:
Code: Select all
#Requires AutoHotkey v2.0.8+
#Warn All
KeyHistory 500
#SingleInstance Force
Persistent
A_MaxHotkeysPerInterval := 200
SendMode "Event"
A_MenuMaskKey := "vkE8"
return
1::
{
SendText "ö"
Sleep 20
}
*RAlt::
{
}
~*Esc:: ExitApp
Log:
Code: Select all
Type Off? Level Running Name
-------------------------------------------------------------------
reg 1
k-hook *RAlt
k-hook ~*Esc
Window: ...\test.ahk - AutoHotkey v2.0.8
Keybd hook: yes
Mouse hook: no
Enabled Timers: 0 of 0 ()
Interrupted threads: 0
Paused threads: 0 of 0 (0 layers)
Modifiers (GetKeyState() now) = RAlt
Modifiers (Hook's Logical) = RAlt
Modifiers (Hook's Physical) =
Prefix key is down: no
NOTE: To disable the key history shown below, call KeyHistory(0). The same method can be used to change the size of the history buffer. For example: KeyHistory 100 (Default is 40, Max is 500)
The oldest are listed first. VK=Virtual Key, SC=Scan Code, Elapsed=Seconds since the previous event. Types: h=Hook Hotkey, s=Suppressed (blocked), i=Ignored because it was generated by an AHK script, a=Artificial, #=Disabled via #HotIf, U=Unicode character (SendInput).
VK SC Type Up/Dn Elapsed Key Window
-------------------------------------------------------------------------------------------------------------
...
A5 138 h d 6.88 RAlt
31 002 d 0.03 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.02 ö
A5 138 s u 0.05 RAlt
31 002 u 0.05 1
A5 138 h d 0.05 RAlt
31 002 d 0.05 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
A5 138 s u 0.09 RAlt
31 002 u 0.00 1
A5 138 h d 0.06 RAlt
31 002 d 0.02 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
A5 138 s u 0.09 RAlt
31 002 u 0.00 1
A5 138 h d 0.05 RAlt
31 002 d 0.03 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
31 002 u 0.09 1
A5 138 s u 0.03 RAlt
A5 138 h d 0.01 RAlt
31 002 d 0.02 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
31 002 u 0.11 1
A5 138 s u 0.00 RAlt
A5 138 h d 0.05 RAlt
31 002 d 0.02 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
A5 138 s u 0.09 RAlt
31 002 u 0.01 1
A5 138 h d 0.05 RAlt
31 002 d 0.03 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
A5 138 s u 0.08 RAlt
31 002 u 0.00 1
A5 138 h d 0.05 RAlt
31 002 d 0.03 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
A5 138 s u 0.06 RAlt
31 002 u 0.03 1
A5 138 h d 0.05 RAlt
31 002 d 0.03 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
A5 138 s u 0.05 RAlt
31 002 u 0.06 1
A5 138 h d 0.00 RAlt
31 002 d 0.06 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
A5 138 s u 0.05 RAlt
31 002 u 0.03 1
A5 138 h d 0.03 RAlt
31 002 d 0.05 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
A5 138 s u 0.05 RAlt
31 002 u 0.06 1
A5 138 h d 0.00 RAlt
31 002 d 0.06 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
A5 138 s u 0.03 RAlt
31 002 u 0.06 1
A5 138 h d 0.09 RAlt
31 002 d 0.02 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
31 002 u 0.06 1
31 002 d 0.11 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
A5 138 s u 0.11 RAlt
31 002 u 0.00 1
A5 138 h d 0.02 RAlt
31 002 d 0.06 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
31 002 u 0.09 1
31 002 d 0.06 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
A5 138 s u 0.06 RAlt
31 002 u 0.03 1
A5 138 h d 0.02 RAlt
31 002 d 0.06 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
A5 138 s u 0.08 RAlt
A5 138 h d 0.02 RAlt
31 002 u 0.02 1
31 002 d 0.06 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
A5 138 s u 0.06 RAlt
31 002 u 0.03 1
A5 138 h d 0.03 RAlt
31 002 d 0.05 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
A5 138 s u 0.03 RAlt
31 002 u 0.05 1
A5 138 h d 0.03 RAlt
31 002 d 0.05 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
A5 138 s u 0.05 RAlt
31 002 u 0.05 1
A5 138 h d 0.03 RAlt
31 002 d 0.06 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
A5 138 s u 0.00 RAlt
31 002 u 0.09 1
A5 138 h d 0.00 RAlt
31 002 d 0.06 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
A5 138 s u 0.02 RAlt
A5 138 h d 0.06 RAlt
A5 138 s u 0.08 RAlt
A5 138 h d 0.06 RAlt
31 002 u 0.08 1
A5 138 s u 0.01 RAlt
31 002 d 0.03 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
A5 138 h d 0.05 RAlt
31 002 u 0.06 1
A5 138 s u 0.00 RAlt
31 002 d 0.06 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
A5 138 h d 0.03 RAlt
A5 138 s u 0.08 RAlt
31 002 u 0.00 1
31 002 d 0.09 1
E7 00F6 U d 0.00 ö
E7 00F6 U u 0.00 ö
A5 138 h d 0.00 RAlt
E8 000 i d 0.01 not found
A5 138 i d 0.00 RAlt
E8 000 i u 0.00 not found
A5 138 s u 0.06 RAlt
A5 138 h d 0.09 RAlt
31 002 u 0.03 1
A5 138 s u 0.03 RAlt
31 002 d 0.03 1
31 002 u 0.06 1
Press [F5] to refresh.
The "i" events is where the problem occurs ("stuck" RAlt key)
Re: Remapping Alt key is unreliable
Posted: 13 Sep 2023, 03:49
by Federhalter
My suspicion is that the keyboard hook becomes disabled for some reason here. When reading the following:
https://www.autohotkey.com/docs/v2/lib/Send.htm#Remarks
Characters vs. keys: By default, characters are sent by first translating them to keystrokes. If this translation is not possible (that is, if the current keyboard layout does not contain a key or key combination which produces that character), the character is sent by one of following fallback methods:
- SendEvent and SendInput use SendInput() with the KEYEVENTF_UNICODE flag.
- SendPlay uses the Alt+nnnnn method, which produces Unicode only if supported by the target application.
- ControlSend posts a WM_CHAR message.
The first case seems to suggest that "SendInput()" would be used. Is the keyboard hook disabled in this case?
The following is just as unreliable (even though it sends a keystroke for which a key exists with that character, so it should not revert to SendInput:
Using ControlSendText works reliably, but is not supported in all applications:
Code: Select all
3::
{
aWin := WinActive("A")
aCtrl := ControlGetFocus(aWin)
ControlSendText "ö", aCtrl, aWin
Sleep 20
}
Re: Remapping Alt key is unreliable
Posted: 13 Sep 2023, 21:56
by lexikos
No, the keyboard hook is temporarily deactivated only by SendInput or Send in SendInput mode, and only if it is not reverting to another mode.
When SendEvent uses SendInput() for individual characters, it does so one call at a time (and applies key delays), so there is no advantage to deactivating the hook (i.e. user input and sent input may be interspersed either way).
Re: Remapping Alt key is unreliable
Posted: 15 Sep 2023, 11:16
by Federhalter
Should I invest time in investigating this problem further, or is my expectation flawed?
My expectation is that it is possible to remap the Right Alt key reliably - and it seems to work fine when using ControlSendText. But a general solution to send characters which are not on the keyboard that works universally in all programs would be better.
Re: Remapping Alt key is unreliable
Posted: 15 Sep 2023, 18:00
by lexikos
I don't get it. It is not typical to have these issues.
Re: Remapping Alt key is unreliable
Posted: 23 Mar 2024, 01:09
by lexikos
This might have been fixed by v2.0.12.
Fixed Send erroneously releasing a modifier due to a race condition. For example, ~LAlt::Send "{Blind}x" intermittently released LAlt if some other keyboard hook was installed more recently than the script's own hook.