Search code examples
python-3.xperformancebooleanctypespyautogui

how can I make this keypress simulator faster?


so I have this code from the pyautogui library, and I don't fully understand what it actually does.


    for apply_mod, vk_mod in [(mods & 4, 0x12), (mods & 2, 0x11),
        (mods & 1 or needsShift, 0x10)]: #HANKAKU not suported! mods & 8
        if apply_mod:
            ctypes.windll.user32.keybd_event(vk_mod, 0, 0, 0) #
    ctypes.windll.user32.keybd_event(vkCode, 0, 2, 0)
    for apply_mod, vk_mod in [(mods & 1 or needsShift, 0x10), (mods & 2, 0x11),
        (mods & 4, 0x12)]: #HANKAKU not suported! mods & 8
        print()
        if apply_mod:
            ctypes.windll.user32.keybd_event(vk_mod, 0, 2, 0)

so assuming that I have an expected input that wont vary or throw errors, what can I take out/ rewrite to make this faster (it is currently quite slow)


Solution

  • I just stumbled upon this very same code today, and although I don't have many details, I get more or less what it does. This code that you pasted corresponds to the keyUp function, which is also executed right after keyDown if you're calling press or typewrite. It checks for special characters that need modifier keys to be properly typed. Right above this code, there's this line:

    mods, vkCode = divmod(keyboardMapping[key], 0x100)
    

    See this variable mods. It receives the floor of the received key divided by 0x100, which is 256. vkCode gets the remainder. If the input key has code 300, for example, mods receives 1, and vkCode receives 44.

    On the first loop, it checks for mods and replaces it with 0x10, 0x11 or 0x12, and calls ctypes.windll.user32.keybd_event(vkCode, 0, 0, 0). This 0 is KEYDOWN. After this, it releases the vkCode key (since it's keyUp), right between the loops. Then the for loop checks again for mods and this time it releases the modifier key, using code 2.

    One way to make it faster is to break the loops once a result is found for mods, but since needsShift is involved, perhaps it needs some more thought to it (there can be 2 modifier keys being held simultaneously by this code).

    Another way is to remove this completely, leaving only the keybd_event in the middle, if you assume you'll never even need to use it, but it will of course be for personal use only. Also, if you plan to change it regardless, look for a similar code on the python file corresponding to the keyDown function to mirror the changes there as well.