While AutoHotkey is collecting input for either the Input command or hotstring detection, it uses
ToAsciiEx or
ToUnicodeEx to convert each keystroke to the appropriate character. These functions handle dead keys, but they do so in a way that interferes with regular keyboard input. AutoHotkey worked around this by re-sending the dead key when the second key in the sequences is about to be passed on to the system. However, as you've found, this did not work correctly when multiple scripts are involved.
I believe I've solved the problem with
v1.1.02. While searching for a solution I found many other people asking the same question with no direct answer, so I'm posting these comments from the source code "out here in the open" in the hopes it may help someone in the future:
Quote:
SUMMARY OF DEAD KEY ISSUE:
Calling ToAsciiEx() on the dead key itself doesn't disrupt anything. The disruption occurs on the next key
(for which the dead key is pending): ToAsciiEx() consumes previous/pending dead key, which causes the
active window's call of ToAsciiEx() to fail to see a dead key. So unless the program reinserts the dead key
after the call to ToAsciiEx() but before allowing the dead key's successor key to pass through to the
active window, that window would see a non-diacritic like "u" instead of û. In other words, the program
"uses up" the dead key to populate its own hotstring buffer, depriving the active window of the dead key.
...
Lexikos: Testing shows that calling ToUnicodeEx with the VK/SC of a dead key
acts the same as actually pressing that key. Calling it once when there is
no pending dead key places the dead key in the keyboard layout's buffer and
returns -1; calling it again consumes the dead key and returns either 1 or 2,
depending on the keyboard layout. For instance:
- Passing vkC0 twice with US-International gives the string "``".
- Passing vkBA twice with Neo2 gives just the combining version of "^".
Normally ToUnicodeEx would be called by the active window (after the hook
returns), thus placing the dead key in the buffer. Since our call above
has already done that, we need to remove the dead key from the buffer
before returning. [...]
[Call ToUnicodeEx again with the same parameters.]
...
Since our call to ToUnicodeOrAsciiEx above has removed the pending dead key from the
buffer, we need to put it back for the active window or the next hook in the chain:
[Call ToUnicodeEx with the original dead key VK/SC.]