Re: [PATCH v3] Cygwin: clipboard: Add workaround for ERROR_CLIPBOARD_NOT_OPEN
Mark Geisert <[email protected]> Fri, 12 Jun 2026 22:55:05 -0700
| Newsgroups | gmane.os.cygwin.patches |
|---|---|
| Message-ID | <[email protected]> |
Hi Takashi, On 6/12/2026 7:54 PM, Takashi Yano wrote: > SetClipboardData() and GetClipboardData() occasionally fail with > ERROR_CLIPBOARD_NOT_OPEN, even though OpenClipboard() succeeded if > NULL HWND is used. Retry until GetClipboardData() does not return > ERROR_CLIPBOARD_NOT_OPEN. > > Addresses: https://cygwin.com/pipermail/cygwin/2026-February/259438.html > Signed-off-by: Takashi Yano <[email protected]> > Reviewed-by: Mark Geisert <[email protected]> > --- > v2: Handle ERROR_NOT_FOUND case. Call CloseClipboard() in the loop. > v3: Change the timing of CloseClipboard(). Thanks for catching this ^^^ I was just about to mention it myself... > winsup/cygwin/fhandler/clipboard.cc | 19 +++++++++++++++++-- > 1 file changed, 17 insertions(+), 2 deletions(-) > > diff --git a/winsup/cygwin/fhandler/clipboard.cc b/winsup/cygwin/fhandler/clipboard.cc > index 12691c7c1..1273863f4 100644 > --- a/winsup/cygwin/fhandler/clipboard.cc > +++ b/winsup/cygwin/fhandler/clipboard.cc > @@ -25,11 +25,26 @@ details. */ > static inline bool > open_clipboard () > { > - const int max_retry = 10; > + const int max_retry = 20; > for (int i = 0; i < max_retry; i++) > { > + /* No appropriate HWND exists here. */ > if (OpenClipboard (NULL)) > - return true; > + { > + /* SetClipboardData() and GetClipboardData() occasionally > + fail with ERROR_CLIPBOARD_NOT_OPEN, even though > + OpenClipboard() succeeded if NULL HWND is used. > + Retry until GetClipboardData() does not return > + ERROR_CLIPBOARD_NOT_OPEN. */ > + if (GetClipboardData (CF_UNICODETEXT)) > + return true; > + DWORD err = GetLastError (); Given the ambiguity of "ERROR_NOT_FOUND" I would add a one-line comment here saying ERROR_NOT_FOUND means GetClipboardData() couldn't find CF_UNICODETEXT data, but it would return data if you ask for the correct format. This latter case means the clipboard is indeed open. (Or some briefer way of saying this complicated case.) Hmm. Maybe more than one line for that comment. With that, patch is GTG. > + if (err == ERROR_NOT_FOUND) > + return true; > + CloseClipboard (); > + if (err != ERROR_CLIPBOARD_NOT_OPEN) > + return false; > + } > Sleep (1); > } > return false; Thanks & Regards, ..mark