Make the renderer optional (#17442)

If `VtEngine` gets removed from conhost, we need to be able to run
without any renderer present whatsoever. To make this possible,
I've turned all `Renderer&` into `Renderer*`.

Part of #14000
This commit is contained in:
Leonard Hecker
2024-06-20 20:26:58 +02:00
committed by GitHub
parent e0686fa6f3
commit bd116e35b2
16 changed files with 111 additions and 89 deletions

View File

@@ -48,7 +48,7 @@ TextBuffer::TextBuffer(til::size screenBufferSize,
const TextAttribute defaultAttributes, const TextAttribute defaultAttributes,
const UINT cursorSize, const UINT cursorSize,
const bool isActiveBuffer, const bool isActiveBuffer,
Microsoft::Console::Render::Renderer& renderer) : Microsoft::Console::Render::Renderer* renderer) :
_renderer{ renderer }, _renderer{ renderer },
_currentAttributes{ defaultAttributes }, _currentAttributes{ defaultAttributes },
// This way every TextBuffer will start with a ""unique"" _lastMutationId // This way every TextBuffer will start with a ""unique"" _lastMutationId
@@ -718,9 +718,9 @@ void TextBuffer::IncrementCircularBuffer(const TextAttribute& fillAttributes)
{ {
// FirstRow is at any given point in time the array index in the circular buffer that corresponds // FirstRow is at any given point in time the array index in the circular buffer that corresponds
// to the logical position 0 in the window (cursor coordinates and all other coordinates). // to the logical position 0 in the window (cursor coordinates and all other coordinates).
if (_isActiveBuffer) if (_isActiveBuffer && _renderer)
{ {
_renderer.TriggerFlush(true); _renderer->TriggerFlush(true);
} }
// Prune hyperlinks to delete obsolete references // Prune hyperlinks to delete obsolete references
@@ -1063,56 +1063,56 @@ bool TextBuffer::IsActiveBuffer() const noexcept
return _isActiveBuffer; return _isActiveBuffer;
} }
Microsoft::Console::Render::Renderer& TextBuffer::GetRenderer() noexcept Microsoft::Console::Render::Renderer* TextBuffer::GetRenderer() noexcept
{ {
return _renderer; return _renderer;
} }
void TextBuffer::NotifyPaintFrame() noexcept void TextBuffer::NotifyPaintFrame() noexcept
{ {
if (_isActiveBuffer) if (_isActiveBuffer && _renderer)
{ {
_renderer.NotifyPaintFrame(); _renderer->NotifyPaintFrame();
} }
} }
void TextBuffer::TriggerRedraw(const Viewport& viewport) void TextBuffer::TriggerRedraw(const Viewport& viewport)
{ {
if (_isActiveBuffer) if (_isActiveBuffer && _renderer)
{ {
_renderer.TriggerRedraw(viewport); _renderer->TriggerRedraw(viewport);
} }
} }
void TextBuffer::TriggerRedrawAll() void TextBuffer::TriggerRedrawAll()
{ {
if (_isActiveBuffer) if (_isActiveBuffer && _renderer)
{ {
_renderer.TriggerRedrawAll(); _renderer->TriggerRedrawAll();
} }
} }
void TextBuffer::TriggerScroll() void TextBuffer::TriggerScroll()
{ {
if (_isActiveBuffer) if (_isActiveBuffer && _renderer)
{ {
_renderer.TriggerScroll(); _renderer->TriggerScroll();
} }
} }
void TextBuffer::TriggerScroll(const til::point delta) void TextBuffer::TriggerScroll(const til::point delta)
{ {
if (_isActiveBuffer) if (_isActiveBuffer && _renderer)
{ {
_renderer.TriggerScroll(&delta); _renderer->TriggerScroll(&delta);
} }
} }
void TextBuffer::TriggerNewTextNotification(const std::wstring_view newText) void TextBuffer::TriggerNewTextNotification(const std::wstring_view newText)
{ {
if (_isActiveBuffer) if (_isActiveBuffer && _renderer)
{ {
_renderer.TriggerNewTextNotification(newText); _renderer->TriggerNewTextNotification(newText);
} }
} }

View File

