diff --git a/src/buffer/out/search.cpp b/src/buffer/out/search.cpp index 9707e8fdeaa..a62cb193460 100644 --- a/src/buffer/out/search.cpp +++ b/src/buffer/out/search.cpp @@ -116,6 +116,8 @@ const til::point_span* Search::GetCurrent() const noexcept bool Search::SelectCurrent() const { + std::vector toSelect; + if (const auto s = GetCurrent()) { // Convert buffer selection offsets into the equivalent screen coordinates @@ -123,7 +125,25 @@ bool Search::SelectCurrent() const const auto& textBuffer = _renderData->GetTextBuffer(); const auto selStart = textBuffer.BufferToScreenPosition(s->start); const auto selEnd = textBuffer.BufferToScreenPosition(s->end); + _renderData->SelectNewRegion(selStart, selEnd); + + 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(toSelect); + return true; } diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 7925fc16eb8..7fd58425ace 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -521,6 +521,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation // modifier key. We'll wait for a real keystroke to dismiss the // GH #7395 - don't update selection when taking PrintScreen // selection. + return _terminal->IsSelectionActive() && ::Microsoft::Terminal::Core::Terminal::IsInputKey(vkey); } diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index 72c34d2f629..f8a95709455 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -212,10 +212,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; @@ -370,6 +372,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; @@ -459,6 +462,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() 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..2f9ebdf5570 100644 --- a/src/cascadia/TerminalCore/TerminalSelection.cpp +++ b/src/cascadia/TerminalCore/TerminalSelection.cpp @@ -63,6 +63,34 @@ 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() const noexcept +{ + std::vector result; + + try + { + std::vector result; + for (const auto& selection : _searchSelections) + { + 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: @@ -243,6 +271,7 @@ void Terminal::SetSelectionEnd(const til::point viewportPos, std::optionalstart, _selection->end) = expandedAnchors; } + _selectionMode = SelectionInteractionMode::Mouse; _selectionIsTargetingUrl = false; } @@ -824,6 +853,7 @@ void Terminal::_MoveByBuffer(SelectionDirection direction, til::point& pos) noex void Terminal::ClearSelection() { _assertLocked(); + _searchSelections.clear(); _selection = std::nullopt; _selectionMode = SelectionInteractionMode::None; _selectionIsTargetingUrl = false; @@ -888,6 +918,7 @@ void Terminal::_ScrollToPoint(const til::point pos) const auto amtBelowView = pos.y - visibleViewport.BottomInclusive(); _scrollOffset -= amtBelowView; } + _NotifyScrollEvent(); _activeBuffer().TriggerScroll(); } diff --git a/src/cascadia/TerminalCore/terminalrenderdata.cpp b/src/cascadia/TerminalCore/terminalrenderdata.cpp index 034a65ab784..4215b577f42 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()) + { + 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 12223e94a63..3704adda875 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 /*color*/, 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 d327c0b9d61..8b8b0e05dfb 100644 --- a/src/host/renderData.cpp +++ b/src/host/renderData.cpp @@ -79,6 +79,27 @@ 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 +{ + std::vector result; + + try + { + for (const auto& select : Selection::Instance().GetSelectionRects()) + { + result.emplace_back(Viewport::FromInclusive(select)); + } + } + CATCH_LOG(); + + return result; +} + // 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 @@ -369,6 +390,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 ce6b903ffd1..d78450a29f4 100644 --- a/src/interactivity/onecore/BgfxEngine.cpp +++ b/src/interactivity/onecore/BgfxEngine.cpp @@ -160,6 +160,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 31fa49c8522..cbd6f1d42d0 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(GridLineSet const lines, COLORREF const color, size_t const cchLine, til::point const 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 e46bb250835..8aab87faf9a 100644 --- a/src/renderer/atlas/AtlasEngine.cpp +++ b/src/renderer/atlas/AtlasEngine.cpp @@ -413,6 +413,51 @@ try } CATCH_RETURN() +[[nodiscard]] HRESULT AtlasEngine::PaintSelections(const std::vector& rects) noexcept +try +{ + // Unfortunately there's no step after Renderer::_PaintBufferOutput that + // would inform us that it's done with the last AtlasEngine::PaintBufferLine. + // As such we got to call _flushBufferLine() here just to be sure. + _flushBufferLine(); + + for (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 (y < _p.rows.size() && rect.top >= 0) + { + auto& row = *_p.rows[y]; + + auto it = std::find_if(row.searchSelections.begin(), row.searchSelections.end(), [&from](const SearchSelection& selection) { + return selection.from == from; + }); + + if (it != row.searchSelections.end()) + { + if (to > it->to) + { + it->to = to; + } + } + else + { + auto s = SearchSelection{ from, to }; + row.searchSelections.emplace_back(s); + } + + _p.dirtyRectInPx.left = std::min(_p.dirtyRectInPx.left, from * _p.s->font->cellSize.x); + _p.dirtyRectInPx.top = std::min(_p.dirtyRectInPx.top, y * _p.s->font->cellSize.y); + _p.dirtyRectInPx.right = std::max(_p.dirtyRectInPx.right, to * _p.s->font->cellSize.x); + _p.dirtyRectInPx.bottom = std::max(_p.dirtyRectInPx.bottom, _p.dirtyRectInPx.top + _p.s->font->cellSize.y); + } + } + 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 b135a8989f8..f39e07973c3 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(GridLineSet lines, COLORREF color, size_t cchLine, 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/atlas/BackendD3D.cpp b/src/renderer/atlas/BackendD3D.cpp index 846567ca613..9c91da6144b 100644 --- a/src/renderer/atlas/BackendD3D.cpp +++ b/src/renderer/atlas/BackendD3D.cpp @@ -237,6 +237,7 @@ void BackendD3D::Render(RenderingPayload& p) _drawBackground(p); _drawCursorBackground(p); _drawText(p); + _drawSearchSelections(p); _drawSelection(p); #if ATLAS_DEBUG_SHOW_DIRTY _debugShowDirty(p); @@ -2066,6 +2067,38 @@ size_t BackendD3D::_drawCursorForegroundSlowPath(const CursorRect& c, size_t off return addedInstances; } +void BackendD3D::_drawSearchSelections(const RenderingPayload& p) +{ + u16 y = 0; + + for (const auto& row : p.rows) + { + if (!row->searchSelections.empty()) + { + for (auto s : row->searchSelections) + { + if (s.from != row->selectionFrom) + { + _appendQuad() = { + .shadingType = ShadingType::Selection, + .position = { + p.s->font->cellSize.x * s.from, + p.s->font->cellSize.y * y, + }, + .size = { + static_cast(p.s->font->cellSize.x * (s.to - s.from)), + p.s->font->cellSize.y, + }, + .color = p.s->misc->searchSelectionColor, + }; + } + } + } + + y++; + } +} + void BackendD3D::_drawSelection(const RenderingPayload& p) { u16 y = 0; diff --git a/src/renderer/atlas/BackendD3D.h b/src/renderer/atlas/BackendD3D.h index 14f4ca2943e..2118c80e28e 100644 --- a/src/renderer/atlas/BackendD3D.h +++ b/src/renderer/atlas/BackendD3D.h @@ -228,6 +228,7 @@ namespace Microsoft::Console::Render::Atlas ATLAS_ATTR_COLD void _drawCursorForeground(); ATLAS_ATTR_COLD size_t _drawCursorForegroundSlowPath(const CursorRect& c, size_t offset); void _drawSelection(const RenderingPayload& p); + void _drawSearchSelections(const RenderingPayload& p); void _executeCustomShader(RenderingPayload& p); wil::com_ptr _renderTargetView; diff --git a/src/renderer/atlas/common.h b/src/renderer/atlas/common.h index bb46ff61547..42be71b9215 100644 --- a/src/renderer/atlas/common.h +++ b/src/renderer/atlas/common.h @@ -377,6 +377,7 @@ namespace Microsoft::Console::Render::Atlas { u32 backgroundColor = 0; u32 selectionColor = 0x7fffffff; + u32 searchSelectionColor = 0x5fff0000; std::wstring customPixelShaderPath; bool useRetroTerminalEffect = false; }; @@ -431,6 +432,12 @@ namespace Microsoft::Console::Render::Atlas u16 to = 0; }; + struct SearchSelection + { + u16 from; + u16 to; + }; + struct ShapedRow { void Clear(u16 y, u16 cellHeight) noexcept @@ -446,6 +453,7 @@ namespace Microsoft::Console::Render::Atlas selectionTo = 0; dirtyTop = y * cellHeight; dirtyBottom = dirtyTop + cellHeight; + searchSelections.clear(); } std::vector mappings; @@ -457,6 +465,7 @@ namespace Microsoft::Console::Render::Atlas LineRendition lineRendition = LineRendition::SingleWidth; u16 selectionFrom = 0; u16 selectionTo = 0; + std::vector searchSelections; til::CoordType dirtyTop = 0; til::CoordType dirtyBottom = 0; }; diff --git a/src/renderer/base/renderer.cpp b/src/renderer/base/renderer.cpp index 917c5ba05f9..70b6a7e67b7 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(); } @@ -1197,6 +1201,8 @@ void Renderer::_PaintSelection(_In_ IRenderEngine* const pEngine) // Get selection rectangles const auto rectangles = _GetSelectionRects(); + const auto searchRectangles = _GetSearchSelectionRects(); + LOG_IF_FAILED(pEngine->PaintSelections(searchRectangles)); for (const auto& rect : rectangles) { for (auto& dirtyRect : dirtyAreas) @@ -1272,6 +1278,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 f74bf528dc1..4bbc3019a0c 100644 --- a/src/renderer/dx/DxRenderer.cpp +++ b/src/renderer/dx/DxRenderer.cpp @@ -1840,6 +1840,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 bfb11205a05..d2c967c61f3 100644 --- a/src/renderer/dx/DxRenderer.hpp +++ b/src/renderer/dx/DxRenderer.hpp @@ -108,6 +108,7 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT PaintBufferGridLines(GridLineSet const lines, COLORREF const color, size_t const cchLine, til::point const 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 a1ab2290a97..e910e642fd2 100644 --- a/src/renderer/gdi/gdirenderer.hpp +++ b/src/renderer/gdi/gdirenderer.hpp @@ -56,6 +56,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 17dc9bddd82..06c6f1c75cc 100644 --- a/src/renderer/gdi/paint.cpp +++ b/src/renderer/gdi/paint.cpp @@ -763,6 +763,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 46221ae911d..efeaad23acd 100644 --- a/src/renderer/inc/IRenderEngine.hpp +++ b/src/renderer/inc/IRenderEngine.hpp @@ -75,6 +75,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 color, 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 e58c227c561..db82d2f9cd6 100644 --- a/src/renderer/uia/UiaRenderer.cpp +++ b/src/renderer/uia/UiaRenderer.cpp @@ -374,6 +374,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 5e486b7e0e1..e8fa6dc1ce2 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 color, 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 801390085c0..9a37816d14f 100644 --- a/src/renderer/vt/paint.cpp +++ b/src/renderer/vt/paint.cpp @@ -231,6 +231,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 15de6e0e760..adf9b0959f2 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(GridLineSet lines, COLORREF color, size_t cchLine, 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 378b1dfd086..a1d46c79bfa 100644 --- a/src/renderer/wddmcon/WddmConRenderer.cpp +++ b/src/renderer/wddmcon/WddmConRenderer.cpp @@ -297,6 +297,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 a658ef51180..0bcd9ce40a4 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(GridLineSet const lines, COLORREF const color, size_t const cchLine, til::point const 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;