On Tue, 1 Jun 2021, Esme Povirk (they/them) wrote:
I think the only correct way to fix this is to have our test code retry (for some attempt/time limit) when OpenClipboard or functions using it fail.
Something like this works pretty well:
BOOL open_clipboard(HWND hwnd) { BOOL ret = OpenClipboard(hwnd); if (!ret && GetLastError() == ERROR_ACCESS_DENIED) { Sleep(10); ret = OpenClipboard(hwnd); } return ret; }
Then s/OpenClipboard/open_clipboard/. We may want to loop a few times for increased robustness.
But we'd also need to wrap other calls like GetOpenClipboardWindow(). I'm not entirely sure how long the list would be. We'd also need to do something similar for the Ole32 APIs in ole32:clipboard.
That feels invasive. I also worry it may end up masking bugs in Wine.
So I tested a few other approaches.
* A simple check like this at the start of the test would work on Windows:
if (FindWindowA("CLIPBRDWNDLASS", NULL)) { skip("skipping to avoid Ole32 clipboard interference\n"); return; }
- Of course it would not work if some other application monitors the clipboard without going through Ole32. - It also does not solve the Wine + KDE issue. - This feels a bit heavy handed, essentially banning all Radeon, Nvidia and Windows 7 machines.
* I also tried to lure the third party clipboard applications by putting some juicy delay-rendered data in the clipboard to detect them when they get it rendered (WM_RENDERFORMAT).
- That works to detect the Wine + KDE issue. - But it does not work for the Ole32 clipboard one. I guess Ole32 only queries the formats and I don't know how to detect that. - It would still end up skipping the whole test, probably also on Radeon, Nvidia, Wine + KDE, etc.
So maybe the wrapping approach is the only sane option.