Repository: microsoft/terminal
File: src/host/consoleInformation.cpp (C++)

Code before:
{
    _cookedReadData = readData;
}

bool CONSOLE_INFORMATION::GetBracketedPasteMode() const noexcept
{
    return _bracketedPasteMode;
}

void CONSOLE_INFORMATION::SetBracketedPasteMode(const bool enabled) noexcept
{
    _bracketedPasteMode = enabled;
}

void CONSOLE_INFORMATION::CopyTextToClipboard(const std::wstring_view text)
{
    const auto window = ServiceLocator::LocateConsoleWindow();
    if (window)
    {
        // The clipboard can only be updated from the main GUI thread, so we
        // need to post a message to trigger the actual copy operation. But if
        // the pending clipboard content is already set, a message would have
        // already been posted, so there's no need to post another one.
        const auto clipboardMessageSent = _pendingClipboardText.has_value();
        _pendingClipboardText = text;
        if (!clipboardMessageSent)
        {
            PostMessageW(window->GetWindowHandle(), CM_UPDATE_CLIPBOARD, 0, 0);
        }
    }
}

std::optional<std::wstring> CONSOLE_INFORMATION::UsePendingClipboardText()
{
    // Once the pending text has been used, we clear the variable to let the
    // CopyTextToClipboard method know that the last CM_UPDATE_CLIPBOARD message
    // has been processed, and future updates will require another message.
    const auto clipboardText = _pendingClipboardText;
    _pendingClipboardText.reset();
    return clipboardText;
}

// Method Description:
// - Return the active screen buffer of the console.
// Arguments:
// - <none>
// Return Value:
// - the active screen buffer of the console.
SCREEN_INFORMATION& CONSOLE_INFORMATION::GetActiveOutputBuffer()
{
    return *pCurrentScreenBuffer;

Review comment (suggestion):
I believe we need to lock this with a mutex, don't we?

But there may be another way to do this: What if we split `Clipboard::_copyToClipboard` into one function that creates a ready-to-use `wil::unique_hglobal` with the given contents, and one function that sets the clipboard to the given `wil::unique_hglobal`.

We can then send the `wil::unique_hglobal` as a simple pointer as the `LPARAM` along with `CM_UPDATE_CLIPBOARD` restore it on the other side and pass it into `Clipboard`.

Not sure if that's more complex though...

Code after:
{
    _cookedReadData = readData;
}

bool CONSOLE_INFORMATION::GetBracketedPasteMode() const noexcept
{
    return _bracketedPasteMode;
}

void CONSOLE_INFORMATION::SetBracketedPasteMode(const bool enabled) noexcept
{
    _bracketedPasteMode = enabled;
}

void CONSOLE_INFORMATION::CopyTextToClipboard(const std::wstring_view text)
{
    const auto window = ServiceLocator::LocateConsoleWindow();
    if (window)
    {
        // The clipboard can only be updated from the main GUI thread, so we
        // need to post a message to trigger the actual copy operation. But if
        // the pending clipboard content is already set, a message would have
        // already been posted, so there's no need to post another one.
        const auto clipboardMessageSent = _pendingClipboardText.has_value();
        _pendingClipboardText = text;
        if (!clipboardMessageSent)
        {
            PostMessageW(window->GetWindowHandle(), CM_UPDATE_CLIPBOARD, 0, 0);
        }
    }
}

std::optional<std::wstring> CONSOLE_INFORMATION::UsePendingClipboardText()
{
    // Once the pending text has been used, we clear the variable to let the
    // CopyTextToClipboard method know that the last CM_UPDATE_CLIPBOARD message
    // has been processed, and future updates will require another message.
    return std::exchange(_pendingClipboardText, {});
}

// Method Description:
// - Return the active screen buffer of the console.
// Arguments:
// - <none>
// Return Value:
// - the active screen buffer of the console.
SCREEN_INFORMATION& CONSOLE_INFORMATION::GetActiveOutputBuffer()
{
    return *pCurrentScreenBuffer;
}