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.

 winsup/cygwin/fhandler/clipboard.cc | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/winsup/cygwin/fhandler/clipboard.cc 
b/winsup/cygwin/fhandler/clipboard.cc
index 12691c7c1..a7ca10039 100644
--- a/winsup/cygwin/fhandler/clipboard.cc
+++ b/winsup/cygwin/fhandler/clipboard.cc
@@ -25,11 +25,24 @@ 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)
+             || GetLastError () == ERROR_NOT_FOUND)
+           return true;
+         if (GetLastError () != ERROR_CLIPBOARD_NOT_OPEN)
+           return false;
+         CloseClipboard ();
+       }
       Sleep (1);
     }
   return false;
-- 
2.51.0

Reply via email to