diff --git a/src/lib/platform/MSWindowsClipboard.cpp b/src/lib/platform/MSWindowsClipboard.cpp index 1d13e1253..eab6155df 100644 --- a/src/lib/platform/MSWindowsClipboard.cpp +++ b/src/lib/platform/MSWindowsClipboard.cpp @@ -1,5 +1,6 @@ /* * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2026 Deskflow Developers * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. * SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception @@ -116,14 +117,26 @@ bool MSWindowsClipboard::open(Time time) const { LOG_DEBUG("open clipboard"); - if (!OpenClipboard(m_window)) { - LOG_WARN("failed to open clipboard: %d", GetLastError()); - return false; + // The clipboard is a global mutex on Windows. We aren't always going to + // get the lock on the first try, so try a few times before giving up. + // Based on Chromium's ScopedClipboard::Acquire() retry loop. + static const int kMaxRetries = 5; + static const int kRetryDelayMs = 5; + + for (int i = 0; i < kMaxRetries; ++i) { + if (OpenClipboard(m_window)) { + m_time = time; + return true; + } + + if (i < kMaxRetries - 1) { + LOG_DEBUG("failed to open clipboard (attempt %d/%d, error=%d), retrying", i + 1, kMaxRetries, GetLastError()); + Sleep(kRetryDelayMs); + } } - m_time = time; - - return true; + LOG_WARN("failed to open clipboard after %d attempts: %d", kMaxRetries, GetLastError()); + return false; } void MSWindowsClipboard::close() const