Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions experiments/shell/clipboard.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,28 @@ class ClipboardError : public std::runtime_error {
};
class ClipboardAccess {
public:
explicit ClipboardAccess(HWND owner) {
if (!OpenClipboard(owner)) throw ClipboardError("OpenClipboard", GetLastError());
// A hosted desktop can hold the clipboard for a few milliseconds at a time
// (Explorer or a neighbouring test). Reads retry briefly so contention is
// not reported as a hard refusal; writes keep the immediate failure because
// the copy-failure contract asserts the first OpenClipboard result.
explicit ClipboardAccess(HWND owner, bool retry = false) {
constexpr int attempts = 5;
for (int attempt = 0; attempt < attempts; ++attempt) {
if (OpenClipboard(owner)) return;
const DWORD error = GetLastError();
if (!retry || error != ERROR_ACCESS_DENIED || attempt + 1 == attempts)
throw ClipboardError("OpenClipboard", error);
Sleep(static_cast<DWORD>(20 * (attempt + 1)));
}
throw ClipboardError("OpenClipboard", GetLastError());
}
~ClipboardAccess() { CloseClipboard(); }
ClipboardAccess(const ClipboardAccess&) = delete;
};
inline std::u16string read_unicode_clipboard(HWND owner, size_t max_units = PastePolicy::hard_utf16_units) {
static_assert(sizeof(wchar_t) == sizeof(char16_t), "Windows UTF-16 expected");
if (max_units > PastePolicy::hard_utf16_units) throw std::length_error("clipboard limit exceeds hard bound");
ClipboardAccess clipboard(owner);
ClipboardAccess clipboard(owner, true);
if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) throw ClipboardError("Unicode text unavailable", ERROR_NOT_FOUND);
HANDLE memory = GetClipboardData(CF_UNICODETEXT);
if (!memory) throw ClipboardError("GetClipboardData", GetLastError());
Expand Down
Loading