April 12, 2021

AutoHotkey: Paste and restore clipboard pitfall

I have stumbled about a paste pitfall in AutoHotkey and seen recently in Reddit I am not alone ;-)
I have learned also recently from an AHK Forum post (thanks to rommmcek) how to handle properly such issue.
I share here my learning and Clipboard code library.

Problem description

To speed up text input it is a good common best practice with AutoHotkey to copy the text to the clipboard and paste it (instead of sending characters one by one).

If you don't want to modify your clipboard history, you might come with  such a code:

ClipPaste(Text){
ClipBackup:= ClipboardAll
Clipboard := Text 
SendInput ^v ; Paste
Clipboard := ClipBackup
}

There is a problem in the 2 last lines of code. 
The clipboard might be restored before the paste is executed means this code will paste the text in the clipboard and not what you want it to (Input Text).
This is because the SendInput is asynchronous. The code goes on without waiting for the key send to finish.
If you are lucky the paste will be instantaneous. But for some heavy consuming applications (for example Outlook or Microsoft Teams) the clipboard will be restored before the real pasting.

Solution

An easy fix would be to add a pause just after the paste. The problem is that it is a fixed time that might be enough in some weird cases or unnecessarily too long ;-)
A better more robust and optimized approach is the following: After sending the Paste you shall wait a minimal time for the clipboard to receive the order and wait until it isn't busy anymore. You can check for clipboard business calling While DllCall("user32\GetOpenClipboardWindow", "Ptr")

This is implemented in my ahk/Lib/Clip.ahk library-> Clip_Paste function. 

Below is an equivalent solution that uses the same approach (the code in the library is slightly differently structured and uses WinClip dependency for other/HTML functionality)

ClipPaste(sText,restore := True) {
If (restore)
    ClipBackup:= ClipboardAll
Clipboard := sText
SendInput ^v
If (restore) {
    Sleep, 150
    While DllCall("user32\GetOpenClipboardWindow", "Ptr")
        Sleep, 150
    Clipboard := ClipBackup
}
} ; eofun

See also

SetClipboardHTML() - AutoHotkey Community

Variable-pasting script works flawlessly in one program, but suddenly consistently not at all in the other: Clipboard-manipulation/pasting variable contents : AutoHotkey (Reddit)


No comments:

Post a Comment