From c64a9d2a32402455d196edacd7f5ac92ddaf508f Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Tue, 13 May 2025 16:18:05 -0700 Subject: [PATCH] wpf: allow OSC 52 to write the clipboard (#18905) We never hooked up this callback! This allows a CLI application to emit text directly to the clipboard. --- .github/actions/spelling/allow/apis.txt | 1 + src/cascadia/TerminalControl/HwndTerminal.cpp | 9 +++++++-- src/cascadia/TerminalControl/HwndTerminal.hpp | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/actions/spelling/allow/apis.txt b/.github/actions/spelling/allow/apis.txt index 9be081bc2b..3137e5624c 100644 --- a/.github/actions/spelling/allow/apis.txt +++ b/.github/actions/spelling/allow/apis.txt @@ -290,4 +290,5 @@ xtree xutility YIcon YMax +zstring zwstring diff --git a/src/cascadia/TerminalControl/HwndTerminal.cpp b/src/cascadia/TerminalControl/HwndTerminal.cpp index 3cb02ee547..e24f8dda94 100644 --- a/src/cascadia/TerminalControl/HwndTerminal.cpp +++ b/src/cascadia/TerminalControl/HwndTerminal.cpp @@ -303,6 +303,7 @@ HRESULT HwndTerminal::Initialize() _terminal->Create({ 80, 25 }, 9001, *_renderer); _terminal->SetWriteInputCallback([=](std::wstring_view input) noexcept { _WriteTextToConnection(input); }); + _terminal->SetCopyToClipboardCallback([=](wil::zwstring_view text) noexcept { _CopyTextToSystemClipboard(text, {}, {}); }); _renderer->EnablePainting(); _multiClickTime = std::chrono::milliseconds{ GetDoubleClickTime() }; @@ -321,6 +322,10 @@ try _renderer.reset(); _renderEngine.reset(); + // These two callbacks have a dangling reference to `this`; let's just clear them + _terminal->SetWriteInputCallback(nullptr); + _terminal->SetCopyToClipboardCallback(nullptr); + if (auto localHwnd{ _hwnd.release() }) { // If we're being called through WM_DESTROY, we won't get here (hwnd is already released) @@ -1043,7 +1048,7 @@ void __stdcall TerminalKillFocus(void* terminal) // - text - selected text in plain-text format // - htmlData - selected text in HTML format // - rtfData - selected text in RTF format -HRESULT HwndTerminal::_CopyTextToSystemClipboard(const std::wstring& text, const std::string& htmlData, const std::string& rtfData) const +HRESULT HwndTerminal::_CopyTextToSystemClipboard(wil::zwstring_view text, wil::zstring_view htmlData, wil::zstring_view rtfData) const try { RETURN_HR_IF_NULL(E_NOT_VALID_STATE, _terminal); @@ -1099,7 +1104,7 @@ CATCH_RETURN() // Arguments: // - stringToCopy - The string to copy // - lpszFormat - the name of the format -HRESULT HwndTerminal::_CopyToSystemClipboard(const std::string& stringToCopy, LPCWSTR lpszFormat) const +HRESULT HwndTerminal::_CopyToSystemClipboard(wil::zstring_view stringToCopy, LPCWSTR lpszFormat) const { const auto cbData = stringToCopy.size() + 1; // +1 for '\0' if (cbData) diff --git a/src/cascadia/TerminalControl/HwndTerminal.hpp b/src/cascadia/TerminalControl/HwndTerminal.hpp index 350727f12a..fef4670e49 100644 --- a/src/cascadia/TerminalControl/HwndTerminal.hpp +++ b/src/cascadia/TerminalControl/HwndTerminal.hpp @@ -145,8 +145,8 @@ private: void _UpdateFont(int newDpi); void _WriteTextToConnection(const std::wstring_view text) noexcept; - HRESULT _CopyTextToSystemClipboard(const std::wstring& text, const std::string& htmlData, const std::string& rtfData) const; - HRESULT _CopyToSystemClipboard(const std::string& stringToCopy, LPCWSTR lpszFormat) const; + HRESULT _CopyTextToSystemClipboard(wil::zwstring_view text, wil::zstring_view htmlData, wil::zstring_view rtfData) const; + HRESULT _CopyToSystemClipboard(wil::zstring_view stringToCopy, LPCWSTR lpszFormat) const; void _PasteTextFromClipboard() noexcept; void _FocusTSF() noexcept;