Repository: microsoft/terminal
File: src/cascadia/TerminalControl/ControlCore.cpp (C++)

Code before:
    void ControlCore::ToggleReadOnlyMode()
    {
        _isReadOnly = !_isReadOnly;
    }

    void ControlCore::SetReadOnlyMode(const bool readOnlyState)
    {
        _isReadOnly = readOnlyState;
    }

    void ControlCore::_raiseReadOnlyWarning()
    {
        auto noticeArgs = winrt::make<NoticeEventArgs>(NoticeLevel::Info, RS_(L"TermControlReadOnly"));
        RaiseNotice.raise(*this, std::move(noticeArgs));
    }
    void ControlCore::_connectionOutputHandler(const hstring& hstr)
    {
        try
        {
            {
                const auto lock = _terminal->LockForWriting();
                _terminal->Write(hstr);
            }

            if (!_pendingResponses.empty())
            {
                _sendInputToConnection(_pendingResponses);
                _pendingResponses.clear();
            }

            // Start the throttled update of where our hyperlinks are.
            const auto shared = _shared.lock_shared();
            if (shared->outputIdle)
            {
                (*shared->outputIdle)();
            }
        }
        catch (...)
        {
            // We're expecting to receive an exception here if the terminal
            // is closed while we're blocked playing a MIDI note.
        }
    }

    ::Microsoft::Console::Render::Renderer* ControlCore::GetRenderer() const noexcept
    {
        return _renderer.get();
    }

    uint64_t ControlCore::SwapChainHandle() const
    {

Review comment (bug):
This fixes the bug. It also fixes 2nd bug: We'd previously use the old `_sendInputToConnection` for responses but this would check whether we're read-only. We shouldn't do that for VT responses.

Code after:
    }

    void ControlCore::SetReadOnlyMode(const bool readOnlyState)
    {
        _isReadOnly = readOnlyState;
    }

    void ControlCore::_raiseReadOnlyWarning()
    {
        auto noticeArgs = winrt::make<NoticeEventArgs>(NoticeLevel::Info, RS_(L"TermControlReadOnly"));
        RaiseNotice.raise(*this, std::move(noticeArgs));
    }
    void ControlCore::_connectionOutputHandler(const hstring& hstr)
    {
        try
        {
            {
                const auto lock = _terminal->LockForWriting();
                _terminal->Write(hstr);
            }

            if (!_pendingResponses.empty())
            {
                _sendInputToConnection(_pendingResponses);
                _pendingResponses.clear();
            }

            // Start the throttled update of where our hyperlinks are.
            const auto shared = _shared.lock_shared();
            if (shared->outputIdle)
            {
                (*shared->outputIdle)();
            }
        }
        catch (...)
        {
            // We're expecting to receive an exception here if the terminal
            // is closed while we're blocked playing a MIDI note.
        }
    }

    ::Microsoft::Console::Render::Renderer* ControlCore::GetRenderer() const noexcept
    {
        return _renderer.get();
    }

    uint64_t ControlCore::SwapChainHandle() const
    {
        // This is only ever called by TermControl::AttachContent, which occurs
        // when we're taking an existing core and moving it to a new control.
        // Otherwise, we only ever use the value from the SwapChainChanged