Fix 5s lags when using OSC 52 clipboard copy (#20728)

Hilarious repro: `printf "\e]0;A\a\e]52;c;Qg==\a"`

This issue is exactly what happens when you Ctrl+X in a clean file in
msedit and it freezes Windows Terminal. It's because it puts a "•" in
the title and copies the text.

It triggers a title and clipboard change in the same frame which causes
the UI and VT thread to deadlock trying to get the console lock.
This commit is contained in:
Leonard Hecker authored and GitHub committed 2026-09-28 15:11:15 +00:00
1 parent bb0541e7a9
commit 0626dc1457
3 files changed
+14 -2

No files matched your search

@@ -444,6 +444,7 @@ DELAYLOAD
DELETEONRELEASE
depersist
deprioritized
DESTROYCLIPBOARD
devicecode
Dext
DFF
+12 -1
View File
@@ -3624,8 +3624,19 @@ namespace winrt::TerminalApp::implementation
}
}
void TerminalPage::_copyToClipboard(const IInspectable, const WriteToClipboardEventArgs args) const
safe_void_coroutine TerminalPage::_copyToClipboard(const IInspectable, const WriteToClipboardEventArgs args) const
{
// This is our hook into SetCopyToClipboardCallback, which gets called by the VT parser thread.
// When this gets called, the console lock is being held. This is not a problem per-se, but there
// is just a teeny tiny problem... EmptyClipboard() sends WM_DESTROYCLIPBOARD to the previous owner.
// *We* may be the previous owner.
//
// So now we (VT thread, holding the lock) are waiting for us (UI thread, waiting for the lock)
// and immediately deadlock. *Tada* 5s app freeze.
//
// Solution: Just do it on the UI thread. Just like conhost.
co_await wil::resume_foreground(Dispatcher());
if (const auto clipboard = clipboard::open(_hostingHwnd.value_or(nullptr)))
{
const auto plain = args.Plain();
+1 -1
View File
@@ -493,7 +493,7 @@ namespace winrt::TerminalApp::implementation
safe_void_coroutine _SetTaskbarProgressHandler(const IInspectable sender, const IInspectable eventArgs);
void _copyToClipboard(IInspectable, Microsoft::Terminal::Control::WriteToClipboardEventArgs args) const;
safe_void_coroutine _copyToClipboard(IInspectable, Microsoft::Terminal::Control::WriteToClipboardEventArgs args) const;
void _PasteText();
safe_void_coroutine _ControlNoticeRaisedHandler(const IInspectable sender, const Microsoft::Terminal::Control::NoticeEventArgs eventArgs);