From ac8cc42b7aac8abe9a24b39551e33d3e8271d526 Mon Sep 17 00:00:00 2001 From: UberKitten <566438+UberKitten@users.noreply.github.com> Date: Fri, 27 Feb 2026 07:22:22 -0800 Subject: [PATCH] fix: retry OpenClipboard() on Windows OpenClipboard() can fail transiently when another process holds the clipboard mutex. Add a retry loop (5 attempts, 5ms delay) so that Deskflow handles brief contention gracefully instead of immediately failing. --- src/lib/platform/MSWindowsClipboard.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) 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