diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index ad827c79c1b..293b3dd070a 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -847,7 +847,7 @@ } ], "required": [ "actions" ] - }, + }, "CommandPaletteAction": { "description": "Arguments for a commandPalette action", "allOf": [ diff --git a/src/buffer/out/textBuffer.cpp b/src/buffer/out/textBuffer.cpp index 466e38ecfc9..3fba7b0829b 100644 --- a/src/buffer/out/textBuffer.cpp +++ b/src/buffer/out/textBuffer.cpp @@ -1430,12 +1430,13 @@ const til::point TextBuffer::GetGlyphStart(const til::point pos, std::optional limitOptional) const +const til::point TextBuffer::GetGlyphEnd(const til::point pos, bool accessibilityMode, std::optional limitOptional) const { COORD resultPos = pos; const auto bufferSize = GetSize(); @@ -1453,7 +1454,10 @@ const til::point TextBuffer::GetGlyphEnd(const til::point pos, std::optional limitOptional = std::nullopt) const; - const til::point GetGlyphEnd(const til::point pos, std::optional limitOptional = std::nullopt) const; + const til::point GetGlyphEnd(const til::point pos, bool accessibilityMode = false, std::optional limitOptional = std::nullopt) const; bool MoveToNextGlyph(til::point& pos, bool allowBottomExclusive = false, std::optional limitOptional = std::nullopt) const; bool MoveToPreviousGlyph(til::point& pos, std::optional limitOptional = std::nullopt) const; diff --git a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp index c86f5d62100..02025be813e 100644 --- a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp +++ b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp @@ -549,11 +549,11 @@ try if (multiClickMapper == 3) { - _terminal->MultiClickSelection(cursorPosition / fontSize, ::Terminal::SelectionExpansionMode::Line); + _terminal->MultiClickSelection(cursorPosition / fontSize, ::Terminal::SelectionExpansion::Line); } else if (multiClickMapper == 2) { - _terminal->MultiClickSelection(cursorPosition / fontSize, ::Terminal::SelectionExpansionMode::Word); + _terminal->MultiClickSelection(cursorPosition / fontSize, ::Terminal::SelectionExpansion::Word); } else { diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index e09eb93ae03..1e41fdb5c34 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -359,21 +359,28 @@ namespace winrt::Microsoft::Terminal::Control::implementation const ControlKeyStates modifiers, const bool keyDown) { - // When there is a selection active, escape should clear it and NOT flow through - // to the terminal. With any other keypress, it should clear the selection AND - // flow through to the terminal. + // Update the selection, if it's present // GH#6423 - don't dismiss selection if the key that was pressed was a // modifier key. We'll wait for a real keystroke to dismiss the // GH #7395 - don't dismiss selection when taking PrintScreen // selection. - // GH#8522, GH#3758 - Only dismiss the selection on key _down_. If we - // dismiss on key up, then there's chance that we'll immediately dismiss + // GH#8522, GH#3758 - Only modify the selection on key _down_. If we + // modify on key up, then there's chance that we'll immediately dismiss // a selection created by an action bound to a keydown. if (HasSelection() && !KeyEvent::IsModifierKey(vkey) && vkey != VK_SNAPSHOT && keyDown) { + // try to update the selection + if (const auto updateSlnParams{ ::Terminal::ConvertKeyEventToUpdateSelectionParams(modifiers, vkey) }) + { + auto lock = _terminal->LockForWriting(); + _terminal->UpdateSelection(updateSlnParams->first, updateSlnParams->second); + _renderer->TriggerSelection(); + return true; + } + // GH#8791 - don't dismiss selection if Windows key was also pressed as a key-combination. if (!modifiers.IsWinPressed()) { @@ -381,6 +388,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation _renderer->TriggerSelection(); } + // When there is a selection active, escape should clear it and NOT flow through + // to the terminal. With any other keypress, it should clear the selection AND + // flow through to the terminal. if (vkey == VK_ESCAPE) { return true; @@ -1399,18 +1409,18 @@ namespace winrt::Microsoft::Terminal::Control::implementation // handle ALT key _terminal->SetBlockSelection(altEnabled); - ::Terminal::SelectionExpansionMode mode = ::Terminal::SelectionExpansionMode::Cell; + ::Terminal::SelectionExpansion mode = ::Terminal::SelectionExpansion::Char; if (numberOfClicks == 1) { - mode = ::Terminal::SelectionExpansionMode::Cell; + mode = ::Terminal::SelectionExpansion::Char; } else if (numberOfClicks == 2) { - mode = ::Terminal::SelectionExpansionMode::Word; + mode = ::Terminal::SelectionExpansion::Word; } else if (numberOfClicks == 3) { - mode = ::Terminal::SelectionExpansionMode::Line; + mode = ::Terminal::SelectionExpansion::Line; } // Update the selection appropriately @@ -1435,7 +1445,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation _terminal->SetSelectionEnd(terminalPosition, mode); selectionNeedsToBeCopied = true; } - else if (mode != ::Terminal::SelectionExpansionMode::Cell || shiftEnabled) + else if (mode != ::Terminal::SelectionExpansion::Char || shiftEnabled) { // If we are handling a double / triple-click or shift+single click // we establish selection using the selected mode @@ -1534,5 +1544,4 @@ namespace winrt::Microsoft::Terminal::Control::implementation return hstring(ss.str()); } - } diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index 27e26b7f280..d3b5f14403f 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -227,16 +227,30 @@ class Microsoft::Terminal::Core::Terminal final : #pragma region TextSelection // These methods are defined in TerminalSelection.cpp - enum class SelectionExpansionMode + enum class SelectionDirection { - Cell, + Left, + Right, + Up, + Down + }; + + enum class SelectionExpansion + { + Char, Word, - Line + Line, // Mouse selection only! + Viewport, + Buffer }; - void MultiClickSelection(const COORD viewportPos, SelectionExpansionMode expansionMode); + void MultiClickSelection(const COORD viewportPos, SelectionExpansion expansionMode); void SetSelectionAnchor(const COORD position); - void SetSelectionEnd(const COORD position, std::optional newExpansionMode = std::nullopt); + void SetSelectionEnd(const COORD position, std::optional newExpansionMode = std::nullopt); void SetBlockSelection(const bool isEnabled) noexcept; + void UpdateSelection(SelectionDirection direction, SelectionExpansion mode); + + using UpdateSelectionParams = std::optional>; + static UpdateSelectionParams ConvertKeyEventToUpdateSelectionParams(const ControlKeyStates mods, const WORD vkey); const TextBuffer::TextAndColor RetrieveSelectedTextFromBuffer(bool trimTrailingWhitespace); #pragma endregion @@ -308,7 +322,7 @@ class Microsoft::Terminal::Core::Terminal final : std::optional _selection; bool _blockSelection; std::wstring _wordDelimiters; - SelectionExpansionMode _multiClickSelectionMode; + SelectionExpansion _multiClickSelectionMode; #pragma endregion // TODO: These members are not shared by an alt-buffer. They should be @@ -375,6 +389,10 @@ class Microsoft::Terminal::Core::Terminal final : std::pair _PivotSelection(const COORD targetPos, bool& targetStart) const; std::pair _ExpandSelectionAnchors(std::pair anchors) const; COORD _ConvertToBufferCell(const COORD viewportPos) const; + void _MoveByChar(SelectionDirection direction, COORD& pos); + void _MoveByWord(SelectionDirection direction, COORD& pos); + void _MoveByViewport(SelectionDirection direction, COORD& pos); + void _MoveByBuffer(SelectionDirection direction, COORD& pos); #pragma endregion Microsoft::Console::VirtualTerminal::SgrStack _sgrStack; diff --git a/src/cascadia/TerminalCore/TerminalSelection.cpp b/src/cascadia/TerminalCore/TerminalSelection.cpp index c8c877032a7..367a8365a56 100644 --- a/src/cascadia/TerminalCore/TerminalSelection.cpp +++ b/src/cascadia/TerminalCore/TerminalSelection.cpp @@ -100,8 +100,8 @@ const bool Terminal::IsBlockSelection() const noexcept // - Perform a multi-click selection at viewportPos expanding according to the expansionMode // Arguments: // - viewportPos: the (x,y) coordinate on the visible viewport -// - expansionMode: the SelectionExpansionMode to dictate the boundaries of the selection anchors -void Terminal::MultiClickSelection(const COORD viewportPos, SelectionExpansionMode expansionMode) +// - expansionMode: the SelectionExpansion to dictate the boundaries of the selection anchors +void Terminal::MultiClickSelection(const COORD viewportPos, SelectionExpansion expansionMode) { // set the selection pivot to expand the selection using SetSelectionEnd() _selection = SelectionAnchors{}; @@ -124,7 +124,7 @@ void Terminal::SetSelectionAnchor(const COORD viewportPos) _selection = SelectionAnchors{}; _selection->pivot = _ConvertToBufferCell(viewportPos); - _multiClickSelectionMode = SelectionExpansionMode::Cell; + _multiClickSelectionMode = SelectionExpansion::Char; SetSelectionEnd(viewportPos); _selection->start = _selection->pivot; @@ -136,7 +136,7 @@ void Terminal::SetSelectionAnchor(const COORD viewportPos) // Arguments: // - viewportPos: the (x,y) coordinate on the visible viewport // - newExpansionMode: overwrites the _multiClickSelectionMode for this function call. Used for ShiftClick -void Terminal::SetSelectionEnd(const COORD viewportPos, std::optional newExpansionMode) +void Terminal::SetSelectionEnd(const COORD viewportPos, std::optional newExpansionMode) { if (!_selection.has_value()) { @@ -210,15 +210,15 @@ std::pair Terminal::_ExpandSelectionAnchors(std::pairGetSize(); switch (_multiClickSelectionMode) { - case SelectionExpansionMode::Line: + case SelectionExpansion::Line: start = { bufferSize.Left(), start.Y }; end = { bufferSize.RightInclusive(), end.Y }; break; - case SelectionExpansionMode::Word: + case SelectionExpansion::Word: start = _buffer->GetWordStart(start, _wordDelimiters); end = _buffer->GetWordEnd(end, _wordDelimiters); break; - case SelectionExpansionMode::Cell: + case SelectionExpansion::Char: default: // no expansion is necessary break; @@ -235,6 +235,229 @@ void Terminal::SetBlockSelection(const bool isEnabled) noexcept _blockSelection = isEnabled; } +Terminal::UpdateSelectionParams Terminal::ConvertKeyEventToUpdateSelectionParams(const ControlKeyStates mods, const WORD vkey) +{ + if (mods.IsShiftPressed() && !mods.IsAltPressed()) + { + if (mods.IsCtrlPressed()) + { + // Ctrl + Shift + _ + switch (vkey) + { + case VK_LEFT: + return UpdateSelectionParams{ std::in_place, SelectionDirection::Left, SelectionExpansion::Word }; + case VK_RIGHT: + return UpdateSelectionParams{ std::in_place, SelectionDirection::Right, SelectionExpansion::Word }; + case VK_HOME: + return UpdateSelectionParams{ std::in_place, SelectionDirection::Left, SelectionExpansion::Buffer }; + case VK_END: + return UpdateSelectionParams{ std::in_place, SelectionDirection::Right, SelectionExpansion::Buffer }; + } + } + else + { + // Shift + _ + switch (vkey) + { + case VK_HOME: + return UpdateSelectionParams{ std::in_place, SelectionDirection::Left, SelectionExpansion::Viewport }; + case VK_END: + return UpdateSelectionParams{ std::in_place, SelectionDirection::Right, SelectionExpansion::Viewport }; + case VK_PRIOR: + return UpdateSelectionParams{ std::in_place, SelectionDirection::Up, SelectionExpansion::Viewport }; + case VK_NEXT: + return UpdateSelectionParams{ std::in_place, SelectionDirection::Down, SelectionExpansion::Viewport }; + case VK_LEFT: + return UpdateSelectionParams{ std::in_place, SelectionDirection::Left, SelectionExpansion::Char }; + case VK_RIGHT: + return UpdateSelectionParams{ std::in_place, SelectionDirection::Right, SelectionExpansion::Char }; + case VK_UP: + return UpdateSelectionParams{ std::in_place, SelectionDirection::Up, SelectionExpansion::Char }; + case VK_DOWN: + return UpdateSelectionParams{ std::in_place, SelectionDirection::Down, SelectionExpansion::Char }; + } + } + } + return std::nullopt; +} + +void Terminal::UpdateSelection(SelectionDirection direction, SelectionExpansion mode) +{ + // 1. Figure out which endpoint to update + // One of the endpoints is the pivot, signifying that the other endpoint is the one we want to move. + const bool movingEnd{ _selection->start == _selection->pivot }; + auto targetPos{ movingEnd ? _selection->end : _selection->start }; + + // 2. Perform the movement + switch (mode) + { + case SelectionExpansion::Char: + _MoveByChar(direction, targetPos); + break; + case SelectionExpansion::Word: + _MoveByWord(direction, targetPos); + break; + case SelectionExpansion::Viewport: + _MoveByViewport(direction, targetPos); + break; + case SelectionExpansion::Buffer: + _MoveByBuffer(direction, targetPos); + break; + } + + // 3. Actually modify the selection + // NOTE: targetStart doesn't matter here + bool targetStart = false; + std::tie(_selection->start, _selection->end) = _PivotSelection(targetPos, targetStart); + + // 4. Scroll (if necessary) + if (const auto viewport = _GetVisibleViewport(); !viewport.IsInBounds(targetPos)) + { + if (const auto amtAboveView = viewport.Top() - targetPos.Y; amtAboveView > 0) + { + // anchor is above visible viewport, scroll by that amount + _scrollOffset += amtAboveView; + } + else + { + // anchor is below visible viewport, scroll by that amount + const auto amtBelowView = targetPos.Y - viewport.BottomInclusive(); + _scrollOffset -= amtBelowView; + } + _NotifyScrollEvent(); + _buffer->GetRenderTarget().TriggerScroll(); + } +} + +void Terminal::_MoveByChar(SelectionDirection direction, COORD& pos) +{ + switch (direction) + { + case SelectionDirection::Left: + _buffer->GetSize().DecrementInBounds(pos); + pos = _buffer->GetGlyphStart(pos); + break; + case SelectionDirection::Right: + _buffer->GetSize().IncrementInBounds(pos); + pos = _buffer->GetGlyphEnd(pos); + break; + case SelectionDirection::Up: + { + const auto bufferSize{ _buffer->GetSize() }; + pos = { pos.X, std::clamp(base::ClampSub(pos.Y, 1).RawValue(), bufferSize.Top(), bufferSize.BottomInclusive()) }; + break; + } + case SelectionDirection::Down: + { + const auto bufferSize{ _buffer->GetSize() }; + pos = { pos.X, std::clamp(base::ClampAdd(pos.Y, 1).RawValue(), bufferSize.Top(), bufferSize.BottomInclusive()) }; + break; + } + } +} + +void Terminal::_MoveByWord(SelectionDirection direction, COORD& pos) +{ + switch (direction) + { + case SelectionDirection::Left: + const auto wordStartPos{ _buffer->GetWordStart(pos, _wordDelimiters) }; + if (_buffer->GetSize().CompareInBounds(_selection->pivot, pos) < 0) + { + // If we're moving towards the pivot, move one more cell + pos = wordStartPos; + _buffer->GetSize().DecrementInBounds(pos); + } + else if (wordStartPos == pos) + { + // already at the beginning of the current word, + // move to the beginning of the previous word + _buffer->GetSize().DecrementInBounds(pos); + pos = _buffer->GetWordStart(pos, _wordDelimiters); + } + else + { + // move to the beginning of the current word + pos = wordStartPos; + } + break; + case SelectionDirection::Right: + const auto wordEndPos{ _buffer->GetWordEnd(pos, _wordDelimiters) }; + if (_buffer->GetSize().CompareInBounds(pos, _selection->pivot) < 0) + { + // If we're moving towards the pivot, move one more cell + pos = _buffer->GetWordEnd(pos, _wordDelimiters); + _buffer->GetSize().IncrementInBounds(pos); + } + else if (wordEndPos == pos) + { + // already at the end of the current word, + // move to the end of the next word + _buffer->GetSize().IncrementInBounds(pos); + pos = _buffer->GetWordEnd(pos, _wordDelimiters); + } + else + { + // move to the end of the current word + pos = wordEndPos; + } + break; + case SelectionDirection::Up: + _MoveByChar(direction, pos); + pos = _buffer->GetWordStart(pos, _wordDelimiters); + break; + case SelectionDirection::Down: + _MoveByChar(direction, pos); + pos = _buffer->GetWordEnd(pos, _wordDelimiters); + break; + } +} + +void Terminal::_MoveByViewport(SelectionDirection direction, COORD& pos) +{ + const auto bufferSize{ _buffer->GetSize() }; + switch (direction) + { + case SelectionDirection::Left: + pos = { bufferSize.Left(), pos.Y }; + break; + case SelectionDirection::Right: + pos = { bufferSize.RightInclusive(), pos.Y }; + break; + case SelectionDirection::Up: + { + const auto viewportHeight{ _mutableViewport.Height() }; + const auto newY{ base::ClampSub(pos.Y, viewportHeight) }; + pos = newY < bufferSize.Top() ? bufferSize.Origin() : COORD{ pos.X, newY }; + break; + } + case SelectionDirection::Down: + { + const auto viewportHeight{ _mutableViewport.Height() }; + const auto mutableBottom{ _mutableViewport.BottomInclusive() }; + const auto newY{ base::ClampAdd(pos.Y, viewportHeight) }; + pos = newY > mutableBottom ? COORD{ bufferSize.RightInclusive(), mutableBottom } : COORD{ pos.X, newY }; + break; + } + } +} + +void Terminal::_MoveByBuffer(SelectionDirection direction, COORD& pos) +{ + const auto bufferSize{ _buffer->GetSize() }; + switch (direction) + { + case SelectionDirection::Left: + case SelectionDirection::Up: + pos = bufferSize.Origin(); + break; + case SelectionDirection::Right: + case SelectionDirection::Down: + pos = { bufferSize.RightInclusive(), _mutableViewport.BottomInclusive() }; + break; + } +} + // Method Description: // - clear selection data and disable rendering it #pragma warning(disable : 26440) // changing this to noexcept would require a change to ConHost's selection model diff --git a/src/cascadia/TerminalCore/terminalrenderdata.cpp b/src/cascadia/TerminalCore/terminalrenderdata.cpp index 84b00eadfeb..6ccb5791d22 100644 --- a/src/cascadia/TerminalCore/terminalrenderdata.cpp +++ b/src/cascadia/TerminalCore/terminalrenderdata.cpp @@ -206,7 +206,7 @@ void Terminal::SelectNewRegion(const COORD coordStart, const COORD coordEnd) realCoordEnd.Y -= gsl::narrow(_VisibleStartIndex()); SetSelectionAnchor(realCoordStart); - SetSelectionEnd(realCoordEnd, SelectionExpansionMode::Cell); + SetSelectionEnd(realCoordEnd, SelectionExpansion::Char); } const std::wstring_view Terminal::GetConsoleTitle() const noexcept diff --git a/src/cascadia/UnitTests_TerminalCore/SelectionTest.cpp b/src/cascadia/UnitTests_TerminalCore/SelectionTest.cpp index d5e5a8f03d7..e0dc7acc5bf 100644 --- a/src/cascadia/UnitTests_TerminalCore/SelectionTest.cpp +++ b/src/cascadia/UnitTests_TerminalCore/SelectionTest.cpp @@ -130,7 +130,7 @@ namespace TerminalCoreUnitTests DummyRenderTarget emptyRT; term.Create({ 10, 10 }, scrollback, emptyRT); - term.MultiClickSelection(maxCoord, Terminal::SelectionExpansionMode::Word); + term.MultiClickSelection(maxCoord, Terminal::SelectionExpansion::Word); ValidateSingleRowSelection(term, expected); }; @@ -142,7 +142,7 @@ namespace TerminalCoreUnitTests DummyRenderTarget emptyRT; term.Create({ 10, 10 }, scrollback, emptyRT); - term.MultiClickSelection(maxCoord, Terminal::SelectionExpansionMode::Line); + term.MultiClickSelection(maxCoord, Terminal::SelectionExpansion::Line); ValidateSingleRowSelection(term, expected); }; @@ -501,7 +501,7 @@ namespace TerminalCoreUnitTests // Simulate double click at (x,y) = (5,10) auto clickPos = COORD{ 5, 10 }; - term.MultiClickSelection(clickPos, Terminal::SelectionExpansionMode::Word); + term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Word); // Validate selection area ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, (4 + gsl::narrow(text.size()) - 1), 10 })); @@ -519,7 +519,7 @@ namespace TerminalCoreUnitTests // Simulate click at (x,y) = (5,10) auto clickPos = COORD{ 5, 10 }; - term.MultiClickSelection(clickPos, Terminal::SelectionExpansionMode::Word); + term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Word); // Simulate renderer calling TriggerSelection and acquiring selection area auto selectionRects = term.GetSelectionRects(); @@ -546,7 +546,7 @@ namespace TerminalCoreUnitTests // Simulate click at (x,y) = (15,10) // this is over the '>' char auto clickPos = COORD{ 15, 10 }; - term.MultiClickSelection(clickPos, Terminal::SelectionExpansionMode::Word); + term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Word); // ---Validate selection area--- // "Terminal" is in class 2 @@ -572,7 +572,7 @@ namespace TerminalCoreUnitTests term.Write(text); // Simulate double click at (x,y) = (5,10) - term.MultiClickSelection({ 5, 10 }, Terminal::SelectionExpansionMode::Word); + term.MultiClickSelection({ 5, 10 }, Terminal::SelectionExpansion::Word); // Simulate move to (x,y) = (21,10) // @@ -601,7 +601,7 @@ namespace TerminalCoreUnitTests term.Write(text); // Simulate double click at (x,y) = (21,10) - term.MultiClickSelection({ 21, 10 }, Terminal::SelectionExpansionMode::Word); + term.MultiClickSelection({ 21, 10 }, Terminal::SelectionExpansion::Word); // Simulate move to (x,y) = (5,10) // @@ -622,7 +622,7 @@ namespace TerminalCoreUnitTests // Simulate click at (x,y) = (5,10) auto clickPos = COORD{ 5, 10 }; - term.MultiClickSelection(clickPos, Terminal::SelectionExpansionMode::Line); + term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Line); // Validate selection area ValidateSingleRowSelection(term, SMALL_RECT({ 0, 10, 99, 10 })); @@ -636,7 +636,7 @@ namespace TerminalCoreUnitTests // Simulate click at (x,y) = (5,10) auto clickPos = COORD{ 5, 10 }; - term.MultiClickSelection(clickPos, Terminal::SelectionExpansionMode::Line); + term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Line); // Simulate move to (x,y) = (7,10) term.SetSelectionEnd({ 7, 10 }); @@ -653,7 +653,7 @@ namespace TerminalCoreUnitTests // Simulate click at (x,y) = (5,10) auto clickPos = COORD{ 5, 10 }; - term.MultiClickSelection(clickPos, Terminal::SelectionExpansionMode::Line); + term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Line); // Simulate move to (x,y) = (5,11) term.SetSelectionEnd({ 5, 11 }); @@ -691,7 +691,7 @@ namespace TerminalCoreUnitTests // Step 1: Create a selection on "doubleClickMe" { // Simulate double click at (x,y) = (5,10) - term.MultiClickSelection({ 5, 10 }, Terminal::SelectionExpansionMode::Word); + term.MultiClickSelection({ 5, 10 }, Terminal::SelectionExpansion::Word); // Validate selection area: "doubleClickMe" selected ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 16, 10 })); @@ -704,7 +704,7 @@ namespace TerminalCoreUnitTests // buffer: doubleClickMe dragThroughHere // ^ ^ // start finish - term.SetSelectionEnd({ 21, 10 }, ::Terminal::SelectionExpansionMode::Cell); + term.SetSelectionEnd({ 21, 10 }, Terminal::SelectionExpansion::Char); // Validate selection area: "doubleClickMe drag" selected ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 21, 10 })); @@ -717,7 +717,7 @@ namespace TerminalCoreUnitTests // buffer: doubleClickMe dragThroughHere // ^ ^ ^ // start click finish - term.SetSelectionEnd({ 21, 10 }, ::Terminal::SelectionExpansionMode::Word); + term.SetSelectionEnd({ 21, 10 }, Terminal::SelectionExpansion::Word); // Validate selection area: "doubleClickMe dragThroughHere" selected ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 32, 10 })); @@ -730,7 +730,7 @@ namespace TerminalCoreUnitTests // buffer: doubleClickMe dragThroughHere | // ^ ^ ^ // start click finish (boundary) - term.SetSelectionEnd({ 21, 10 }, ::Terminal::SelectionExpansionMode::Line); + term.SetSelectionEnd({ 21, 10 }, Terminal::SelectionExpansion::Line); // Validate selection area: "doubleClickMe dragThroughHere..." selected ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 99, 10 })); @@ -743,7 +743,7 @@ namespace TerminalCoreUnitTests // buffer: doubleClickMe dragThroughHere // ^ ^ ^ // start click finish - term.SetSelectionEnd({ 21, 10 }, ::Terminal::SelectionExpansionMode::Word); + term.SetSelectionEnd({ 21, 10 }, Terminal::SelectionExpansion::Word); // Validate selection area: "doubleClickMe dragThroughHere" selected ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 32, 10 })); @@ -825,7 +825,7 @@ namespace TerminalCoreUnitTests // Step 4: Shift+Click at (5,10) { - term.SetSelectionEnd({ 5, 10 }, ::Terminal::SelectionExpansionMode::Cell); + term.SetSelectionEnd({ 5, 10 }, Terminal::SelectionExpansion::Char); // Validate selection area // NOTE: Pivot should still be (10, 10) @@ -834,7 +834,7 @@ namespace TerminalCoreUnitTests // Step 5: Shift+Click back at (20,10) { - term.SetSelectionEnd({ 20, 10 }, ::Terminal::SelectionExpansionMode::Cell); + term.SetSelectionEnd({ 20, 10 }, Terminal::SelectionExpansion::Char); // Validate selection area // NOTE: Pivot should still be (10, 10) diff --git a/src/host/ut_host/TextBufferTests.cpp b/src/host/ut_host/TextBufferTests.cpp index 92c07f85fd2..c8dd0679362 100644 --- a/src/host/ut_host/TextBufferTests.cpp +++ b/src/host/ut_host/TextBufferTests.cpp @@ -2253,7 +2253,7 @@ void TextBufferTests::GetGlyphBoundaries() _buffer->Write(iter, target); auto start = _buffer->GetGlyphStart(target); - auto end = _buffer->GetGlyphEnd(target); + auto end = _buffer->GetGlyphEnd(target, true); VERIFY_ARE_EQUAL(test.start, start); VERIFY_ARE_EQUAL(wideGlyph ? test.wideGlyphEnd : test.normalEnd, end); diff --git a/src/renderer/dx/DxRenderer.cpp b/src/renderer/dx/DxRenderer.cpp index d01d99364ad..de33cd00c79 100644 --- a/src/renderer/dx/DxRenderer.cpp +++ b/src/renderer/dx/DxRenderer.cpp @@ -493,6 +493,7 @@ void DxEngine::_ComputePixelShaderSettings() noexcept // actual failure from the API itself. [[nodiscard]] HRESULT DxEngine::_CreateSurfaceHandle() noexcept { +#pragma warning(suppress : 26447) wil::unique_hmodule hDComp{ LoadLibraryEx(L"Dcomp.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32) }; RETURN_LAST_ERROR_IF(hDComp.get() == nullptr); diff --git a/src/types/UiaTextRangeBase.cpp b/src/types/UiaTextRangeBase.cpp index 860dabcd756..08133944ca8 100644 --- a/src/types/UiaTextRangeBase.cpp +++ b/src/types/UiaTextRangeBase.cpp @@ -295,7 +295,7 @@ void UiaTextRangeBase::_expandToEnclosingUnit(TextUnit unit) if (unit == TextUnit_Character) { _start = buffer.GetGlyphStart(_start, documentEnd); - _end = buffer.GetGlyphEnd(_start, documentEnd); + _end = buffer.GetGlyphEnd(_start, true, documentEnd); } else if (unit <= TextUnit_Word) {