diff --git a/src/buffer/out/search.cpp b/src/buffer/out/search.cpp index 9707e8fdeaa..fd8942e0bac 100644 --- a/src/buffer/out/search.cpp +++ b/src/buffer/out/search.cpp @@ -111,6 +111,28 @@ const til::point_span* Search::GetCurrent() const noexcept return nullptr; } +void Search::HighlightResults() const +{ + std::vector toSelect; + const auto& textBuffer = _renderData->GetTextBuffer(); + + for (const auto& r : _results) + { + const auto rbStart = textBuffer.BufferToScreenPosition(r.start); + const auto rbEnd = textBuffer.BufferToScreenPosition(r.end); + + til::inclusive_rect re; + re.top = rbStart.y; + re.bottom = rbEnd.y; + re.left = rbStart.x; + re.right = rbEnd.x; + + toSelect.emplace_back(re); + } + + _renderData->SelectSearchRegions(std::move(toSelect)); +} + // Routine Description: // - Takes the found word and selects it in the screen buffer @@ -127,6 +149,7 @@ bool Search::SelectCurrent() const return true; } + _renderData->ClearSelection(); return false; } diff --git a/src/buffer/out/search.h b/src/buffer/out/search.h index c2d035e3e9c..a338f1272c4 100644 --- a/src/buffer/out/search.h +++ b/src/buffer/out/search.h @@ -33,6 +33,7 @@ class Search final void FindNext() noexcept; const til::point_span* GetCurrent() const noexcept; + void HighlightResults() const; bool SelectCurrent() const; const std::vector& Results() const noexcept; diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 734e1b98d2a..4efcabf711a 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -1652,6 +1652,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation if (_searcher.ResetIfStale(*GetRenderData(), text, !goForward, !caseSensitive)) { + _searcher.HighlightResults(); _searcher.MoveToCurrentSelection(); _cachedSearchResultRows = {}; } @@ -1668,7 +1669,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation // DO NOT call _updateSelectionUI() here. // We don't want to show the markers so manually tell it to clear it. _terminal->SetBlockSelection(false); - _renderer->TriggerSelection(); _UpdateSelectionMarkersHandlers(*this, winrt::make(true)); foundResults->TotalMatches(gsl::narrow(_searcher.Results().size())); @@ -1676,6 +1676,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation _terminal->AlwaysNotifyOnBufferRotation(true); } + _renderer->TriggerSelection(); // Raise a FoundMatch event, which the control will use to notify // narrator if there was any results in the buffer diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index 3e2ffe4c083..603e0e521ba 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -215,10 +215,12 @@ class Microsoft::Terminal::Core::Terminal final : std::pair GetAttributeColors(const TextAttribute& attr) const noexcept override; std::vector GetSelectionRects() noexcept override; + std::vector GetSearchSelectionRects() noexcept override; const bool IsSelectionActive() const noexcept override; const bool IsBlockSelection() const noexcept override; void ClearSelection() override; void SelectNewRegion(const til::point coordStart, const til::point coordEnd) override; + void SelectSearchRegions(std::vector source) override; const til::point GetSelectionAnchor() const noexcept override; const til::point GetSelectionEnd() const noexcept override; const std::wstring_view GetConsoleTitle() const noexcept override; @@ -377,6 +379,7 @@ class Microsoft::Terminal::Core::Terminal final : til::point pivot; }; std::optional _selection; + std::vector _searchSelections; bool _blockSelection = false; std::wstring _wordDelimiters; SelectionExpansion _multiClickSelectionMode = SelectionExpansion::Char; @@ -464,6 +467,7 @@ class Microsoft::Terminal::Core::Terminal final : #pragma region TextSelection // These methods are defined in TerminalSelection.cpp std::vector _GetSelectionRects() const noexcept; + std::vector _GetSearchSelectionRects(Microsoft::Console::Types::Viewport viewport) const noexcept; std::vector _GetSelectionSpans() const noexcept; std::pair _PivotSelection(const til::point targetPos, bool& targetStart) const noexcept; std::pair _ExpandSelectionAnchors(std::pair anchors) const; diff --git a/src/cascadia/TerminalCore/TerminalSelection.cpp b/src/cascadia/TerminalCore/TerminalSelection.cpp index 1978f5738bc..cfbc004b7d7 100644 --- a/src/cascadia/TerminalCore/TerminalSelection.cpp +++ b/src/cascadia/TerminalCore/TerminalSelection.cpp @@ -63,6 +63,40 @@ std::vector Terminal::_GetSelectionRects() const noexcept return result; } +// Method Description: +// - Helper to determine the selected region of the buffer. Used for rendering. +// Return Value: +// - A vector of rectangles representing the regions to select, line by line. They are absolute coordinates relative to the buffer origin. +std::vector Terminal::_GetSearchSelectionRects(Microsoft::Console::Types::Viewport viewport) const noexcept +{ + std::vector result; + try + { + auto lowerIt = std::lower_bound(_searchSelections.begin(), _searchSelections.end(), viewport.Top(), [](const til::inclusive_rect& rect, til::CoordType value) { + return rect.top < value; + }); + + auto upperIt = std::upper_bound(_searchSelections.begin(), _searchSelections.end(), viewport.BottomExclusive(), [](til::CoordType value, const til::inclusive_rect& rect) { + return value < rect.top; + }); + + for (auto selection = lowerIt; selection != upperIt; ++selection) + { + const auto start = til::point{ selection->left, selection->top }; + const auto end = til::point{ selection->right, selection->top }; + const auto adj = _activeBuffer().GetTextRects(start, end, _blockSelection, false); + for (auto a : adj) + { + result.emplace_back(a); + } + } + + return result; + } + CATCH_LOG(); + return result; +} + // Method Description: // - Identical to GetTextRects if it's a block selection, else returns a single span for the whole selection. // Return Value: @@ -824,6 +858,7 @@ void Terminal::_MoveByBuffer(SelectionDirection direction, til::point& pos) noex void Terminal::ClearSelection() { _assertLocked(); + _searchSelections.clear(); _selection = std::nullopt; _selectionMode = SelectionInteractionMode::None; _selectionIsTargetingUrl = false; diff --git a/src/cascadia/TerminalCore/terminalrenderdata.cpp b/src/cascadia/TerminalCore/terminalrenderdata.cpp index 034a65ab784..8dd9b4dae9a 100644 --- a/src/cascadia/TerminalCore/terminalrenderdata.cpp +++ b/src/cascadia/TerminalCore/terminalrenderdata.cpp @@ -150,6 +150,24 @@ catch (...) return {}; } +std::vector Terminal::GetSearchSelectionRects() noexcept +try +{ + std::vector result; + + for (const auto& lineRect : _GetSearchSelectionRects(_GetVisibleViewport())) + { + result.emplace_back(Viewport::FromInclusive(lineRect)); + } + + return result; +} +catch (...) +{ + LOG_CAUGHT_EXCEPTION(); + return {}; +} + void Terminal::SelectNewRegion(const til::point coordStart, const til::point coordEnd) { #pragma warning(push) @@ -188,6 +206,23 @@ void Terminal::SelectNewRegion(const til::point coordStart, const til::point coo SetSelectionEnd(realCoordEnd, SelectionExpansion::Char); } +void Terminal::SelectSearchRegions(std::vector rects) +{ + _searchSelections.clear(); + for (auto& rect : rects) + { + rect.top -= _VisibleStartIndex(); + rect.bottom -= _VisibleStartIndex(); + + const auto realStart = _ConvertToBufferCell(til::point{ rect.left, rect.top }); + const auto realEnd = _ConvertToBufferCell(til::point{ rect.right, rect.bottom }); + + auto rr = til::inclusive_rect{ realStart.x, realStart.y, realEnd.x, realEnd.y }; + + _searchSelections.emplace_back(rr); + } +} + const std::wstring_view Terminal::GetConsoleTitle() const noexcept { _assertLocked(); diff --git a/src/cascadia/UnitTests_TerminalCore/ScrollTest.cpp b/src/cascadia/UnitTests_TerminalCore/ScrollTest.cpp index d5baebadf26..21022f30333 100644 --- a/src/cascadia/UnitTests_TerminalCore/ScrollTest.cpp +++ b/src/cascadia/UnitTests_TerminalCore/ScrollTest.cpp @@ -59,6 +59,7 @@ namespace HRESULT PaintBufferLine(std::span /*clusters*/, til::point /*coord*/, bool /*fTrimLeft*/, bool /*lineWrapped*/) noexcept { return S_OK; } HRESULT PaintBufferGridLines(GridLineSet /*lines*/, COLORREF /*gridlineColor*/, COLORREF /*underlineColor*/, size_t /*cchLine*/, til::point /*coordTarget*/) noexcept { return S_OK; } HRESULT PaintSelection(const til::rect& /*rect*/) noexcept { return S_OK; } + HRESULT PaintSelections(const std::vector& /*rects*/) noexcept { return S_OK; } HRESULT PaintCursor(const CursorOptions& /*options*/) noexcept { return S_OK; } HRESULT UpdateDrawingBrushes(const TextAttribute& /*textAttributes*/, const RenderSettings& /*renderSettings*/, gsl::not_null /*pData*/, bool /*usingSoftFont*/, bool /*isSettingDefaultBrushes*/) noexcept { return S_OK; } HRESULT UpdateFont(const FontInfoDesired& /*FontInfoDesired*/, _Out_ FontInfo& /*FontInfo*/) noexcept { return S_OK; } diff --git a/src/host/renderData.cpp b/src/host/renderData.cpp index 5c89edae9a9..d9b094626ba 100644 --- a/src/host/renderData.cpp +++ b/src/host/renderData.cpp @@ -79,6 +79,16 @@ std::vector RenderData::GetSelectionRects() noexcept return result; } +// Method Description: +// - Retrieves one rectangle per line describing the area of the viewport +// that should be highlighted in some way to represent a user-interactive selection +// Return Value: +// - Vector of Viewports describing the area selected +std::vector RenderData::GetSearchSelectionRects() noexcept +{ + return {}; +} + // Method Description: // - Lock the console for reading the contents of the buffer. Ensures that the // contents of the console won't be changed in the middle of a paint @@ -371,6 +381,10 @@ void RenderData::SelectNewRegion(const til::point coordStart, const til::point c Selection::Instance().SelectNewRegion(coordStart, coordEnd); } +void RenderData::SelectSearchRegions(std::vector source) +{ +} + // Routine Description: // - Gets the current selection anchor position // Arguments: diff --git a/src/host/renderData.hpp b/src/host/renderData.hpp index 5e649353cd7..52056d7a6f5 100644 --- a/src/host/renderData.hpp +++ b/src/host/renderData.hpp @@ -26,6 +26,7 @@ class RenderData final : const FontInfo& GetFontInfo() const noexcept override; std::vector GetSelectionRects() noexcept override; + std::vector GetSearchSelectionRects() noexcept override; void LockConsole() noexcept override; void UnlockConsole() noexcept override; @@ -54,6 +55,7 @@ class RenderData final : const bool IsBlockSelection() const noexcept override; void ClearSelection() override; void SelectNewRegion(const til::point coordStart, const til::point coordEnd) override; + void SelectSearchRegions(std::vector source) override; const til::point GetSelectionAnchor() const noexcept override; const til::point GetSelectionEnd() const noexcept override; const bool IsUiaDataInitialized() const noexcept override { return true; } diff --git a/src/host/ut_host/VtIoTests.cpp b/src/host/ut_host/VtIoTests.cpp index 902f711771d..7f4796df60d 100644 --- a/src/host/ut_host/VtIoTests.cpp +++ b/src/host/ut_host/VtIoTests.cpp @@ -282,6 +282,11 @@ class MockRenderData : public IRenderData return std::vector{}; } + std::vector GetSearchSelectionRects() noexcept override + { + return std::vector{}; + } + void LockConsole() noexcept override { } @@ -363,6 +368,10 @@ class MockRenderData : public IRenderData { } + void SelectSearchRegions(std::vector /*source*/) override + { + } + const til::point GetSelectionAnchor() const noexcept { return {}; diff --git a/src/interactivity/onecore/BgfxEngine.cpp b/src/interactivity/onecore/BgfxEngine.cpp index d508603d5f9..a730ae8219e 100644 --- a/src/interactivity/onecore/BgfxEngine.cpp +++ b/src/interactivity/onecore/BgfxEngine.cpp @@ -161,6 +161,11 @@ CATCH_RETURN() return S_OK; } +[[nodiscard]] HRESULT BgfxEngine::PaintSelections(const std::vector& /*rects*/) noexcept +{ + return S_OK; +} + [[nodiscard]] HRESULT BgfxEngine::PaintCursor(const CursorOptions& options) noexcept try { diff --git a/src/interactivity/onecore/BgfxEngine.hpp b/src/interactivity/onecore/BgfxEngine.hpp index e9759ce0306..c787baba392 100644 --- a/src/interactivity/onecore/BgfxEngine.hpp +++ b/src/interactivity/onecore/BgfxEngine.hpp @@ -53,6 +53,7 @@ namespace Microsoft::Console::Render const bool lineWrapped) noexcept override; [[nodiscard]] HRESULT PaintBufferGridLines(const GridLineSet lines, const COLORREF gridlineColor, const COLORREF underlineColor, const size_t cchLine, const til::point coordTarget) noexcept override; [[nodiscard]] HRESULT PaintSelection(const til::rect& rect) noexcept override; + [[nodiscard]] HRESULT PaintSelections(const std::vector& rects) noexcept override; [[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override; diff --git a/src/renderer/atlas/AtlasEngine.cpp b/src/renderer/atlas/AtlasEngine.cpp index 7438b93543e..93821394ce1 100644 --- a/src/renderer/atlas/AtlasEngine.cpp +++ b/src/renderer/atlas/AtlasEngine.cpp @@ -414,6 +414,40 @@ try } CATCH_RETURN() +[[nodiscard]] HRESULT AtlasEngine::PaintSelections(const std::vector& rects) noexcept +try +{ + if (rects.empty()) + { + return S_OK; + } + + for (const auto& rect : rects) + { + const auto y = gsl::narrow_cast(clamp(rect.top, 0, _p.s->viewportCellCount.y)); + const auto from = gsl::narrow_cast(clamp(rect.left, 0, _p.s->viewportCellCount.x - 1)); + const auto to = gsl::narrow_cast(clamp(rect.right, from, _p.s->viewportCellCount.x)); + + if (rect.bottom <= 0 || rect.top >= _p.s->viewportCellCount.y) + { + continue; + } + + const auto bg = &_p.backgroundBitmap[_p.colorBitmapRowStride * y]; + const auto fg = &_p.foregroundBitmap[_p.colorBitmapRowStride * y]; + std::fill(bg + from, bg + to, 0xff3296ff); + std::fill(fg + from, fg + to, 0xff000000); + } + + for (int i = 0; i < 2; ++i) + { + _p.colorBitmapGenerations[i].bump(); + } + + return S_OK; +} +CATCH_RETURN() + [[nodiscard]] HRESULT AtlasEngine::PaintCursor(const CursorOptions& options) noexcept try { diff --git a/src/renderer/atlas/AtlasEngine.h b/src/renderer/atlas/AtlasEngine.h index 4ec09a9e931..8d6d76795c0 100644 --- a/src/renderer/atlas/AtlasEngine.h +++ b/src/renderer/atlas/AtlasEngine.h @@ -45,6 +45,7 @@ namespace Microsoft::Console::Render::Atlas [[nodiscard]] HRESULT PaintBufferLine(std::span clusters, til::point coord, bool fTrimLeft, bool lineWrapped) noexcept override; [[nodiscard]] HRESULT PaintBufferGridLines(const GridLineSet lines, const COLORREF gridlineColor, const COLORREF underlineColor, const size_t cchLine, const til::point coordTarget) noexcept override; [[nodiscard]] HRESULT PaintSelection(const til::rect& rect) noexcept override; + [[nodiscard]] HRESULT PaintSelections(const std::vector& rects) noexcept override; [[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override; [[nodiscard]] HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, const RenderSettings& renderSettings, gsl::not_null pData, bool usingSoftFont, bool isSettingDefaultBrushes) noexcept override; [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo) noexcept override; diff --git a/src/renderer/base/renderer.cpp b/src/renderer/base/renderer.cpp index 0b1d6b004cb..c7c5c491815 100644 --- a/src/renderer/base/renderer.cpp +++ b/src/renderer/base/renderer.cpp @@ -362,6 +362,7 @@ void Renderer::TriggerSelection() { // Get selection rectangles auto rects = _GetSelectionRects(); + auto searchSelections = _GetSearchSelectionRects(); // Make a viewport representing the coordinates that are currently presentable. const til::rect viewport{ _pData->GetViewport().Dimensions() }; @@ -374,11 +375,14 @@ void Renderer::TriggerSelection() FOREACH_ENGINE(pEngine) { + LOG_IF_FAILED(pEngine->InvalidateSelection(_previousSearchSelection)); LOG_IF_FAILED(pEngine->InvalidateSelection(_previousSelection)); + LOG_IF_FAILED(pEngine->InvalidateSelection(searchSelections)); LOG_IF_FAILED(pEngine->InvalidateSelection(rects)); } _previousSelection = std::move(rects); + _previousSearchSelection = std::move(searchSelections); NotifyPaintFrame(); } @@ -1206,9 +1210,20 @@ void Renderer::_PaintSelection(_In_ IRenderEngine* const pEngine) // Get selection rectangles const auto rectangles = _GetSelectionRects(); - for (const auto& rect : rectangles) + const auto searchRectangles = _GetSearchSelectionRects(); + + std::vector dirtySearchRectangles; + for (auto& dirtyRect : dirtyAreas) { - for (auto& dirtyRect : dirtyAreas) + for (const auto& sr : searchRectangles) + { + if (const auto rectCopy = sr & dirtyRect) + { + dirtySearchRectangles.emplace_back(rectCopy); + } + } + + for (const auto& rect : rectangles) { if (const auto rectCopy = rect & dirtyRect) { @@ -1216,6 +1231,11 @@ void Renderer::_PaintSelection(_In_ IRenderEngine* const pEngine) } } } + + if (!dirtySearchRectangles.empty()) + { + LOG_IF_FAILED(pEngine->PaintSelections(std::move(dirtySearchRectangles))); + } } CATCH_LOG(); } @@ -1281,6 +1301,28 @@ std::vector Renderer::_GetSelectionRects() const return result; } +std::vector Renderer::_GetSearchSelectionRects() const +{ + const auto& buffer = _pData->GetTextBuffer(); + auto rects = _pData->GetSearchSelectionRects(); + // Adjust rectangles to viewport + auto view = _pData->GetViewport(); + + std::vector result; + result.reserve(rects.size()); + + for (auto rect : rects) + { + // Convert buffer offsets to the equivalent range of screen cells + // expected by callers, taking line rendition into account. + const auto lineRendition = buffer.GetLineRendition(rect.Top()); + rect = Viewport::FromInclusive(BufferToScreenLine(rect.ToInclusive(), lineRendition)); + result.emplace_back(view.ConvertToOrigin(rect).ToExclusive()); + } + + return result; +} + // Method Description: // - Offsets all of the selection rectangles we might be holding onto // as the previously selected area. If the whole viewport scrolls, diff --git a/src/renderer/base/renderer.hpp b/src/renderer/base/renderer.hpp index ae3ed2cfda9..1cd61799a8f 100644 --- a/src/renderer/base/renderer.hpp +++ b/src/renderer/base/renderer.hpp @@ -110,6 +110,7 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT _UpdateDrawingBrushes(_In_ IRenderEngine* const pEngine, const TextAttribute attr, const bool usingSoftFont, const bool isSettingDefaultBrushes); [[nodiscard]] HRESULT _PerformScrolling(_In_ IRenderEngine* const pEngine); std::vector _GetSelectionRects() const; + std::vector _GetSearchSelectionRects() const; void _ScrollPreviousSelection(const til::point delta); [[nodiscard]] HRESULT _PaintTitle(IRenderEngine* const pEngine); bool _isInHoveredInterval(til::point coordTarget) const noexcept; @@ -127,6 +128,7 @@ namespace Microsoft::Console::Render Microsoft::Console::Types::Viewport _viewport; std::vector _clusterBuffer; std::vector _previousSelection; + std::vector _previousSearchSelection; std::function _pfnBackgroundColorChanged; std::function _pfnFrameColorChanged; std::function _pfnRendererEnteredErrorState; diff --git a/src/renderer/dx/DxRenderer.cpp b/src/renderer/dx/DxRenderer.cpp index 064d219f72a..e03cfb20081 100644 --- a/src/renderer/dx/DxRenderer.cpp +++ b/src/renderer/dx/DxRenderer.cpp @@ -1844,6 +1844,14 @@ try } CATCH_RETURN() +[[nodiscard]] HRESULT DxEngine::PaintSelections(const std::vector& rects) noexcept +try +{ + UNREFERENCED_PARAMETER(rects); + return S_OK; +} +CATCH_RETURN() + // Routine Description: // - Does nothing. Our cursor is drawn in CustomTextRenderer::DrawGlyphRun, // either above or below the text. diff --git a/src/renderer/dx/DxRenderer.hpp b/src/renderer/dx/DxRenderer.hpp index 877b3f1adfa..990c77e18e5 100644 --- a/src/renderer/dx/DxRenderer.hpp +++ b/src/renderer/dx/DxRenderer.hpp @@ -108,6 +108,7 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT PaintBufferGridLines(const GridLineSet lines, const COLORREF gridlineColor, const COLORREF underlineColor, const size_t cchLine, const til::point coordTarget) noexcept override; [[nodiscard]] HRESULT PaintSelection(const til::rect& rect) noexcept override; + [[nodiscard]] HRESULT PaintSelections(const std::vector& rect) noexcept override; [[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override; diff --git a/src/renderer/gdi/gdirenderer.hpp b/src/renderer/gdi/gdirenderer.hpp index 2cc5b4dc14c..1d855d2746e 100644 --- a/src/renderer/gdi/gdirenderer.hpp +++ b/src/renderer/gdi/gdirenderer.hpp @@ -57,6 +57,7 @@ namespace Microsoft::Console::Render const size_t cchLine, const til::point coordTarget) noexcept override; [[nodiscard]] HRESULT PaintSelection(const til::rect& rect) noexcept override; + [[nodiscard]] HRESULT PaintSelections(const std::vector& rects) noexcept override; [[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override; diff --git a/src/renderer/gdi/paint.cpp b/src/renderer/gdi/paint.cpp index 222576390e2..5951c57ef29 100644 --- a/src/renderer/gdi/paint.cpp +++ b/src/renderer/gdi/paint.cpp @@ -815,6 +815,13 @@ bool GdiEngine::FontHasWesternScript(HDC hdc) return S_OK; } +[[nodiscard]] HRESULT GdiEngine::PaintSelections(const std::vector& rects) noexcept +{ + UNREFERENCED_PARAMETER(rects); + + return S_OK; +} + #ifdef DBG void GdiEngine::_CreateDebugWindow() diff --git a/src/renderer/inc/IRenderData.hpp b/src/renderer/inc/IRenderData.hpp index 69e0dc2a0e6..cfc035a7f9b 100644 --- a/src/renderer/inc/IRenderData.hpp +++ b/src/renderer/inc/IRenderData.hpp @@ -47,6 +47,7 @@ namespace Microsoft::Console::Render virtual const TextBuffer& GetTextBuffer() const noexcept = 0; virtual const FontInfo& GetFontInfo() const noexcept = 0; virtual std::vector GetSelectionRects() noexcept = 0; + virtual std::vector GetSearchSelectionRects() noexcept = 0; virtual void LockConsole() noexcept = 0; virtual void UnlockConsole() noexcept = 0; @@ -71,6 +72,7 @@ namespace Microsoft::Console::Render virtual const bool IsBlockSelection() const = 0; virtual void ClearSelection() = 0; virtual void SelectNewRegion(const til::point coordStart, const til::point coordEnd) = 0; + virtual void SelectSearchRegions(std::vector source) = 0; virtual const til::point GetSelectionAnchor() const noexcept = 0; virtual const til::point GetSelectionEnd() const noexcept = 0; virtual const bool IsUiaDataInitialized() const noexcept = 0; diff --git a/src/renderer/inc/IRenderEngine.hpp b/src/renderer/inc/IRenderEngine.hpp index afcaa5aff59..016f0f10baa 100644 --- a/src/renderer/inc/IRenderEngine.hpp +++ b/src/renderer/inc/IRenderEngine.hpp @@ -78,6 +78,7 @@ namespace Microsoft::Console::Render [[nodiscard]] virtual HRESULT PaintBufferLine(std::span clusters, til::point coord, bool fTrimLeft, bool lineWrapped) noexcept = 0; [[nodiscard]] virtual HRESULT PaintBufferGridLines(GridLineSet lines, COLORREF gridlineColor, COLORREF underlineColor, size_t cchLine, til::point coordTarget) noexcept = 0; [[nodiscard]] virtual HRESULT PaintSelection(const til::rect& rect) noexcept = 0; + [[nodiscard]] virtual HRESULT PaintSelections(const std::vector& rects) noexcept = 0; [[nodiscard]] virtual HRESULT PaintCursor(const CursorOptions& options) noexcept = 0; [[nodiscard]] virtual HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, const RenderSettings& renderSettings, gsl::not_null pData, bool usingSoftFont, bool isSettingDefaultBrushes) noexcept = 0; [[nodiscard]] virtual HRESULT UpdateFont(const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo) noexcept = 0; diff --git a/src/renderer/uia/UiaRenderer.cpp b/src/renderer/uia/UiaRenderer.cpp index d1e72fbd0eb..a245491dead 100644 --- a/src/renderer/uia/UiaRenderer.cpp +++ b/src/renderer/uia/UiaRenderer.cpp @@ -386,6 +386,11 @@ void UiaEngine::WaitUntilCanRender() noexcept return S_FALSE; } +[[nodiscard]] HRESULT UiaEngine::PaintSelections(const std::vector& /*rect*/) noexcept +{ + return S_FALSE; +} + // Routine Description: // - Draws the cursor on the screen // For UIA, this doesn't mean anything. So do nothing. diff --git a/src/renderer/uia/UiaRenderer.hpp b/src/renderer/uia/UiaRenderer.hpp index 4625ca155cb..bd1734c5d64 100644 --- a/src/renderer/uia/UiaRenderer.hpp +++ b/src/renderer/uia/UiaRenderer.hpp @@ -51,6 +51,7 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT PaintBufferLine(const std::span clusters, const til::point coord, const bool fTrimLeft, const bool lineWrapped) noexcept override; [[nodiscard]] HRESULT PaintBufferGridLines(const GridLineSet lines, const COLORREF gridlineColor, const COLORREF underlineColor, const size_t cchLine, const til::point coordTarget) noexcept override; [[nodiscard]] HRESULT PaintSelection(const til::rect& rect) noexcept override; + [[nodiscard]] HRESULT PaintSelections(const std::vector& rects) noexcept override; [[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override; [[nodiscard]] HRESULT UpdateDrawingBrushes(const TextAttribute& textAttributes, const RenderSettings& renderSettings, const gsl::not_null pData, const bool usingSoftFont, const bool isSettingDefaultBrushes) noexcept override; [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo) noexcept override; diff --git a/src/renderer/vt/paint.cpp b/src/renderer/vt/paint.cpp index 99f8853a98f..d8e3e66686b 100644 --- a/src/renderer/vt/paint.cpp +++ b/src/renderer/vt/paint.cpp @@ -233,6 +233,11 @@ using namespace Microsoft::Console::Types; return S_OK; } +[[nodiscard]] HRESULT VtEngine::PaintSelections(const std::vector& /*rect*/) noexcept +{ + return S_OK; +} + // Routine Description: // - Write a VT sequence to change the current colors of text. Writes true RGB // color sequences. diff --git a/src/renderer/vt/vtrenderer.hpp b/src/renderer/vt/vtrenderer.hpp index 676672ee814..7a974850afc 100644 --- a/src/renderer/vt/vtrenderer.hpp +++ b/src/renderer/vt/vtrenderer.hpp @@ -64,6 +64,7 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT PaintBufferLine(std::span clusters, til::point coord, bool fTrimLeft, bool lineWrapped) noexcept override; [[nodiscard]] HRESULT PaintBufferGridLines(const GridLineSet lines, const COLORREF gridlineColor, const COLORREF underlineColor, const size_t cchLine, const til::point coordTarget) noexcept override; [[nodiscard]] HRESULT PaintSelection(const til::rect& rect) noexcept override; + [[nodiscard]] HRESULT PaintSelections(const std::vector& rects) noexcept override; [[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override; [[nodiscard]] HRESULT UpdateFont(const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo) noexcept override; [[nodiscard]] HRESULT UpdateDpi(int iDpi) noexcept override; diff --git a/src/renderer/wddmcon/WddmConRenderer.cpp b/src/renderer/wddmcon/WddmConRenderer.cpp index fda8ae6c21b..db729467cae 100644 --- a/src/renderer/wddmcon/WddmConRenderer.cpp +++ b/src/renderer/wddmcon/WddmConRenderer.cpp @@ -298,6 +298,11 @@ CATCH_RETURN() return S_OK; } +[[nodiscard]] HRESULT WddmConEngine::PaintSelections(const std::vector& /*rects*/) noexcept +{ + return S_OK; +} + [[nodiscard]] HRESULT WddmConEngine::PaintCursor(const CursorOptions& /*options*/) noexcept { return S_OK; diff --git a/src/renderer/wddmcon/WddmConRenderer.hpp b/src/renderer/wddmcon/WddmConRenderer.hpp index 954dc226946..930fbe6dea6 100644 --- a/src/renderer/wddmcon/WddmConRenderer.hpp +++ b/src/renderer/wddmcon/WddmConRenderer.hpp @@ -46,6 +46,7 @@ namespace Microsoft::Console::Render const bool lineWrapped) noexcept override; [[nodiscard]] HRESULT PaintBufferGridLines(const GridLineSet lines, const COLORREF gridlineColor, const COLORREF underlineColor, const size_t cchLine, const til::point coordTarget) noexcept override; [[nodiscard]] HRESULT PaintSelection(const til::rect& rect) noexcept override; + [[nodiscard]] HRESULT PaintSelections(const std::vector& rects) noexcept override; [[nodiscard]] HRESULT PaintCursor(const CursorOptions& options) noexcept override;