@@ -72,7 +72,7 @@ public:
const TextAttribute defaultAttributes, const TextAttribute defaultAttributes,
const UINT cursorSize, const UINT cursorSize,
const bool isActiveBuffer, const bool isActiveBuffer,
Microsoft::Console::Render::Renderer& renderer); Microsoft::Console::Render::Renderer* renderer);
TextBuffer(const TextBuffer&) = delete; TextBuffer(const TextBuffer&) = delete;
TextBuffer(TextBuffer&&) = delete; TextBuffer(TextBuffer&&) = delete;
@@ -161,7 +161,7 @@ public:
void SetAsActiveBuffer(const bool isActiveBuffer) noexcept; void SetAsActiveBuffer(const bool isActiveBuffer) noexcept;
bool IsActiveBuffer() const noexcept; bool IsActiveBuffer() const noexcept;
Microsoft::Console::Render::Renderer& GetRenderer() noexcept; Microsoft::Console::Render::Renderer* GetRenderer() noexcept;
void NotifyPaintFrame() noexcept; void NotifyPaintFrame() noexcept;
void TriggerRedraw(const Microsoft::Console::Types::Viewport& viewport); void TriggerRedraw(const Microsoft::Console::Types::Viewport& viewport);
@@ -333,7 +333,7 @@ private:
static void _AppendRTFText(std::string& contentBuilder, const std::wstring_view& text); static void _AppendRTFText(std::string& contentBuilder, const std::wstring_view& text);
Microsoft::Console::Render::Renderer& _renderer; Microsoft::Console::Render::Renderer* _renderer = nullptr;
std::unordered_map<uint16_t, std::wstring> _hyperlinkMap; std::unordered_map<uint16_t, std::wstring> _hyperlinkMap;
std::unordered_map<std::wstring, uint16_t> _hyperlinkCustomIdMap; std::unordered_map<std::wstring, uint16_t> _hyperlinkCustomIdMap;

View File

