User
User

Reputation: 53

Why " Keywait " in Autohotkey cause two letters be replaced during typing?

I have this script:

#IfWinActive Oxford Advanced Learner's Dictionary
$m:: 
KeyWait,m,T0.25 
If (ErrorLevel) 
 {
    Click, 210,563, 10
    sleep,100
    Send, {Down}
    KeyWait,m 
 }
    Else
    {
        Send, m
    }        
return
 $i::
KeyWait, i, T0.25
If (ErrorLevel) {
    Loop 7
        Click, 768,192,3
} else {
    Send, i
}
return

But when I type the letters m and i fast to type " mi " it types " im " instead. but when I type them slower, no problem occurs. why this happens and How can I fix this issue?

Upvotes: 0

Views: 481

Answers (2)

User
User

Reputation: 53

I've find the following code here by the user " Rohwedder " on a forum of autohotkey site.

#IfWinActive Oxford Advanced Learner's Dictionary
~$m::
KeyWait,m,T0.25
If (ErrorLevel)
{
    Click, 210,563, 10
    sleep,100
    Send, {Down}
}
return
~$i::
KeyWait, i, T0.25
If (ErrorLevel)
    Loop 7
        Click, 768,192,3
return

It worked perfectly for me but I realized by writing the keywait in this way, when I hold for example m for few seconds unlike the script on my question it first type an "m" on the search bar, then do the functions I defined for it (clicking and sending down). so my first expression was trying to fix previous code as suggested in other answer by @Josh by using critical . but I had some issues with it too!

Finally I used the above code by a little adjustments: I added this

   sleep,50
   send,{backspace}

below each hotkey (at first lines inside if) so the result is deleting extra letter that is made by holding a key immediately and then it did functions I defined for it instantly.

So the problem is solved !

Upvotes: 0

Lifeweaver
Lifeweaver

Reputation: 1042

I think this quote from the Threads page is relevant here:

Although AutoHotkey doesn't actually use multiple threads, it simulates some of that behavior: If a second thread is started -- such as by pressing another hotkey while the previous is still running -- the current thread will be interrupted (temporarily halted) to allow the new thread to become current. If a third thread is started while the second is still running, both the second and first will be in a dormant state, and so on.

When the current thread finishes, the one most recently interrupted will be resumed, and so on, until all the threads finally finish.

I believe when you type i after m, in a quick manner while the m keywait is still inside the timeout, it pauses that keywait and runs i's.

As to how to fix this, merely add Critical in the m hotkey, note this will make it so no other hotkey will run before this one is done, it will however queue things up:

#IfWinActive Oxford Advanced Learner's Dictionary
$m::
Critical
KeyWait,m,T0.25 
If (ErrorLevel) 
{
    Click, 210,563, 10
    sleep,100
    Send, {Down}
    KeyWait,m 
} else {
    Send, m
}        
return

$i::
KeyWait, i, T0.25
If (ErrorLevel) {
    Loop 7
        Click, 768,192,3
} else {
    Send, i
}
return

Upvotes: 2

Related Questions