Skip to content

Commit

Permalink
Fix color selection operations in conhost (microsoft#8577)
Browse files Browse the repository at this point in the history
In conhost there is a keyboard shortcut that applies colors to the
selected range of text, and another shortcut that searches for the
selected text, and applies colors to any matching content. The former
operation doesn't work correctly when the selection is wrapped, and both
have problems when the selected text spans DBCS characters. This PR
attempts to fix those issues.

The problem with the color section was that it applied the color to a
simple rect spanning the start and end points of the selection. I've now
updated it to use the `Selection::GetSelectionRects` method, which
correctly handles a wrapped range of lines, and makes sure that double
width characters are fully covered.

The problem with the "find-and-color" operation was in the way it
obtained the search text from the selected screen cells. Since it
retrieved one cell at a time, and a DBCS character can span two cells,
that resulted in some characters being repeated in the search text. I've
now corrected that code to take the width of the characters into
account.

## Validation Steps Performed
I've manually verified that the test cases described in microsoft#8572 and microsoft#8574
are now working correctly.

Closes microsoft#8572
Closes microsoft#8574
  • Loading branch information
j4james authored and mpela81 committed Jan 28, 2021
1 parent 06bf911 commit 851d24a
Showing 1 changed file with 10 additions and 5 deletions.
15 changes: 10 additions & 5 deletions src/host/selectionInput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -692,12 +692,13 @@ bool Selection::_HandleColorSelection(const INPUT_KEY_INFO* const pInputKeyInfo)
std::wstring str;
for (const auto& selectRect : selectionRects)
{
auto it = screenInfo.GetTextDataAt(COORD{ selectRect.Left, selectRect.Top });
auto it = screenInfo.GetCellDataAt(COORD{ selectRect.Left, selectRect.Top });

for (SHORT i = 0; i < (selectRect.Right - selectRect.Left + 1); ++i)
for (SHORT i = 0; i < (selectRect.Right - selectRect.Left + 1);)
{
str.append((*it).begin(), (*it).end());
it++;
str.append(it->Chars());
i += gsl::narrow_cast<SHORT>(it->Columns());
it += it->Columns();
}
}

Expand All @@ -717,7 +718,11 @@ bool Selection::_HandleColorSelection(const INPUT_KEY_INFO* const pInputKeyInfo)
}
else
{
ColorSelection(_srSelectionRect, selectionAttr);
const auto selectionRects = GetSelectionRects();
for (const auto& selectionRect : selectionRects)
{
ColorSelection(selectionRect, selectionAttr);
}
ClearSelection();
}

Expand Down

0 comments on commit 851d24a

Please sign in to comment.