@@ -699,7 +699,7 @@ class ReflowTests
static DummyRenderer renderer; static DummyRenderer renderer;
static std::unique_ptr<TextBuffer> _textBufferFromTestBuffer(const TestBuffer& testBuffer) static std::unique_ptr<TextBuffer> _textBufferFromTestBuffer(const TestBuffer& testBuffer)
{ {
auto buffer = std::make_unique<TextBuffer>(testBuffer.size, TextAttribute{ 0x7 }, 0, false, renderer); auto buffer = std::make_unique<TextBuffer>(testBuffer.size, TextAttribute{ 0x7 }, 0, false, &renderer);
til::CoordType y = 0; til::CoordType y = 0;
for (const auto& testRow : testBuffer.rows) for (const auto& testRow : testBuffer.rows)
@@ -725,7 +725,7 @@ class ReflowTests
static std::unique_ptr<TextBuffer> _textBufferByReflowingTextBuffer(TextBuffer& originalBuffer, const til::size newSize) static std::unique_ptr<TextBuffer> _textBufferByReflowingTextBuffer(TextBuffer& originalBuffer, const til::size newSize)
{ {
auto buffer = std::make_unique<TextBuffer>(newSize, TextAttribute{ 0x7 }, 0, false, renderer); auto buffer = std::make_unique<TextBuffer>(newSize, TextAttribute{ 0x7 }, 0, false, &renderer);
TextBuffer::Reflow(originalBuffer, *buffer); TextBuffer::Reflow(originalBuffer, *buffer);
return buffer; return buffer;
} }

View File

@@ -37,7 +37,7 @@ class UTextAdapterTests
TEST_METHOD(Unicode) TEST_METHOD(Unicode)
{ {
DummyRenderer renderer; DummyRenderer renderer;
TextBuffer buffer{ til::size{ 24, 1 }, TextAttribute{}, 0, false, renderer }; TextBuffer buffer{ til::size{ 24, 1 }, TextAttribute{}, 0, false, &renderer };
RowWriteState state{ RowWriteState state{
.text = L"abc 𝒶𝒷𝒸 abc ネコちゃん", .text = L"abc 𝒶𝒷𝒸 abc ネコちゃん",

View File

@@ -1894,7 +1894,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
const auto lock = _terminal->LockForWriting(); const auto lock = _terminal->LockForWriting();
auto& renderSettings = _terminal->GetRenderSettings(); auto& renderSettings = _terminal->GetRenderSettings();
renderSettings.ToggleBlinkRendition(*_renderer); renderSettings.ToggleBlinkRendition(_renderer.get());
} }
void ControlCore::BlinkCursor() void ControlCore::BlinkCursor()

View File

@@ -47,9 +47,9 @@ void Terminal::Create(til::size viewportSize, til::CoordType scrollbackLines, Re
Utils::ClampToShortMax(viewportSize.height + scrollbackLines, 1) }; Utils::ClampToShortMax(viewportSize.height + scrollbackLines, 1) };
const TextAttribute attr{}; const TextAttribute attr{};
const UINT cursorSize = 12; const UINT cursorSize = 12;
_mainBuffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, true, renderer); _mainBuffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, true, &renderer);
auto dispatch = std::make_unique<AdaptDispatch>(*this, renderer, _renderSettings, _terminalInput); auto dispatch = std::make_unique<AdaptDispatch>(*this, &renderer, _renderSettings, _terminalInput);
auto engine = std::make_unique<OutputStateMachineEngine>(std::move(dispatch)); auto engine = std::make_unique<OutputStateMachineEngine>(std::move(dispatch));
_stateMachine = std::make_unique<StateMachine>(std::move(engine)); _stateMachine = std::make_unique<StateMachine>(std::move(engine));

View File

@@ -117,7 +117,7 @@ SCREEN_INFORMATION::~SCREEN_INFORMATION()
defaultAttributes, defaultAttributes,
uiCursorSize, uiCursorSize,
pScreen->IsActiveScreenBuffer(), pScreen->IsActiveScreenBuffer(),
*ServiceLocator::LocateGlobals().pRender); ServiceLocator::LocateGlobals().pRender);
const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
pScreen->_textBuffer->GetCursor().SetType(gci.GetCursorType()); pScreen->_textBuffer->GetCursor().SetType(gci.GetCursorType());
@@ -253,10 +253,9 @@ void SCREEN_INFORMATION::s_RemoveScreenBuffer(_In_ SCREEN_INFORMATION* const pSc
{ {
auto& g = ServiceLocator::LocateGlobals(); auto& g = ServiceLocator::LocateGlobals();
auto& gci = g.getConsoleInformation(); auto& gci = g.getConsoleInformation();
auto& renderer = *g.pRender;
auto& renderSettings = gci.GetRenderSettings(); auto& renderSettings = gci.GetRenderSettings();
auto& terminalInput = gci.GetActiveInputBuffer()->GetTerminalInput(); auto& terminalInput = gci.GetActiveInputBuffer()->GetTerminalInput();
auto adapter = std::make_unique<AdaptDispatch>(_api, renderer, renderSettings, terminalInput); auto adapter = std::make_unique<AdaptDispatch>(_api, g.pRender, renderSettings, terminalInput);
auto engine = std::make_unique<OutputStateMachineEngine>(std::move(adapter)); auto engine = std::make_unique<OutputStateMachineEngine>(std::move(adapter));
// Note that at this point in the setup, we haven't determined if we're // Note that at this point in the setup, we haven't determined if we're
// in VtIo mode or not yet. We'll set the OutputStateMachine's // in VtIo mode or not yet. We'll set the OutputStateMachine's

View File

@@ -1542,7 +1542,7 @@ void TextBufferTests::ResizeTraditional()
const til::size smallSize = { 5, 5 }; const til::size smallSize = { 5, 5 };
const TextAttribute defaultAttr(0); const TextAttribute defaultAttr(0);
TextBuffer buffer(smallSize, defaultAttr, 12, false, _renderer); TextBuffer buffer(smallSize, defaultAttr, 12, false, &_renderer);
Log::Comment(L"Fill buffer with some data and do assorted resize operations."); Log::Comment(L"Fill buffer with some data and do assorted resize operations.");
@@ -1638,7 +1638,7 @@ void TextBufferTests::ResizeTraditionalRotationPreservesHighUnicode()
const til::size bufferSize{ 80, 10 }; const til::size bufferSize{ 80, 10 };
const UINT cursorSize = 12; const UINT cursorSize = 12;
const TextAttribute attr{ 0x7f }; const TextAttribute attr{ 0x7f };
auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer); auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, &_renderer);
// Get a position inside the buffer // Get a position inside the buffer
const til::point pos{ 2, 1 }; const til::point pos{ 2, 1 };
@@ -1679,7 +1679,7 @@ void TextBufferTests::ScrollBufferRotationPreservesHighUnicode()
const til::size bufferSize{ 80, 10 }; const til::size bufferSize{ 80, 10 };
const UINT cursorSize = 12; const UINT cursorSize = 12;
const TextAttribute attr{ 0x7f }; const TextAttribute attr{ 0x7f };
auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer); auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, &_renderer);
// Get a position inside the buffer // Get a position inside the buffer
const til::point pos{ 2, 1 }; const til::point pos{ 2, 1 };
@@ -1714,7 +1714,7 @@ void TextBufferTests::ResizeTraditionalHighUnicodeRowRemoval()
const til::size bufferSize{ 80, 10 }; const til::size bufferSize{ 80, 10 };
const UINT cursorSize = 12; const UINT cursorSize = 12;
const TextAttribute attr{ 0x7f }; const TextAttribute attr{ 0x7f };
auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer); auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, &_renderer);
// Get a position inside the buffer in the bottom row // Get a position inside the buffer in the bottom row
const til::point pos{ 0, bufferSize.height - 1 }; const til::point pos{ 0, bufferSize.height - 1 };
@@ -1744,7 +1744,7 @@ void TextBufferTests::ResizeTraditionalHighUnicodeColumnRemoval()
const til::size bufferSize{ 80, 10 }; const til::size bufferSize{ 80, 10 };
const UINT cursorSize = 12; const UINT cursorSize = 12;
const TextAttribute attr{ 0x7f }; const TextAttribute attr{ 0x7f };
auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer); auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, &_renderer);
// Get a position inside the buffer in the last column (-2 as the inserted character is 2 columns wide). // Get a position inside the buffer in the last column (-2 as the inserted character is 2 columns wide).
const til::point pos{ bufferSize.width - 2, 0 }; const til::point pos{ bufferSize.width - 2, 0 };
@@ -1771,7 +1771,7 @@ void TextBufferTests::TestOverwriteChars()
til::size bufferSize{ 10, 3 }; til::size bufferSize{ 10, 3 };
UINT cursorSize = 12; UINT cursorSize = 12;
TextAttribute attr{ 0x7f }; TextAttribute attr{ 0x7f };
TextBuffer buffer{ bufferSize, attr, cursorSize, false, _renderer }; TextBuffer buffer{ bufferSize, attr, cursorSize, false, &_renderer };
auto& row = buffer.GetMutableRowByOffset(0); auto& row = buffer.GetMutableRowByOffset(0);
// scientist emoji U+1F9D1 U+200D U+1F52C // scientist emoji U+1F9D1 U+200D U+1F52C
@@ -1827,7 +1827,7 @@ void TextBufferTests::TestReplace()
static constexpr til::size bufferSize{ 10, 3 }; static constexpr til::size bufferSize{ 10, 3 };
static constexpr UINT cursorSize = 12; static constexpr UINT cursorSize = 12;
const TextAttribute attr{ 0x7f }; const TextAttribute attr{ 0x7f };
TextBuffer buffer{ bufferSize, attr, cursorSize, false, _renderer }; TextBuffer buffer{ bufferSize, attr, cursorSize, false, &_renderer };
#define complex L"\U0001F41B" #define complex L"\U0001F41B"
@@ -1909,7 +1909,7 @@ void TextBufferTests::TestInsert()
static constexpr TextAttribute attr1{ 0x11111111, 0x00000000 }; static constexpr TextAttribute attr1{ 0x11111111, 0x00000000 };
static constexpr TextAttribute attr2{ 0x22222222, 0x00000000 }; static constexpr TextAttribute attr2{ 0x22222222, 0x00000000 };
static constexpr TextAttribute attr3{ 0x33333333, 0x00000000 }; static constexpr TextAttribute attr3{ 0x33333333, 0x00000000 };
TextBuffer buffer{ bufferSize, attr1, cursorSize, false, _renderer }; TextBuffer buffer{ bufferSize, attr1, cursorSize, false, &_renderer };
struct Test struct Test
{ {
@@ -2048,7 +2048,7 @@ void TextBufferTests::GetWordBoundaries()
til::size bufferSize{ 80, 9001 }; til::size bufferSize{ 80, 9001 };
UINT cursorSize = 12; UINT cursorSize = 12;
TextAttribute attr{ 0x7f }; TextAttribute attr{ 0x7f };
auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer); auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, &_renderer);
// Setup: Write lines of text to the buffer // Setup: Write lines of text to the buffer
const std::vector<std::wstring> text = { L"word other", const std::vector<std::wstring> text = { L"word other",
@@ -2264,7 +2264,7 @@ void TextBufferTests::MoveByWord()
til::size bufferSize{ 80, 9001 }; til::size bufferSize{ 80, 9001 };
UINT cursorSize = 12; UINT cursorSize = 12;
TextAttribute attr{ 0x7f }; TextAttribute attr{ 0x7f };
auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer); auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, &_renderer);
// Setup: Write lines of text to the buffer // Setup: Write lines of text to the buffer
const std::vector<std::wstring> text = { L"word other", const std::vector<std::wstring> text = { L"word other",
@@ -2371,7 +2371,7 @@ void TextBufferTests::GetGlyphBoundaries()
til::size bufferSize{ 10, 10 }; til::size bufferSize{ 10, 10 };
UINT cursorSize = 12; UINT cursorSize = 12;
TextAttribute attr{ 0x7f }; TextAttribute attr{ 0x7f };
auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer); auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, &_renderer);
// This is the burrito emoji: 🌯 // This is the burrito emoji: 🌯
// It's encoded in UTF-16, as needed by the buffer. // It's encoded in UTF-16, as needed by the buffer.
@@ -2407,7 +2407,7 @@ void TextBufferTests::GetTextRects()
til::size bufferSize{ 20, 50 }; til::size bufferSize{ 20, 50 };
UINT cursorSize = 12; UINT cursorSize = 12;
TextAttribute attr{ 0x7f }; TextAttribute attr{ 0x7f };
auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer); auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, &_renderer);
// Setup: Write lines of text to the buffer // Setup: Write lines of text to the buffer
const std::vector<std::wstring> text = { L"0123456789", const std::vector<std::wstring> text = { L"0123456789",
@@ -2487,7 +2487,7 @@ void TextBufferTests::GetPlainText()
til::size bufferSize{ 10, 20 }; til::size bufferSize{ 10, 20 };
UINT cursorSize = 12; UINT cursorSize = 12;
TextAttribute attr{ 0x7f }; TextAttribute attr{ 0x7f };
auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer); auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, &_renderer);
// Setup: Write lines of text to the buffer // Setup: Write lines of text to the buffer
const std::vector<std::wstring> bufferText = { L"12345", const std::vector<std::wstring> bufferText = { L"12345",
@@ -2575,7 +2575,7 @@ void TextBufferTests::GetPlainText()
til::size bufferSize{ 5, 20 }; til::size bufferSize{ 5, 20 };
UINT cursorSize = 12; UINT cursorSize = 12;
TextAttribute attr{ 0x7f }; TextAttribute attr{ 0x7f };
auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer); auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, &_renderer);
// Setup: Write lines of text to the buffer // Setup: Write lines of text to the buffer
const std::vector<std::wstring> bufferText = { L"1234567", const std::vector<std::wstring> bufferText = { L"1234567",
@@ -2704,7 +2704,7 @@ void TextBufferTests::HyperlinkTrim()
const til::size bufferSize{ 80, 10 }; const til::size bufferSize{ 80, 10 };
const UINT cursorSize = 12; const UINT cursorSize = 12;
const TextAttribute attr{ 0x7f }; const TextAttribute attr{ 0x7f };
auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer); auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, &_renderer);
static constexpr std::wstring_view url{ L"test.url" }; static constexpr std::wstring_view url{ L"test.url" };
static constexpr std::wstring_view otherUrl{ L"other.url" }; static constexpr std::wstring_view otherUrl{ L"other.url" };
@@ -2750,7 +2750,7 @@ void TextBufferTests::NoHyperlinkTrim()
const til::size bufferSize{ 80, 10 }; const til::size bufferSize{ 80, 10 };
const UINT cursorSize = 12; const UINT cursorSize = 12;
const TextAttribute attr{ 0x7f }; const TextAttribute attr{ 0x7f };
auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, _renderer); auto _buffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, false, &_renderer);
static constexpr std::wstring_view url{ L"test.url" }; static constexpr std::wstring_view url{ L"test.url" };
static constexpr std::wstring_view customId{ L"CustomId" }; static constexpr std::wstring_view customId{ L"CustomId" };
@@ -2902,7 +2902,7 @@ void TextBufferTests::ReflowPromptRegions()
// After we resize, make sure to get the new textBuffers // After we resize, make sure to get the new textBuffers
til::size newSize{ oldSize.Width() + dx, oldSize.Height() }; til::size newSize{ oldSize.Width() + dx, oldSize.Height() };
auto newBuffer = std::make_unique<TextBuffer>(newSize, TextAttribute{ 0x7 }, 0, false, _renderer); auto newBuffer = std::make_unique<TextBuffer>(newSize, TextAttribute{ 0x7 }, 0, false, &_renderer);
TextBuffer::Reflow(*tbi, *newBuffer); TextBuffer::Reflow(*tbi, *newBuffer);
Log::Comment(L"========== Checking the host buffer state (after) =========="); Log::Comment(L"========== Checking the host buffer state (after) ==========");

