Release v0.6.19: retry dropped copies and stabilize snippet integration

This commit is contained in:
2026-10-31 02:03:07 +02:00
parent 0d3b2acae9
commit 6603d28f68
9 changed files with 127 additions and 17 deletions
+24 -1
View File
@@ -124,7 +124,13 @@ class Transaction
{
check();
adopted.clear();
app.ownSequence = expected = writeClipboard(app.window, c);
// These are temporary transaction contents, not a user's clipboard entry.
// In particular, do not invite the Windows history service to read our
// sentinel while the target editor is trying to open the clipboard.
auto temporary = c;
const std::wstring exclusion = L"ExcludeClipboardContentFromMonitorProcessing";
temporary.formats.push_back({RegisterClipboardFormatW(exclusion.c_str()), exclusion, Bytes{0}});
app.ownSequence = expected = writeClipboard(app.window, temporary);
// A concurrent writer can win immediately after CloseClipboard, before we read its sequence.
// Never adopt that writer's sequence as our own and paste its content.
if (GetClipboardOwner() != app.window)
@@ -146,6 +152,8 @@ class Transaction
return {};
}
ULONGLONG deadline = GetTickCount64() + 2000;
ULONGLONG retryAt = GetTickCount64() + 250;
unsigned attempts = 1;
DWORD changed = before;
ULONGLONG stable = 0;
bool changedAgain = false;
@@ -162,6 +170,21 @@ class Transaction
}
if (changed != before && GetTickCount64() - stable >= 60)
break;
// Native editors can silently drop Ctrl+C if another process has
// the clipboard open. Retry only while our sentinel is untouched;
// never overwrite a copy result or another application's content.
if (changed == before && attempts < 3 && GetTickCount64() >= retryAt &&
!GetOpenClipboardWindow())
{
check();
if (!valid() || GetClipboardSequenceNumber() != before)
return {};
if (!chord(L'C', MOD_CONTROL))
return {};
diagnosticEvent(L"Copy retry: clipboard unchanged after Ctrl+C");
++attempts;
retryAt = GetTickCount64() + 250;
}
Sleep(10);
}
if (changed == before || !valid())