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.
This commit is contained in:
UberKitten
2026-02-27 07:22:22 -08:00
committed by Chris Rizzitello
parent 7126f31d3f
commit ac8cc42b7a

View File

@ -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