View File

@@ -188,7 +188,7 @@ public:
initialAttributes, initialAttributes,
uiCursorSize, uiCursorSize,
true, true,
*g.pRender); g.pRender);
if (textBuffer.get() == nullptr) if (textBuffer.get() == nullptr)
{ {
m_hrTextBufferInfo = E_OUTOFMEMORY; m_hrTextBufferInfo = E_OUTOFMEMORY;

View File

@@ -259,7 +259,7 @@ COLORREF RenderSettings::GetAttributeUnderlineColor(const TextAttribute& attr) c
// renderer if there are blinking cells currently in view. // renderer if there are blinking cells currently in view.
// Arguments: // Arguments:
// - renderer: the renderer that will be redrawn. // - renderer: the renderer that will be redrawn.
void RenderSettings::ToggleBlinkRendition(Renderer& renderer) noexcept void RenderSettings::ToggleBlinkRendition(Renderer* renderer) noexcept
try try
{ {
if (GetRenderMode(Mode::BlinkAllowed)) if (GetRenderMode(Mode::BlinkAllowed))
@@ -277,7 +277,10 @@ try
// We reset the _blinkIsInUse flag before redrawing, so we can // We reset the _blinkIsInUse flag before redrawing, so we can
// get a fresh assessment of the current blink attribute usage. // get a fresh assessment of the current blink attribute usage.
_blinkIsInUse = false; _blinkIsInUse = false;
renderer.TriggerRedrawAll(); if (renderer)
{
renderer->TriggerRedrawAll();
}
} }
} }
} }

