Win32 OpenClipboard failures

816 views
Skip to first unread message

Neil Hodgson

unread,
Feb 21, 2016, 1:13:29 AM2/21/16
to Scintilla mailing list
On Windows the OpenClipboard call, used before reading or writing the clipboard, can fail. This may occur because another application has opened the clipboard. Currently Scintilla fails the Cut/Copy/Paste/… operation when it can not open the clipboard. Normally clipboard operations are driven by the user so do not often overlap. However, sometimes another application such as a clipboard viewer or a virtual machine with a bridged clipboard may be acting on the clipboard in the background. On my main Windows box, it appears that DropBox is causing problems by opening the clipboard when it changes.

It would be possible to retry the OpenClipboard call if it fails. Other APIs, such as the .Net Clipboard.SetDataObject include retry parameters with default behaviour of retrying up to 10 times with a delay between attempts of 100 milliseconds.

Neil

Jason Haslam

unread,
Feb 21, 2016, 2:29:35 PM2/21/16
to scintilla...@googlegroups.com
The Qt backend on Windows has the same issue. There’s already some extra logic there to pop up an error dialog instead of just silently failing. It probably should be fixed in Qt (https://bugreports.qt.io/browse/QTBUG-27097) but handling it better in Scintilla would be good too. I can submit a patch for the Qt platform.

Jason


--
You received this message because you are subscribed to the Google Groups "scintilla-interest" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scintilla-inter...@googlegroups.com.
To post to this group, send email to scintilla...@googlegroups.com.
Visit this group at https://groups.google.com/group/scintilla-interest.
For more options, visit https://groups.google.com/d/optout.

Neil Hodgson

unread,
Feb 21, 2016, 7:00:55 PM2/21/16
to scintilla...@googlegroups.com
Jason Hallam:

The Qt backend on Windows has the same issue. There’s already some extra logic there to pop up an error dialog instead of just silently failing. It probably should be fixed in Qt (https://bugreports.qt.io/browse/QTBUG-27097) but handling it better in Scintilla would be good too. I can submit a patch for the Qt platform.

   That would be good.

   Here is my current implementation. With DropBox, I have never seen more than 2 retries needed and 2 is much less common than 1. Its possible that other applications could keep the clipboard open while performing network I/O which could take longer that 1/8 seconds. Some of the search hits for this problem mention Remote Desktop.

   Using a uniform delay of 100 ms which is the .Net behaviour doubled the average time taken by Scintilla’s main automated tests when there is a clash. The automated tests are very susceptible to this issue, likely because they perform copies then immediately paste and any clipboard watchers will open the clipboard as soon as they see the clipboard change because of the copy. Application operations and user macros that work through the clipboard will probably see a similar chance of clashes.

// OpenClipboard may fail if another application has opened the clipboard.
// Try up to 8 times, with an initial delay of 1 ms and an exponential back off
// for a maximum total delay of 127 ms (1+2+4+8+16+32+64).
static bool OpenClipboardRetry(HWND hwnd) {
for (int attempt=0; attempt<8; attempt++) {
if (attempt > 0) {
::Sleep(1 << (attempt-1));
}
if (::OpenClipboard(hwnd)) {
if (attempt > 0)
Platform::DebugPrintf("Failed %d times", attempt);
return true;
}
}
return false;
}

   Neil

Neil Hodgson

unread,
Feb 22, 2016, 7:48:59 PM2/22/16
to scintilla...@googlegroups.com

Jason Haslam

unread,
Feb 23, 2016, 2:57:02 PM2/23/16
to scintilla...@googlegroups.com
The attached patch works for me. I’m not sure about this though. It should really be fixed in Qt.

Jason

qt-copy-retry.diff

Neil Hodgson

unread,
Feb 23, 2016, 7:01:15 PM2/23/16
to scintilla...@googlegroups.com
Jason Hallam:

The attached patch works for me. I’m not sure about this though. It should really be fixed in Qt.

   Committed as it should be an improvement and can be reverted if its fixed in Qt.
https://sourceforge.net/p/scintilla/code/ci/8bc19ede3b5160c638fc6e23806e1ba0fdc6d4a0/

   I commented on the QTBUG and it doesn’t look like it would be difficult to fix so hopefully it will be addressed. The main way Qt performs copies is by calling OleSetClipboard rather than OpenClipboard and can be seen in …/platforms/windows/qwindowsclipboard.cpp. The OleGetClipboard call there could also be fixed.

   Neil
Reply all
Reply to author
Forward
0 new messages