AutoHotkey causing control key to get stuck
Asked Answered
A

6

11

I have several situations when my control key gets stuck, and it happens only when I have AutoHotkey running. This happens with multiple different modifier keys including the control (^), windows (#), and alt (!) keys.

Similar problems have been posted several times before: 1, 2, 3. Some solutions exists, and the one suggested here partially helped me (decreased the frequency of the problem), but the control key still gets stuck occasionally. Things I have tried include #InstallKeybdHook.

I have two questions:

  1. Is it possible to prevent this problem?
  2. Is there a good way to have AutoHotkey monitor when keys are stuck (eg automatically notice when keys have been held for >10s) and fix this as soon as it happens?

I have tried everything suggested above, and created my own version of a StuckKeyUp function (as suggested here):

StuckKeyUp(){
sleep 300 
send {<# up} 
send {># up} 
send {# up} 
send {+ up} 
send {<+ up} 
send {! up} 
send {<! up} 
send {>! up} 
send {^<^^>! up} 
send {^<^>! up} 
send {^ up} 
send {Ctrl down} 
send {Ctrl up}

Send {§ up}         
Send {Shift Up}
Send {LShift Up}
Send {RShift Up}
Send {Alt Up}
Send {LAlt Up}
Send {RAlt Up}
Send {Control Up}
Send {LControl Up}  
Send {<^ down}      
Send {<^ Up}        ; solves some issues, but not all
Send {>^ down}      
Send {>^ Up}        
Send {RControl Up}
Send {LControl Up}
Send {LWin Up}
Send {RWin Up}
sleep 100 
; reload, ; Avoid - Reloading AutoHotkey File causes functions depending on this function to break
return 
}
Alica answered 27/2, 2018 at 12:51 Comment(0)
B
4

As suggested in the other answers and in my original answer:

Among other debugging methods you can try

  • #HotkeyModifierTimeout affects the behavior of hotkey modifiers: Ctrl, Alt, Win, and Shift.

  • Install the keyboard hook by adding the line #InstallKeybdHook.

  • Use the SendInput method.

  • Put this code at specific positions in your script (within hotkey definitions that send the control key or in a timer) and look in the KeyHistory (after closing the message box) in which situations the key gets stuck:

If GetKeyState("Ctrl")           ; If the OS believes the key to be in (logical state),
{
    If !GetKeyState("Ctrl","P")  ; but the user isn't physically holding it down (physical state)
    {
        Send {Ctrl Up}
        MsgBox,,, Ctrl released
        KeyHistory
    }
}

To cover all modifier keys you can use

#Requires AutoHotkey v1.1

#NoEnv
#InstallKeybdHook
SendMode Input

Keys := "LControl,RControl,LAlt,RAlt,LWin,RWin,LShift,RShift"
SetTimer, ReleaseKeys, 500 

; ....

            RETURN   ; === end of auto-execute section ===


; Your hotkeys here

; ....

ReleaseKeys:
    Loop, parse, Keys, `,
    {
        If GetKeyState(A_LoopField)           ; If the OS believes the key to be in (logical state)
        {
            If !GetKeyState(A_LoopField,"P")  ; but the user isn't physically holding it down (physical state)
            {
                Send {%A_LoopField% Up}
                MsgBox,,, %A_LoopField% released
                KeyHistory
            }
        }
    }
Return
Buckingham answered 28/2, 2018 at 16:34 Comment(0)
I
3

I also had this problem (with only Ctrl ever getting stuck), and the fix for me was to use #MenuMaskKey at the top of the script:

;; Avoid Ctrl getting stuck in down state, even when not physically pressed:
#MenuMaskKey vkFF

Background info from https://www.autohotkey.com/docs/commands/_MenuMaskKey.htm

The mask key is sent automatically to prevent the Start menu or the active window's menu bar from activating at unexpected times.

The default mask key is Ctrl.

...

If the system was to detect only a Win or Alt keydown and keyup with no intervening keypress, it would usually activate a menu. To prevent this, the keyboard or mouse hook may automatically send the mask key.

Icebox answered 4/11, 2020 at 2:8 Comment(0)
G
2

I added #InstallKeybdHook and all was well. See below for details.

https://www.autohotkey.com/docs/commands/_HotkeyModifierTimeout.htm

Grous answered 28/8, 2019 at 18:5 Comment(1)
This is a solution that works for some cases, although not in this case.Alica
L
1

While user3419297's answer is very good, I think the blind keyup call is not what fixes the problem.

It appears that the KeyHistory command causes the keys to be released.

When I used a version of user3419297's script without KeyHistory, it never worked for me. In contrast, invoking KeyHistory alone has been sufficient to resolve the problem for me every time it has occured.

Laevogyrate answered 13/7, 2019 at 17:21 Comment(0)
D
1

This problem suddenly started occurring in a script that had been working without a hitch for years and to which I had made no changes. FWIW it started after a Windows update that seems to have slightly slowed down both AHK and python scripts that send keystrokes to applications. Which everyone seems to say can't happen but I know what I see. Anyhow, I tried everything I could find and nothing worked until I put this at the start of my script:

^T:: ;Script starts here
    Sleep, 500
    Send {LCtrl Up}
    ;Script continues and Ctrl is no longer pressed :)

Sorry I don't have a precise technical explanation for why this works. I'm guessing that I'm not letting go of the Ctrl key fast enough when I press my hotkey (in this case Ctrl-T), but that it somehow hasn't quite registered with AHK. Whatever the case, that little pause before sending the key up seems to work every time. The 500 ms was arbitrary; it works and I haven't bothered trying to make it any shorter. No more pressing Ctrl after every script, yay!

Dreadful answered 31/5, 2021 at 18:24 Comment(0)
D
1

Use KeyWait if you use AutoHotKey v2.

In AutoHotkey v2, there is a useful function KeyWait. It solves these stuck problems exclusively. Before I saw it I've tried Send "{Ctrl up}", waiting for seconds but neither working, until I find KeyWait in Official document. The similar function appears to ClipWait.

BTW, I would like to share my codes, rewrite from another LaTeX AHK codes. It can add brackets (In my code they're braces) on both sides:

^0::{
    KeyWait "Control"
    ClipBackup := ClipboardAll()
    A_Clipboard := ""
    SendInput "^x"
    Sleep 50
    selection := A_Clipboard
    SendInput "{{}{}}{Left}{Text}" selection
    Sleep 50
    len := StrLen(StrReplace(selection, "`r`n", "`n"))
    ; MsgBox "String '" selection "' has length " len
    Sleep 5 * len
    SendInput "{Left " len "}"
    Sleep 5 * len
    SendInput "+{Right " len "}"
    A_Clipboard := ClipBackup
    Return
}

Hope these can help you.

Degeneracy answered 19/3 at 13:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.