View File

@@ -42,7 +42,7 @@ namespace Microsoft::Console::Render
std::pair<COLORREF, COLORREF> GetAttributeColors(const TextAttribute& attr) const noexcept; std::pair<COLORREF, COLORREF> GetAttributeColors(const TextAttribute& attr) const noexcept;
std::pair<COLORREF, COLORREF> GetAttributeColorsWithAlpha(const TextAttribute& attr) const noexcept; std::pair<COLORREF, COLORREF> GetAttributeColorsWithAlpha(const TextAttribute& attr) const noexcept;
COLORREF GetAttributeUnderlineColor(const TextAttribute& attr) const noexcept; COLORREF GetAttributeUnderlineColor(const TextAttribute& attr) const noexcept;
void ToggleBlinkRendition(class Renderer& renderer) noexcept; void ToggleBlinkRendition(class Renderer* renderer) noexcept;
private: private:
til::enumset<Mode> _renderMode{ Mode::BlinkAllowed, Mode::IntenseIsBright }; til::enumset<Mode> _renderMode{ Mode::BlinkAllowed, Mode::IntenseIsBright };

View File

@@ -99,7 +99,7 @@ void Page::MoveViewportDown() noexcept
_viewport.bottom++; _viewport.bottom++;
} }
PageManager::PageManager(ITerminalApi& api, Renderer& renderer) noexcept : PageManager::PageManager(ITerminalApi& api, Renderer* renderer) noexcept :
_api{ api }, _api{ api },
_renderer{ renderer } _renderer{ renderer }
{ {
@@ -220,9 +220,9 @@ void PageManager::MoveTo(const til::CoordType pageNumber, const bool makeVisible
} }
_activePageNumber = newPageNumber; _activePageNumber = newPageNumber;
if (redrawRequired) if (redrawRequired && _renderer)
{ {
_renderer.TriggerRedrawAll(); _renderer->TriggerRedrawAll();
} }
} }

View File

@@ -46,7 +46,7 @@ namespace Microsoft::Console::VirtualTerminal
using Renderer = Microsoft::Console::Render::Renderer; using Renderer = Microsoft::Console::Render::Renderer;
public: public:
PageManager(ITerminalApi& api, Renderer& renderer) noexcept; PageManager(ITerminalApi& api, Renderer* renderer) noexcept;
void Reset(); void Reset();
Page Get(const til::CoordType pageNumber) const; Page Get(const til::CoordType pageNumber) const;
Page ActivePage() const; Page ActivePage() const;
@@ -59,7 +59,7 @@ namespace Microsoft::Console::VirtualTerminal
TextBuffer& _getBuffer(const til::CoordType pageNumber, const til::size pageSize) const; TextBuffer& _getBuffer(const til::CoordType pageNumber, const til::size pageSize) const;
ITerminalApi& _api; ITerminalApi& _api;
Renderer& _renderer; Renderer* _renderer;
til::CoordType _activePageNumber = 1; til::CoordType _activePageNumber = 1;
til::CoordType _visiblePageNumber = 1; til::CoordType _visiblePageNumber = 1;
static constexpr til::CoordType MAX_PAGES = 6; static constexpr til::CoordType MAX_PAGES = 6;

View File

@@ -16,7 +16,7 @@ using namespace Microsoft::Console::VirtualTerminal;
static constexpr std::wstring_view whitespace{ L" " }; static constexpr std::wstring_view whitespace{ L" " };
AdaptDispatch::AdaptDispatch(ITerminalApi& api, Renderer& renderer, RenderSettings& renderSettings, TerminalInput& terminalInput) noexcept : AdaptDispatch::AdaptDispatch(ITerminalApi& api, Renderer* renderer, RenderSettings& renderSettings, TerminalInput& terminalInput) noexcept :
_api{ api }, _api{ api },
_renderer{ renderer }, _renderer{ renderer },
_renderSettings{ renderSettings }, _renderSettings{ renderSettings },
@@ -1937,7 +1937,10 @@ bool AdaptDispatch::_ModeParamsHelper(const DispatchTypes::ModeParams param, con
{ {
return false; return false;
} }
_renderer.TriggerRedrawAll(); if (_renderer)
{
_renderer->TriggerRedrawAll();
}
return true; return true;
case DispatchTypes::ModeParams::DECOM_OriginMode: case DispatchTypes::ModeParams::DECOM_OriginMode:
_modes.set(Mode::Origin, enable); _modes.set(Mode::Origin, enable);
@@ -3221,7 +3224,10 @@ bool AdaptDispatch::HardReset()
TabSet(DispatchTypes::TabSetType::SetEvery8Columns); TabSet(DispatchTypes::TabSetType::SetEvery8Columns);
// Clear the soft font in the renderer and delete the font buffer. // Clear the soft font in the renderer and delete the font buffer.
_renderer.UpdateSoftFont({}, {}, false); if (_renderer)
{
_renderer->UpdateSoftFont({}, {}, false);
}
_fontBuffer = nullptr; _fontBuffer = nullptr;
// Reset internal modes to their initial state // Reset internal modes to their initial state
@@ -3501,18 +3507,20 @@ bool AdaptDispatch::SetColorTableEntry(const size_t tableIndex, const DWORD dwCo
return false; return false;
} }
// If we're updating the background color, we need to let the renderer if (_renderer)
// know, since it may want to repaint the window background to match. {
const auto backgroundIndex = _renderSettings.GetColorAliasIndex(ColorAlias::DefaultBackground); // If we're updating the background color, we need to let the renderer
const auto backgroundChanged = (tableIndex == backgroundIndex); // know, since it may want to repaint the window background to match.
const auto backgroundIndex = _renderSettings.GetColorAliasIndex(ColorAlias::DefaultBackground);
const auto backgroundChanged = (tableIndex == backgroundIndex);
// Similarly for the frame color, the tab may need to be repainted. // Similarly for the frame color, the tab may need to be repainted.
const auto frameIndex = _renderSettings.GetColorAliasIndex(ColorAlias::FrameBackground); const auto frameIndex = _renderSettings.GetColorAliasIndex(ColorAlias::FrameBackground);
const auto frameChanged = (tableIndex == frameIndex); const auto frameChanged = (tableIndex == frameIndex);
_renderer->TriggerRedrawAll(backgroundChanged, frameChanged);
}
// Update the screen colors if we're not a pty
// No need to force a redraw in pty mode.
_renderer.TriggerRedrawAll(backgroundChanged, frameChanged);
return true; return true;
} }
@@ -3566,14 +3574,19 @@ bool AdaptDispatch::AssignColor(const DispatchTypes::ColorItem item, const VTInt
} }
// No need to force a redraw in pty mode. // No need to force a redraw in pty mode.
const auto inPtyMode = _api.IsConsolePty(); if (_api.IsConsolePty())
if (!inPtyMode) {
return false;
}
if (_renderer)
{ {
const auto backgroundChanged = item == DispatchTypes::ColorItem::NormalText; const auto backgroundChanged = item == DispatchTypes::ColorItem::NormalText;
const auto frameChanged = item == DispatchTypes::ColorItem::WindowFrame; const auto frameChanged = item == DispatchTypes::ColorItem::WindowFrame;
_renderer.TriggerRedrawAll(backgroundChanged, frameChanged); _renderer->TriggerRedrawAll(backgroundChanged, frameChanged);
} }
return !inPtyMode;
return true;
} }
//Routine Description: //Routine Description:
@@ -3769,11 +3782,11 @@ bool AdaptDispatch::DoConEmuAction(const std::wstring_view string)
bool AdaptDispatch::DoITerm2Action(const std::wstring_view string) bool AdaptDispatch::DoITerm2Action(const std::wstring_view string)
{ {
const auto isConPty = _api.IsConsolePty(); const auto isConPty = _api.IsConsolePty();
if (isConPty) if (isConPty && _renderer)
{ {
// Flush the frame manually, to make sure marks end up on the right // Flush the frame manually, to make sure marks end up on the right
// line, like the alt buffer sequence. // line, like the alt buffer sequence.
_renderer.TriggerFlush(false); _renderer->TriggerFlush(false);
} }
if constexpr (!Feature_ScrollbarMarks::IsEnabled()) if constexpr (!Feature_ScrollbarMarks::IsEnabled())
@@ -3813,11 +3826,11 @@ bool AdaptDispatch::DoITerm2Action(const std::wstring_view string)
bool AdaptDispatch::DoFinalTermAction(const std::wstring_view string) bool AdaptDispatch::DoFinalTermAction(const std::wstring_view string)
{ {
const auto isConPty = _api.IsConsolePty(); const auto isConPty = _api.IsConsolePty();
if (isConPty) if (isConPty && _renderer)
{ {
// Flush the frame manually, to make sure marks end up on the right // Flush the frame manually, to make sure marks end up on the right
// line, like the alt buffer sequence. // line, like the alt buffer sequence.
_renderer.TriggerFlush(false); _renderer->TriggerFlush(false);
} }
if constexpr (!Feature_ScrollbarMarks::IsEnabled()) if constexpr (!Feature_ScrollbarMarks::IsEnabled())
@@ -3904,10 +3917,10 @@ bool AdaptDispatch::DoFinalTermAction(const std::wstring_view string)
bool AdaptDispatch::DoVsCodeAction(const std::wstring_view string) bool AdaptDispatch::DoVsCodeAction(const std::wstring_view string)
{ {
// This is not implemented in conhost. // This is not implemented in conhost.
if (_api.IsConsolePty()) if (_api.IsConsolePty() && _renderer)
{ {
// Flush the frame manually to make sure this action happens at the right time. // Flush the frame manually to make sure this action happens at the right time.
_renderer.TriggerFlush(false); _renderer->TriggerFlush(false);
return false; return false;
} }
@@ -4048,10 +4061,13 @@ ITermDispatch::StringHandler AdaptDispatch::DownloadDRCS(const VTInt fontNumber,
{ {
_termOutput.SetDrcs94Designation(_fontBuffer->GetDesignation()); _termOutput.SetDrcs94Designation(_fontBuffer->GetDesignation());
} }
const auto bitPattern = _fontBuffer->GetBitPattern(); if (_renderer)
const auto cellSize = _fontBuffer->GetCellSize(); {
const auto centeringHint = _fontBuffer->GetTextCenteringHint(); const auto bitPattern = _fontBuffer->GetBitPattern();
_renderer.UpdateSoftFont(bitPattern, cellSize, centeringHint); const auto cellSize = _fontBuffer->GetCellSize();
const auto centeringHint = _fontBuffer->GetTextCenteringHint();
_renderer->UpdateSoftFont(bitPattern, cellSize, centeringHint);
}
} }
return true; return true;
}; };
@@ -4912,9 +4928,9 @@ bool AdaptDispatch::PlaySounds(const VTParameters parameters)
// If we're a conpty, we return false so the command will be passed on // If we're a conpty, we return false so the command will be passed on
// to the connected terminal. But we need to flush the current frame // to the connected terminal. But we need to flush the current frame
// first, otherwise the visual output will lag behind the sound. // first, otherwise the visual output will lag behind the sound.
if (_api.IsConsolePty()) if (_api.IsConsolePty() && _renderer)
{ {
_renderer.TriggerFlush(false); _renderer->TriggerFlush(false);
return false; return false;
} }
@@ -4948,7 +4964,11 @@ ITermDispatch::StringHandler AdaptDispatch::_CreatePassthroughHandler()
{ {
// Before we pass through any more data, we need to flush the current frame // Before we pass through any more data, we need to flush the current frame
// first, otherwise it can end up arriving out of sync. // first, otherwise it can end up arriving out of sync.
_renderer.TriggerFlush(false); if (_renderer)
{
_renderer->TriggerFlush(false);
}
// Then we need to flush the sequence introducer and parameters that have // Then we need to flush the sequence introducer and parameters that have
// already been parsed by the state machine. // already been parsed by the state machine.
auto& stateMachine = _api.GetStateMachine(); auto& stateMachine = _api.GetStateMachine();

View File

@@ -36,7 +36,7 @@ namespace Microsoft::Console::VirtualTerminal
using RenderSettings = Microsoft::Console::Render::RenderSettings; using RenderSettings = Microsoft::Console::Render::RenderSettings;
public: public:
AdaptDispatch(ITerminalApi& api, Renderer& renderer, RenderSettings& renderSettings, TerminalInput& terminalInput) noexcept; AdaptDispatch(ITerminalApi& api, Renderer* renderer, RenderSettings& renderSettings, TerminalInput& terminalInput) noexcept;
void Print(const wchar_t wchPrintable) override; void Print(const wchar_t wchPrintable) override;
void PrintString(const std::wstring_view string) override; void PrintString(const std::wstring_view string) override;
@@ -286,7 +286,7 @@ namespace Microsoft::Console::VirtualTerminal
bool _initDefaultTabStops = true; bool _initDefaultTabStops = true;
ITerminalApi& _api; ITerminalApi& _api;
Renderer& _renderer; Renderer* _renderer;
RenderSettings& _renderSettings; RenderSettings& _renderSettings;
TerminalInput& _terminalInput; TerminalInput& _terminalInput;
TerminalOutput _termOutput; TerminalOutput _termOutput;

View File

@@ -250,7 +250,7 @@ public:
_setTextAttributesResult = TRUE; _setTextAttributesResult = TRUE;
_returnResponseResult = TRUE; _returnResponseResult = TRUE;
_textBuffer = std::make_unique<TextBuffer>(til::size{ 100, 600 }, TextAttribute{}, 0, false, _renderer); _textBuffer = std::make_unique<TextBuffer>(til::size{ 100, 600 }, TextAttribute{}, 0, false, &_renderer);
// Viewport sitting in the "middle" of the buffer somewhere (so all sides have excess buffer around them) // Viewport sitting in the "middle" of the buffer somewhere (so all sides have excess buffer around them)
_viewport.top = 20; _viewport.top = 20;
@@ -406,7 +406,7 @@ public:
_terminalInput = TerminalInput{}; _terminalInput = TerminalInput{};
auto& renderer = _testGetSet->_renderer; auto& renderer = _testGetSet->_renderer;
auto& renderSettings = renderer._renderSettings; auto& renderSettings = renderer._renderSettings;
auto adapter = std::make_unique<AdaptDispatch>(*_testGetSet, renderer, renderSettings, _terminalInput); auto adapter = std::make_unique<AdaptDispatch>(*_testGetSet, &renderer, renderSettings, _terminalInput);
fSuccess = adapter.get() != nullptr; fSuccess = adapter.get() != nullptr;
if (fSuccess) if (fSuccess)
@@ -2448,7 +2448,7 @@ public:
Log::Comment(L"Starting test..."); Log::Comment(L"Starting test...");
til::inclusive_rect srTestMargins; til::inclusive_rect srTestMargins;
_testGetSet->_textBuffer = std::make_unique<TextBuffer>(til::size{ 100, 600 }, TextAttribute{}, 0, false, _testGetSet->_renderer); _testGetSet->_textBuffer = std::make_unique<TextBuffer>(til::size{ 100, 600 }, TextAttribute{}, 0, false, &_testGetSet->_renderer);
_testGetSet->_viewport.right = 8; _testGetSet->_viewport.right = 8;
_testGetSet->_viewport.bottom = 8; _testGetSet->_viewport.bottom = 8;
auto sScreenHeight = _testGetSet->_viewport.bottom - _testGetSet->_viewport.top; auto sScreenHeight = _testGetSet->_viewport.bottom - _testGetSet->_viewport.top;