mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-19 18:11:39 -05:00
Use 32-bit coordinates throughout the project (#13025)
Previously this project used a great variety of types to present text buffer coordinates: `short`, `unsigned short`, `int`, `unsigned int`, `size_t`, `ptrdiff_t`, `COORD`/`SMALL_RECT` (aka `short`), and more. This massive commit migrates almost all use of those types over to the centralized types `til::point`/`size`/`rect`/`inclusive_rect` and their underlying type `til::CoordType` (aka `int32_t`). Due to the size of the changeset and statistics I expect it to contain bugs. The biggest risk I see is that some code potentially, maybe implicitly, expected arithmetic to be mod 2^16 and that this code now allows it to be mod 2^32. Any narrowing into `short` later on would then throw exceptions. ## PR Checklist * [x] Closes #4015 * [x] I work here * [x] Tests added/passed ## Validation Steps Performed Casual usage of OpenConsole and Windows Terminal. ✅
This commit is contained in:
@@ -11,8 +11,8 @@
|
|||||||
// - attr - the default text attribute
|
// - attr - the default text attribute
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - constructed object
|
// - constructed object
|
||||||
ATTR_ROW::ATTR_ROW(const uint16_t width, const TextAttribute attr) :
|
ATTR_ROW::ATTR_ROW(const til::CoordType width, const TextAttribute attr) :
|
||||||
_data(width, attr) {}
|
_data(gsl::narrow_cast<uint16_t>(width), attr) {}
|
||||||
|
|
||||||
// Routine Description:
|
// Routine Description:
|
||||||
// - Sets all properties of the ATTR_ROW to default values
|
// - Sets all properties of the ATTR_ROW to default values
|
||||||
@@ -32,9 +32,9 @@ void ATTR_ROW::Reset(const TextAttribute attr)
|
|||||||
// - newWidth - The new width of the row.
|
// - newWidth - The new width of the row.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - <none>, throws exceptions on failures.
|
// - <none>, throws exceptions on failures.
|
||||||
void ATTR_ROW::Resize(const uint16_t newWidth)
|
void ATTR_ROW::Resize(const til::CoordType newWidth)
|
||||||
{
|
{
|
||||||
_data.resize_trailing_extent(newWidth);
|
_data.resize_trailing_extent(gsl::narrow<uint16_t>(newWidth));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routine Description:
|
// Routine Description:
|
||||||
@@ -45,9 +45,9 @@ void ATTR_ROW::Resize(const uint16_t newWidth)
|
|||||||
// - the text attribute at column
|
// - the text attribute at column
|
||||||
// Note:
|
// Note:
|
||||||
// - will throw on error
|
// - will throw on error
|
||||||
TextAttribute ATTR_ROW::GetAttrByColumn(const uint16_t column) const
|
TextAttribute ATTR_ROW::GetAttrByColumn(const til::CoordType column) const
|
||||||
{
|
{
|
||||||
return _data.at(column);
|
return _data.at(gsl::narrow<uint16_t>(column));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routine Description:
|
// Routine Description:
|
||||||
@@ -74,7 +74,7 @@ std::vector<uint16_t> ATTR_ROW::GetHyperlinks() const
|
|||||||
// - attr - Attribute (color) to fill remaining characters with
|
// - attr - Attribute (color) to fill remaining characters with
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - <none>
|
// - <none>
|
||||||
bool ATTR_ROW::SetAttrToEnd(const uint16_t beginIndex, const TextAttribute attr)
|
bool ATTR_ROW::SetAttrToEnd(const til::CoordType beginIndex, const TextAttribute attr)
|
||||||
{
|
{
|
||||||
_data.replace(gsl::narrow<uint16_t>(beginIndex), _data.size(), attr);
|
_data.replace(gsl::narrow<uint16_t>(beginIndex), _data.size(), attr);
|
||||||
return true;
|
return true;
|
||||||
@@ -103,9 +103,9 @@ void ATTR_ROW::ReplaceAttrs(const TextAttribute& toBeReplacedAttr, const TextAtt
|
|||||||
// - newAttr: The attribute to merge into this row.
|
// - newAttr: The attribute to merge into this row.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - <none>
|
// - <none>
|
||||||
void ATTR_ROW::Replace(const uint16_t beginIndex, const uint16_t endIndex, const TextAttribute& newAttr)
|
void ATTR_ROW::Replace(const til::CoordType beginIndex, const til::CoordType endIndex, const TextAttribute& newAttr)
|
||||||
{
|
{
|
||||||
_data.replace(beginIndex, endIndex, newAttr);
|
_data.replace(gsl::narrow<uint16_t>(beginIndex), gsl::narrow<uint16_t>(endIndex), newAttr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ATTR_ROW::const_iterator ATTR_ROW::begin() const noexcept
|
ATTR_ROW::const_iterator ATTR_ROW::begin() const noexcept
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class ATTR_ROW final
|
|||||||
public:
|
public:
|
||||||
using const_iterator = rle_vector::const_iterator;
|
using const_iterator = rle_vector::const_iterator;
|
||||||
|
|
||||||
ATTR_ROW(uint16_t width, TextAttribute attr);
|
ATTR_ROW(til::CoordType width, TextAttribute attr);
|
||||||
|
|
||||||
~ATTR_ROW() = default;
|
~ATTR_ROW() = default;
|
||||||
|
|
||||||
@@ -40,13 +40,13 @@ public:
|
|||||||
noexcept = default;
|
noexcept = default;
|
||||||
ATTR_ROW& operator=(ATTR_ROW&&) noexcept = default;
|
ATTR_ROW& operator=(ATTR_ROW&&) noexcept = default;
|
||||||
|
|
||||||
TextAttribute GetAttrByColumn(uint16_t column) const;
|
TextAttribute GetAttrByColumn(til::CoordType column) const;
|
||||||
std::vector<uint16_t> GetHyperlinks() const;
|
std::vector<uint16_t> GetHyperlinks() const;
|
||||||
|
|
||||||
bool SetAttrToEnd(uint16_t beginIndex, TextAttribute attr);
|
bool SetAttrToEnd(til::CoordType beginIndex, TextAttribute attr);
|
||||||
void ReplaceAttrs(const TextAttribute& toBeReplacedAttr, const TextAttribute& replaceWith);
|
void ReplaceAttrs(const TextAttribute& toBeReplacedAttr, const TextAttribute& replaceWith);
|
||||||
void Resize(uint16_t newWidth);
|
void Resize(til::CoordType newWidth);
|
||||||
void Replace(uint16_t beginIndex, uint16_t endIndex, const TextAttribute& newAttr);
|
void Replace(til::CoordType beginIndex, til::CoordType endIndex, const TextAttribute& newAttr);
|
||||||
|
|
||||||
const_iterator begin() const noexcept;
|
const_iterator begin() const noexcept;
|
||||||
const_iterator end() const noexcept;
|
const_iterator end() const noexcept;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
// Note: will through if unable to allocate char/attribute buffers
|
// Note: will through if unable to allocate char/attribute buffers
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 26447) // small_vector's constructor says it can throw but it should not given how we use it. This suppresses this error for the AuditMode build.
|
#pragma warning(disable : 26447) // small_vector's constructor says it can throw but it should not given how we use it. This suppresses this error for the AuditMode build.
|
||||||
CharRow::CharRow(size_t rowWidth, ROW* const pParent) noexcept :
|
CharRow::CharRow(til::CoordType rowWidth, ROW* const pParent) noexcept :
|
||||||
_data(rowWidth, value_type()),
|
_data(rowWidth, value_type()),
|
||||||
_pParent{ FAIL_FAST_IF_NULL(pParent) }
|
_pParent{ FAIL_FAST_IF_NULL(pParent) }
|
||||||
{
|
{
|
||||||
@@ -30,9 +30,9 @@ CharRow::CharRow(size_t rowWidth, ROW* const pParent) noexcept :
|
|||||||
// - <none>
|
// - <none>
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - the size of the row
|
// - the size of the row
|
||||||
size_t CharRow::size() const noexcept
|
til::CoordType CharRow::size() const noexcept
|
||||||
{
|
{
|
||||||
return _data.size();
|
return gsl::narrow_cast<til::CoordType>(_data.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routine Description:
|
// Routine Description:
|
||||||
@@ -55,7 +55,7 @@ void CharRow::Reset() noexcept
|
|||||||
// - newSize - the new width of the character and attributes rows
|
// - newSize - the new width of the character and attributes rows
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - S_OK on success, otherwise relevant error code
|
// - S_OK on success, otherwise relevant error code
|
||||||
[[nodiscard]] HRESULT CharRow::Resize(const size_t newSize) noexcept
|
[[nodiscard]] HRESULT CharRow::Resize(const til::CoordType newSize) noexcept
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -93,14 +93,14 @@ typename CharRow::const_iterator CharRow::cend() const noexcept
|
|||||||
// - <none>
|
// - <none>
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The calculated left boundary of the internal string.
|
// - The calculated left boundary of the internal string.
|
||||||
size_t CharRow::MeasureLeft() const noexcept
|
til::CoordType CharRow::MeasureLeft() const noexcept
|
||||||
{
|
{
|
||||||
auto it = _data.cbegin();
|
auto it = _data.cbegin();
|
||||||
while (it != _data.cend() && it->IsSpace())
|
while (it != _data.cend() && it->IsSpace())
|
||||||
{
|
{
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
return it - _data.cbegin();
|
return gsl::narrow_cast<til::CoordType>(it - _data.cbegin());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routine Description:
|
// Routine Description:
|
||||||
@@ -109,17 +109,17 @@ size_t CharRow::MeasureLeft() const noexcept
|
|||||||
// - <none>
|
// - <none>
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The calculated right boundary of the internal string.
|
// - The calculated right boundary of the internal string.
|
||||||
size_t CharRow::MeasureRight() const
|
til::CoordType CharRow::MeasureRight() const
|
||||||
{
|
{
|
||||||
auto it = _data.crbegin();
|
auto it = _data.crbegin();
|
||||||
while (it != _data.crend() && it->IsSpace())
|
while (it != _data.crend() && it->IsSpace())
|
||||||
{
|
{
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
return _data.crend() - it;
|
return gsl::narrow_cast<til::CoordType>(_data.crend() - it);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharRow::ClearCell(const size_t column)
|
void CharRow::ClearCell(const til::CoordType column)
|
||||||
{
|
{
|
||||||
_data.at(column).Reset();
|
_data.at(column).Reset();
|
||||||
}
|
}
|
||||||
@@ -149,7 +149,7 @@ bool CharRow::ContainsText() const noexcept
|
|||||||
// Return Value:
|
// Return Value:
|
||||||
// - the attribute
|
// - the attribute
|
||||||
// Note: will throw exception if column is out of bounds
|
// Note: will throw exception if column is out of bounds
|
||||||
const DbcsAttribute& CharRow::DbcsAttrAt(const size_t column) const
|
const DbcsAttribute& CharRow::DbcsAttrAt(const til::CoordType column) const
|
||||||
{
|
{
|
||||||
return _data.at(column).DbcsAttr();
|
return _data.at(column).DbcsAttr();
|
||||||
}
|
}
|
||||||
@@ -161,7 +161,7 @@ const DbcsAttribute& CharRow::DbcsAttrAt(const size_t column) const
|
|||||||
// Return Value:
|
// Return Value:
|
||||||
// - the attribute
|
// - the attribute
|
||||||
// Note: will throw exception if column is out of bounds
|
// Note: will throw exception if column is out of bounds
|
||||||
DbcsAttribute& CharRow::DbcsAttrAt(const size_t column)
|
DbcsAttribute& CharRow::DbcsAttrAt(const til::CoordType column)
|
||||||
{
|
{
|
||||||
return _data.at(column).DbcsAttr();
|
return _data.at(column).DbcsAttr();
|
||||||
}
|
}
|
||||||
@@ -173,7 +173,7 @@ DbcsAttribute& CharRow::DbcsAttrAt(const size_t column)
|
|||||||
// Return Value:
|
// Return Value:
|
||||||
// - <none>
|
// - <none>
|
||||||
// Note: will throw exception if column is out of bounds
|
// Note: will throw exception if column is out of bounds
|
||||||
void CharRow::ClearGlyph(const size_t column)
|
void CharRow::ClearGlyph(const til::CoordType column)
|
||||||
{
|
{
|
||||||
_data.at(column).EraseChars();
|
_data.at(column).EraseChars();
|
||||||
}
|
}
|
||||||
@@ -185,9 +185,9 @@ void CharRow::ClearGlyph(const size_t column)
|
|||||||
// Return Value:
|
// Return Value:
|
||||||
// - text data at column
|
// - text data at column
|
||||||
// - Note: will throw exception if column is out of bounds
|
// - Note: will throw exception if column is out of bounds
|
||||||
const CharRow::reference CharRow::GlyphAt(const size_t column) const
|
const CharRow::reference CharRow::GlyphAt(const til::CoordType column) const
|
||||||
{
|
{
|
||||||
THROW_HR_IF(E_INVALIDARG, column >= _data.size());
|
THROW_HR_IF(E_INVALIDARG, column < 0 || column >= gsl::narrow_cast<til::CoordType>(_data.size()));
|
||||||
return { const_cast<CharRow&>(*this), column };
|
return { const_cast<CharRow&>(*this), column };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,9 +198,9 @@ const CharRow::reference CharRow::GlyphAt(const size_t column) const
|
|||||||
// Return Value:
|
// Return Value:
|
||||||
// - text data at column
|
// - text data at column
|
||||||
// - Note: will throw exception if column is out of bounds
|
// - Note: will throw exception if column is out of bounds
|
||||||
CharRow::reference CharRow::GlyphAt(const size_t column)
|
CharRow::reference CharRow::GlyphAt(const til::CoordType column)
|
||||||
{
|
{
|
||||||
THROW_HR_IF(E_INVALIDARG, column >= _data.size());
|
THROW_HR_IF(E_INVALIDARG, column < 0 || column >= gsl::narrow_cast<til::CoordType>(_data.size()));
|
||||||
return { *this, column };
|
return { *this, column };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +209,7 @@ std::wstring CharRow::GetText() const
|
|||||||
std::wstring wstr;
|
std::wstring wstr;
|
||||||
wstr.reserve(_data.size());
|
wstr.reserve(_data.size());
|
||||||
|
|
||||||
for (size_t i = 0; i < _data.size(); ++i)
|
for (til::CoordType i = 0; i < gsl::narrow_cast<til::CoordType>(_data.size()); ++i)
|
||||||
{
|
{
|
||||||
const auto glyph = GlyphAt(i);
|
const auto glyph = GlyphAt(i);
|
||||||
if (!DbcsAttrAt(i).IsTrailing())
|
if (!DbcsAttrAt(i).IsTrailing())
|
||||||
@@ -231,9 +231,9 @@ std::wstring CharRow::GetText() const
|
|||||||
// - wordDelimiters: the delimiters defined as a part of the DelimiterClass::DelimiterChar
|
// - wordDelimiters: the delimiters defined as a part of the DelimiterClass::DelimiterChar
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - the delimiter class for the given char
|
// - the delimiter class for the given char
|
||||||
const DelimiterClass CharRow::DelimiterClassAt(const size_t column, const std::wstring_view wordDelimiters) const
|
const DelimiterClass CharRow::DelimiterClassAt(const til::CoordType column, const std::wstring_view wordDelimiters) const
|
||||||
{
|
{
|
||||||
THROW_HR_IF(E_INVALIDARG, column >= _data.size());
|
THROW_HR_IF(E_INVALIDARG, column < 0 || column >= gsl::narrow_cast<til::CoordType>(_data.size()));
|
||||||
|
|
||||||
const auto glyph = *GlyphAt(column).begin();
|
const auto glyph = *GlyphAt(column).begin();
|
||||||
if (glyph <= UNICODE_SPACE)
|
if (glyph <= UNICODE_SPACE)
|
||||||
@@ -265,10 +265,10 @@ const UnicodeStorage& CharRow::GetUnicodeStorage() const noexcept
|
|||||||
// Arguments:
|
// Arguments:
|
||||||
// - column - the column to generate the key for
|
// - column - the column to generate the key for
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - the COORD key for data access from UnicodeStorage for the column
|
// - the til::point key for data access from UnicodeStorage for the column
|
||||||
COORD CharRow::GetStorageKey(const size_t column) const noexcept
|
til::point CharRow::GetStorageKey(const til::CoordType column) const noexcept
|
||||||
{
|
{
|
||||||
return { gsl::narrow<SHORT>(column), _pParent->GetId() };
|
return { column, _pParent->GetId() };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routine Description:
|
// Routine Description:
|
||||||
|
|||||||
@@ -54,22 +54,22 @@ public:
|
|||||||
using const_reverse_iterator = typename boost::container::small_vector_base<value_type>::const_reverse_iterator;
|
using const_reverse_iterator = typename boost::container::small_vector_base<value_type>::const_reverse_iterator;
|
||||||
using reference = typename CharRowCellReference;
|
using reference = typename CharRowCellReference;
|
||||||
|
|
||||||
CharRow(size_t rowWidth, ROW* const pParent) noexcept;
|
CharRow(til::CoordType rowWidth, ROW* const pParent) noexcept;
|
||||||
|
|
||||||
size_t size() const noexcept;
|
til::CoordType size() const noexcept;
|
||||||
[[nodiscard]] HRESULT Resize(const size_t newSize) noexcept;
|
[[nodiscard]] HRESULT Resize(const til::CoordType newSize) noexcept;
|
||||||
size_t MeasureLeft() const noexcept;
|
til::CoordType MeasureLeft() const noexcept;
|
||||||
size_t MeasureRight() const;
|
til::CoordType MeasureRight() const;
|
||||||
bool ContainsText() const noexcept;
|
bool ContainsText() const noexcept;
|
||||||
const DbcsAttribute& DbcsAttrAt(const size_t column) const;
|
const DbcsAttribute& DbcsAttrAt(const til::CoordType column) const;
|
||||||
DbcsAttribute& DbcsAttrAt(const size_t column);
|
DbcsAttribute& DbcsAttrAt(const til::CoordType column);
|
||||||
void ClearGlyph(const size_t column);
|
void ClearGlyph(const til::CoordType column);
|
||||||
|
|
||||||
const DelimiterClass DelimiterClassAt(const size_t column, const std::wstring_view wordDelimiters) const;
|
const DelimiterClass DelimiterClassAt(const til::CoordType column, const std::wstring_view wordDelimiters) const;
|
||||||
|
|
||||||
// working with glyphs
|
// working with glyphs
|
||||||
const reference GlyphAt(const size_t column) const;
|
const reference GlyphAt(const til::CoordType column) const;
|
||||||
reference GlyphAt(const size_t column);
|
reference GlyphAt(const til::CoordType column);
|
||||||
|
|
||||||
// iterators
|
// iterators
|
||||||
iterator begin() noexcept;
|
iterator begin() noexcept;
|
||||||
@@ -82,7 +82,7 @@ public:
|
|||||||
|
|
||||||
UnicodeStorage& GetUnicodeStorage() noexcept;
|
UnicodeStorage& GetUnicodeStorage() noexcept;
|
||||||
const UnicodeStorage& GetUnicodeStorage() const noexcept;
|
const UnicodeStorage& GetUnicodeStorage() const noexcept;
|
||||||
COORD GetStorageKey(const size_t column) const noexcept;
|
til::point GetStorageKey(const til::CoordType column) const noexcept;
|
||||||
|
|
||||||
void UpdateParent(ROW* const pParent);
|
void UpdateParent(ROW* const pParent);
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void Reset() noexcept;
|
void Reset() noexcept;
|
||||||
void ClearCell(const size_t column);
|
void ClearCell(const til::CoordType column);
|
||||||
std::wstring GetText() const;
|
std::wstring GetText() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class CharRowCellReference final
|
|||||||
public:
|
public:
|
||||||
using const_iterator = const wchar_t*;
|
using const_iterator = const wchar_t*;
|
||||||
|
|
||||||
CharRowCellReference(CharRow& parent, const size_t index) noexcept :
|
CharRowCellReference(CharRow& parent, const til::CoordType index) noexcept :
|
||||||
_parent{ parent },
|
_parent{ parent },
|
||||||
_index{ index }
|
_index{ index }
|
||||||
{
|
{
|
||||||
@@ -51,7 +51,7 @@ private:
|
|||||||
// what char row the object belongs to
|
// what char row the object belongs to
|
||||||
CharRow& _parent;
|
CharRow& _parent;
|
||||||
// the index of the cell in the parent char row
|
// the index of the cell in the parent char row
|
||||||
const size_t _index;
|
til::CoordType _index;
|
||||||
|
|
||||||
CharRowCell& _cellData();
|
CharRowCell& _cellData();
|
||||||
const CharRowCell& _cellData() const;
|
const CharRowCell& _cellData() const;
|
||||||
|
|||||||
@@ -21,16 +21,16 @@ enum class LineRendition
|
|||||||
DoubleHeightBottom
|
DoubleHeightBottom
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr SMALL_RECT ScreenToBufferLine(const SMALL_RECT& line, const LineRendition lineRendition)
|
constexpr til::inclusive_rect ScreenToBufferLine(const til::inclusive_rect& line, const LineRendition lineRendition)
|
||||||
{
|
{
|
||||||
// Use shift right to quickly divide the Left and Right by 2 for double width lines.
|
// Use shift right to quickly divide the Left and Right by 2 for double width lines.
|
||||||
const SHORT scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
|
const auto scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
|
||||||
return { line.Left >> scale, line.Top, line.Right >> scale, line.Bottom };
|
return { line.Left >> scale, line.Top, line.Right >> scale, line.Bottom };
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr SMALL_RECT BufferToScreenLine(const SMALL_RECT& line, const LineRendition lineRendition)
|
constexpr til::inclusive_rect BufferToScreenLine(const til::inclusive_rect& line, const LineRendition lineRendition)
|
||||||
{
|
{
|
||||||
// Use shift left to quickly multiply the Left and Right by 2 for double width lines.
|
// Use shift left to quickly multiply the Left and Right by 2 for double width lines.
|
||||||
const SHORT scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
|
const auto scale = lineRendition == LineRendition::SingleWidth ? 0 : 1;
|
||||||
return { line.Left << scale, line.Top, (line.Right << scale) + scale, line.Bottom };
|
return { line.Left << scale, line.Top, (line.Right << scale) + scale, line.Bottom };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -531,16 +531,16 @@ OutputCellView OutputCellIterator::s_GenerateView(const OutputCell& cell)
|
|||||||
// - Gets the distance between two iterators relative to the input data given in.
|
// - Gets the distance between two iterators relative to the input data given in.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The number of items of the input run consumed between these two iterators.
|
// - The number of items of the input run consumed between these two iterators.
|
||||||
ptrdiff_t OutputCellIterator::GetInputDistance(OutputCellIterator other) const noexcept
|
til::CoordType OutputCellIterator::GetInputDistance(OutputCellIterator other) const noexcept
|
||||||
{
|
{
|
||||||
return _pos - other._pos;
|
return gsl::narrow_cast<til::CoordType>(_pos - other._pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routine Description:
|
// Routine Description:
|
||||||
// - Gets the distance between two iterators relative to the number of cells inserted.
|
// - Gets the distance between two iterators relative to the number of cells inserted.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The number of cells in the backing buffer filled between these two iterators.
|
// - The number of cells in the backing buffer filled between these two iterators.
|
||||||
ptrdiff_t OutputCellIterator::GetCellDistance(OutputCellIterator other) const noexcept
|
til::CoordType OutputCellIterator::GetCellDistance(OutputCellIterator other) const noexcept
|
||||||
{
|
{
|
||||||
return _distance - other._distance;
|
return gsl::narrow_cast<til::CoordType>(_distance - other._distance);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class OutputCellIterator final
|
|||||||
public:
|
public:
|
||||||
using iterator_category = std::input_iterator_tag;
|
using iterator_category = std::input_iterator_tag;
|
||||||
using value_type = OutputCellView;
|
using value_type = OutputCellView;
|
||||||
using difference_type = ptrdiff_t;
|
using difference_type = til::CoordType;
|
||||||
using pointer = OutputCellView*;
|
using pointer = OutputCellView*;
|
||||||
using reference = OutputCellView&;
|
using reference = OutputCellView&;
|
||||||
|
|
||||||
@@ -48,9 +48,9 @@ public:
|
|||||||
|
|
||||||
operator bool() const noexcept;
|
operator bool() const noexcept;
|
||||||
|
|
||||||
ptrdiff_t GetCellDistance(OutputCellIterator other) const noexcept;
|
til::CoordType GetCellDistance(OutputCellIterator other) const noexcept;
|
||||||
ptrdiff_t GetInputDistance(OutputCellIterator other) const noexcept;
|
til::CoordType GetInputDistance(OutputCellIterator other) const noexcept;
|
||||||
friend ptrdiff_t operator-(OutputCellIterator one, OutputCellIterator two) = delete;
|
friend til::CoordType operator-(OutputCellIterator one, OutputCellIterator two) = delete;
|
||||||
|
|
||||||
OutputCellIterator& operator++();
|
OutputCellIterator& operator++();
|
||||||
OutputCellIterator operator++(int);
|
OutputCellIterator operator++(int);
|
||||||
|
|||||||
@@ -21,14 +21,11 @@ OutputCellRect::OutputCellRect() noexcept :
|
|||||||
// Arguments:
|
// Arguments:
|
||||||
// - rows - Rows in the rectangle (height)
|
// - rows - Rows in the rectangle (height)
|
||||||
// - cols - Columns in the rectangle (width)
|
// - cols - Columns in the rectangle (width)
|
||||||
OutputCellRect::OutputCellRect(const size_t rows, const size_t cols) :
|
OutputCellRect::OutputCellRect(const til::CoordType rows, const til::CoordType cols) :
|
||||||
_rows(rows),
|
_rows(rows),
|
||||||
_cols(cols)
|
_cols(cols)
|
||||||
{
|
{
|
||||||
size_t totalCells;
|
_storage.resize(gsl::narrow<size_t>(rows * cols));
|
||||||
THROW_IF_FAILED(SizeTMult(rows, cols, &totalCells));
|
|
||||||
|
|
||||||
_storage.resize(totalCells);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routine Description:
|
// Routine Description:
|
||||||
@@ -37,7 +34,7 @@ OutputCellRect::OutputCellRect(const size_t rows, const size_t cols) :
|
|||||||
// - row - The Y position or row index in the buffer.
|
// - row - The Y position or row index in the buffer.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - Read/write span of OutputCells
|
// - Read/write span of OutputCells
|
||||||
gsl::span<OutputCell> OutputCellRect::GetRow(const size_t row)
|
gsl::span<OutputCell> OutputCellRect::GetRow(const til::CoordType row)
|
||||||
{
|
{
|
||||||
return gsl::span<OutputCell>(_FindRowOffset(row), _cols);
|
return gsl::span<OutputCell>(_FindRowOffset(row), _cols);
|
||||||
}
|
}
|
||||||
@@ -48,7 +45,7 @@ gsl::span<OutputCell> OutputCellRect::GetRow(const size_t row)
|
|||||||
// - row - The Y position or row index in the buffer.
|
// - row - The Y position or row index in the buffer.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - Read-only iterator of OutputCells
|
// - Read-only iterator of OutputCells
|
||||||
OutputCellIterator OutputCellRect::GetRowIter(const size_t row) const
|
OutputCellIterator OutputCellRect::GetRowIter(const til::CoordType row) const
|
||||||
{
|
{
|
||||||
const gsl::span<const OutputCell> view(_FindRowOffset(row), _cols);
|
const gsl::span<const OutputCell> view(_FindRowOffset(row), _cols);
|
||||||
|
|
||||||
@@ -62,9 +59,9 @@ OutputCellIterator OutputCellRect::GetRowIter(const size_t row) const
|
|||||||
// - row - The Y position or row index in the buffer.
|
// - row - The Y position or row index in the buffer.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - Pointer to the location in the rectangle that represents the start of the requested row.
|
// - Pointer to the location in the rectangle that represents the start of the requested row.
|
||||||
OutputCell* OutputCellRect::_FindRowOffset(const size_t row)
|
OutputCell* OutputCellRect::_FindRowOffset(const til::CoordType row)
|
||||||
{
|
{
|
||||||
return &_storage.at(row * _cols);
|
return &_storage.at(gsl::narrow_cast<size_t>(row * _cols));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routine Description:
|
// Routine Description:
|
||||||
@@ -74,16 +71,16 @@ OutputCell* OutputCellRect::_FindRowOffset(const size_t row)
|
|||||||
// - row - The Y position or row index in the buffer.
|
// - row - The Y position or row index in the buffer.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - Pointer to the location in the rectangle that represents the start of the requested row.
|
// - Pointer to the location in the rectangle that represents the start of the requested row.
|
||||||
const OutputCell* OutputCellRect::_FindRowOffset(const size_t row) const
|
const OutputCell* OutputCellRect::_FindRowOffset(const til::CoordType row) const
|
||||||
{
|
{
|
||||||
return &_storage.at(row * _cols);
|
return &_storage.at(gsl::narrow_cast<size_t>(row * _cols));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routine Description:
|
// Routine Description:
|
||||||
// - Gets the height of the rectangle
|
// - Gets the height of the rectangle
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - Height
|
// - Height
|
||||||
size_t OutputCellRect::Height() const noexcept
|
til::CoordType OutputCellRect::Height() const noexcept
|
||||||
{
|
{
|
||||||
return _rows;
|
return _rows;
|
||||||
}
|
}
|
||||||
@@ -92,7 +89,7 @@ size_t OutputCellRect::Height() const noexcept
|
|||||||
// - Gets the width of the rectangle
|
// - Gets the width of the rectangle
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - Width
|
// - Width
|
||||||
size_t OutputCellRect::Width() const noexcept
|
til::CoordType OutputCellRect::Width() const noexcept
|
||||||
{
|
{
|
||||||
return _cols;
|
return _cols;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,20 +30,20 @@ class OutputCellRect final
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OutputCellRect() noexcept;
|
OutputCellRect() noexcept;
|
||||||
OutputCellRect(const size_t rows, const size_t cols);
|
OutputCellRect(const til::CoordType rows, const til::CoordType cols);
|
||||||
|
|
||||||
gsl::span<OutputCell> GetRow(const size_t row);
|
gsl::span<OutputCell> GetRow(const til::CoordType row);
|
||||||
OutputCellIterator GetRowIter(const size_t row) const;
|
OutputCellIterator GetRowIter(const til::CoordType row) const;
|
||||||
|
|
||||||
size_t Height() const noexcept;
|
til::CoordType Height() const noexcept;
|
||||||
size_t Width() const noexcept;
|
til::CoordType Width() const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<OutputCell> _storage;
|
std::vector<OutputCell> _storage;
|
||||||
|
|
||||||
OutputCell* _FindRowOffset(const size_t row);
|
OutputCell* _FindRowOffset(const til::CoordType row);
|
||||||
const OutputCell* _FindRowOffset(const size_t row) const;
|
const OutputCell* _FindRowOffset(const til::CoordType row) const;
|
||||||
|
|
||||||
size_t _cols;
|
til::CoordType _cols;
|
||||||
size_t _rows;
|
til::CoordType _rows;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ OutputCellView::OutputCellView(const std::wstring_view view,
|
|||||||
// - Reports how many columns we expect the Chars() text data to consume
|
// - Reports how many columns we expect the Chars() text data to consume
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - Count of column cells on the screen
|
// - Count of column cells on the screen
|
||||||
size_t OutputCellView::Columns() const noexcept
|
til::CoordType OutputCellView::Columns() const noexcept
|
||||||
{
|
{
|
||||||
if (DbcsAttr().IsSingle())
|
if (DbcsAttr().IsSingle())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public:
|
|||||||
const TextAttributeBehavior behavior) noexcept;
|
const TextAttributeBehavior behavior) noexcept;
|
||||||
|
|
||||||
const std::wstring_view& Chars() const noexcept;
|
const std::wstring_view& Chars() const noexcept;
|
||||||
size_t Columns() const noexcept;
|
til::CoordType Columns() const noexcept;
|
||||||
DbcsAttribute DbcsAttr() const noexcept;
|
DbcsAttribute DbcsAttr() const noexcept;
|
||||||
TextAttribute TextAttr() const noexcept;
|
TextAttribute TextAttr() const noexcept;
|
||||||
TextAttributeBehavior TextAttrBehavior() const noexcept;
|
TextAttributeBehavior TextAttrBehavior() const noexcept;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
// - pParent - the text buffer that this row belongs to
|
// - pParent - the text buffer that this row belongs to
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - constructed object
|
// - constructed object
|
||||||
ROW::ROW(const SHORT rowId, const unsigned short rowWidth, const TextAttribute fillAttribute, TextBuffer* const pParent) :
|
ROW::ROW(const til::CoordType rowId, const til::CoordType rowWidth, const TextAttribute fillAttribute, TextBuffer* const pParent) :
|
||||||
_id{ rowId },
|
_id{ rowId },
|
||||||
_rowWidth{ rowWidth },
|
_rowWidth{ rowWidth },
|
||||||
_charRow{ rowWidth, this },
|
_charRow{ rowWidth, this },
|
||||||
@@ -58,7 +58,7 @@ bool ROW::Reset(const TextAttribute Attr)
|
|||||||
// - width - the new width, in cells
|
// - width - the new width, in cells
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - S_OK if successful, otherwise relevant error
|
// - S_OK if successful, otherwise relevant error
|
||||||
[[nodiscard]] HRESULT ROW::Resize(const unsigned short width)
|
[[nodiscard]] HRESULT ROW::Resize(const til::CoordType width)
|
||||||
{
|
{
|
||||||
RETURN_IF_FAILED(_charRow.Resize(width));
|
RETURN_IF_FAILED(_charRow.Resize(width));
|
||||||
try
|
try
|
||||||
@@ -78,7 +78,7 @@ bool ROW::Reset(const TextAttribute Attr)
|
|||||||
// - column - 0-indexed column index
|
// - column - 0-indexed column index
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - <none>
|
// - <none>
|
||||||
void ROW::ClearColumn(const size_t column)
|
void ROW::ClearColumn(const til::CoordType column)
|
||||||
{
|
{
|
||||||
THROW_HR_IF(E_INVALIDARG, column >= _charRow.size());
|
THROW_HR_IF(E_INVALIDARG, column >= _charRow.size());
|
||||||
_charRow.ClearCell(column);
|
_charRow.ClearCell(column);
|
||||||
@@ -103,7 +103,7 @@ const UnicodeStorage& ROW::GetUnicodeStorage() const noexcept
|
|||||||
// - limitRight - right inclusive column ID for the last write in this row. (optional, will just write to the end of row if nullopt)
|
// - limitRight - right inclusive column ID for the last write in this row. (optional, will just write to the end of row if nullopt)
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - iterator to first cell that was not written to this row.
|
// - iterator to first cell that was not written to this row.
|
||||||
OutputCellIterator ROW::WriteCells(OutputCellIterator it, const size_t index, const std::optional<bool> wrap, std::optional<size_t> limitRight)
|
OutputCellIterator ROW::WriteCells(OutputCellIterator it, const til::CoordType index, const std::optional<bool> wrap, std::optional<til::CoordType> limitRight)
|
||||||
{
|
{
|
||||||
THROW_HR_IF(E_INVALIDARG, index >= _charRow.size());
|
THROW_HR_IF(E_INVALIDARG, index >= _charRow.size());
|
||||||
THROW_HR_IF(E_INVALIDARG, limitRight.value_or(0) >= _charRow.size());
|
THROW_HR_IF(E_INVALIDARG, limitRight.value_or(0) >= _charRow.size());
|
||||||
|
|||||||
@@ -32,9 +32,9 @@ class TextBuffer;
|
|||||||
class ROW final
|
class ROW final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ROW(const SHORT rowId, const unsigned short rowWidth, const TextAttribute fillAttribute, TextBuffer* const pParent);
|
ROW(const til::CoordType rowId, const til::CoordType rowWidth, const TextAttribute fillAttribute, TextBuffer* const pParent);
|
||||||
|
|
||||||
size_t size() const noexcept { return _rowWidth; }
|
til::CoordType size() const noexcept { return _rowWidth; }
|
||||||
|
|
||||||
void SetWrapForced(const bool wrap) noexcept { _wrapForced = wrap; }
|
void SetWrapForced(const bool wrap) noexcept { _wrapForced = wrap; }
|
||||||
bool WasWrapForced() const noexcept { return _wrapForced; }
|
bool WasWrapForced() const noexcept { return _wrapForced; }
|
||||||
@@ -51,19 +51,19 @@ public:
|
|||||||
LineRendition GetLineRendition() const noexcept { return _lineRendition; }
|
LineRendition GetLineRendition() const noexcept { return _lineRendition; }
|
||||||
void SetLineRendition(const LineRendition lineRendition) noexcept { _lineRendition = lineRendition; }
|
void SetLineRendition(const LineRendition lineRendition) noexcept { _lineRendition = lineRendition; }
|
||||||
|
|
||||||
SHORT GetId() const noexcept { return _id; }
|
til::CoordType GetId() const noexcept { return _id; }
|
||||||
void SetId(const SHORT id) noexcept { _id = id; }
|
void SetId(const til::CoordType id) noexcept { _id = id; }
|
||||||
|
|
||||||
bool Reset(const TextAttribute Attr);
|
bool Reset(const TextAttribute Attr);
|
||||||
[[nodiscard]] HRESULT Resize(const unsigned short width);
|
[[nodiscard]] HRESULT Resize(const til::CoordType width);
|
||||||
|
|
||||||
void ClearColumn(const size_t column);
|
void ClearColumn(const til::CoordType column);
|
||||||
std::wstring GetText() const { return _charRow.GetText(); }
|
std::wstring GetText() const { return _charRow.GetText(); }
|
||||||
|
|
||||||
UnicodeStorage& GetUnicodeStorage() noexcept;
|
UnicodeStorage& GetUnicodeStorage() noexcept;
|
||||||
const UnicodeStorage& GetUnicodeStorage() const noexcept;
|
const UnicodeStorage& GetUnicodeStorage() const noexcept;
|
||||||
|
|
||||||
OutputCellIterator WriteCells(OutputCellIterator it, const size_t index, const std::optional<bool> wrap = std::nullopt, std::optional<size_t> limitRight = std::nullopt);
|
OutputCellIterator WriteCells(OutputCellIterator it, const til::CoordType index, const std::optional<bool> wrap = std::nullopt, std::optional<til::CoordType> limitRight = std::nullopt);
|
||||||
|
|
||||||
#ifdef UNIT_TESTING
|
#ifdef UNIT_TESTING
|
||||||
friend constexpr bool operator==(const ROW& a, const ROW& b) noexcept;
|
friend constexpr bool operator==(const ROW& a, const ROW& b) noexcept;
|
||||||
@@ -74,8 +74,8 @@ private:
|
|||||||
CharRow _charRow;
|
CharRow _charRow;
|
||||||
ATTR_ROW _attrRow;
|
ATTR_ROW _attrRow;
|
||||||
LineRendition _lineRendition;
|
LineRendition _lineRendition;
|
||||||
SHORT _id;
|
til::CoordType _id;
|
||||||
unsigned short _rowWidth;
|
til::CoordType _rowWidth;
|
||||||
// Occurs when the user runs out of text in a given row and we're forced to wrap the cursor to the next line
|
// Occurs when the user runs out of text in a given row and we're forced to wrap the cursor to the next line
|
||||||
bool _wrapForced;
|
bool _wrapForced;
|
||||||
// Occurs when the user runs out of text to support a double byte character and we're forced to the next line
|
// Occurs when the user runs out of text to support a double byte character and we're forced to the next line
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ void UnicodeStorage::Erase(const key_type key) noexcept
|
|||||||
// - rowMap - A map of the old row IDs to the new row IDs.
|
// - rowMap - A map of the old row IDs to the new row IDs.
|
||||||
// - width - The width of the new row. Remove any items that are beyond the row width.
|
// - width - The width of the new row. Remove any items that are beyond the row width.
|
||||||
// - Use nullopt if we're not resizing the width of the row, just renumbering the rows.
|
// - Use nullopt if we're not resizing the width of the row, just renumbering the rows.
|
||||||
void UnicodeStorage::Remap(const std::unordered_map<SHORT, SHORT>& rowMap, const std::optional<SHORT> width)
|
void UnicodeStorage::Remap(const std::unordered_map<til::CoordType, til::CoordType>& rowMap, const std::optional<til::CoordType> width)
|
||||||
{
|
{
|
||||||
// Make a temporary map to hold all the new row positioning
|
// Make a temporary map to hold all the new row positioning
|
||||||
std::unordered_map<key_type, mapped_type> newMap;
|
std::unordered_map<key_type, mapped_type> newMap;
|
||||||
@@ -87,7 +87,7 @@ void UnicodeStorage::Remap(const std::unordered_map<SHORT, SHORT>& rowMap, const
|
|||||||
const auto newRowId = mapIter->second;
|
const auto newRowId = mapIter->second;
|
||||||
|
|
||||||
// Generate a new coordinate with the same X as the old one, but a new Y value.
|
// Generate a new coordinate with the same X as the old one, but a new Y value.
|
||||||
const auto newCoord = COORD{ oldCoord.X, newRowId };
|
const auto newCoord = til::point{ oldCoord.X, newRowId };
|
||||||
|
|
||||||
// Put the adjusted coordinate into the map with the original value.
|
// Put the adjusted coordinate into the map with the original value.
|
||||||
newMap.emplace(newCoord, pair.second);
|
newMap.emplace(newCoord, pair.second);
|
||||||
|
|||||||
@@ -20,11 +20,11 @@ Author(s):
|
|||||||
#include <til/bit.h>
|
#include <til/bit.h>
|
||||||
#include <til/hash.h>
|
#include <til/hash.h>
|
||||||
|
|
||||||
// std::unordered_map needs help to know how to hash a COORD
|
// std::unordered_map needs help to know how to hash a til::point
|
||||||
namespace std
|
namespace std
|
||||||
{
|
{
|
||||||
template<>
|
template<>
|
||||||
struct hash<COORD>
|
struct hash<til::point>
|
||||||
{
|
{
|
||||||
// Routine Description:
|
// Routine Description:
|
||||||
// - hashes a coord. coord will be hashed by storing the x and y values consecutively in the lower
|
// - hashes a coord. coord will be hashed by storing the x and y values consecutively in the lower
|
||||||
@@ -33,9 +33,9 @@ namespace std
|
|||||||
// - coord - the coord to hash
|
// - coord - the coord to hash
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - the hashed coord
|
// - the hashed coord
|
||||||
constexpr size_t operator()(const COORD& coord) const noexcept
|
constexpr size_t operator()(const til::point coord) const noexcept
|
||||||
{
|
{
|
||||||
return til::hash(til::bit_cast<uint32_t>(coord));
|
return til::hash(til::bit_cast<uint64_t>(coord));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ namespace std
|
|||||||
class UnicodeStorage final
|
class UnicodeStorage final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using key_type = typename COORD;
|
using key_type = typename til::point;
|
||||||
using mapped_type = typename std::vector<wchar_t>;
|
using mapped_type = typename std::vector<wchar_t>;
|
||||||
|
|
||||||
UnicodeStorage() noexcept;
|
UnicodeStorage() noexcept;
|
||||||
@@ -54,7 +54,7 @@ public:
|
|||||||
|
|
||||||
void Erase(const key_type key) noexcept;
|
void Erase(const key_type key) noexcept;
|
||||||
|
|
||||||
void Remap(const std::unordered_map<SHORT, SHORT>& rowMap, const std::optional<SHORT> width);
|
void Remap(const std::unordered_map<til::CoordType, til::CoordType>& rowMap, const std::optional<til::CoordType> width);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<key_type, mapped_type> _map;
|
std::unordered_map<key_type, mapped_type> _map;
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
// - ulSize - The height of the cursor within this buffer
|
// - ulSize - The height of the cursor within this buffer
|
||||||
Cursor::Cursor(const ULONG ulSize, TextBuffer& parentBuffer) noexcept :
|
Cursor::Cursor(const ULONG ulSize, TextBuffer& parentBuffer) noexcept :
|
||||||
_parentBuffer{ parentBuffer },
|
_parentBuffer{ parentBuffer },
|
||||||
_cPosition{ 0 },
|
|
||||||
_fHasMoved(false),
|
_fHasMoved(false),
|
||||||
_fIsVisible(true),
|
_fIsVisible(true),
|
||||||
_fIsOn(true),
|
_fIsOn(true),
|
||||||
@@ -23,7 +22,6 @@ Cursor::Cursor(const ULONG ulSize, TextBuffer& parentBuffer) noexcept :
|
|||||||
_fIsConversionArea(false),
|
_fIsConversionArea(false),
|
||||||
_fIsPopupShown(false),
|
_fIsPopupShown(false),
|
||||||
_fDelayedEolWrap(false),
|
_fDelayedEolWrap(false),
|
||||||
_coordDelayedAt{ 0 },
|
|
||||||
_fDeferCursorRedraw(false),
|
_fDeferCursorRedraw(false),
|
||||||
_fHaveDeferredCursorRedraw(false),
|
_fHaveDeferredCursorRedraw(false),
|
||||||
_ulSize(ulSize),
|
_ulSize(ulSize),
|
||||||
@@ -35,7 +33,7 @@ Cursor::~Cursor()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
COORD Cursor::GetPosition() const noexcept
|
til::point Cursor::GetPosition() const noexcept
|
||||||
{
|
{
|
||||||
return _cPosition;
|
return _cPosition;
|
||||||
}
|
}
|
||||||
@@ -192,59 +190,58 @@ void Cursor::_RedrawCursorAlways() noexcept
|
|||||||
CATCH_LOG();
|
CATCH_LOG();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cursor::SetPosition(const COORD cPosition) noexcept
|
void Cursor::SetPosition(const til::point cPosition) noexcept
|
||||||
{
|
{
|
||||||
_RedrawCursor();
|
_RedrawCursor();
|
||||||
_cPosition.X = cPosition.X;
|
_cPosition = cPosition;
|
||||||
_cPosition.Y = cPosition.Y;
|
|
||||||
_RedrawCursor();
|
_RedrawCursor();
|
||||||
ResetDelayEOLWrap();
|
ResetDelayEOLWrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cursor::SetXPosition(const int NewX) noexcept
|
void Cursor::SetXPosition(const til::CoordType NewX) noexcept
|
||||||
{
|
{
|
||||||
_RedrawCursor();
|
_RedrawCursor();
|
||||||
_cPosition.X = gsl::narrow<SHORT>(NewX);
|
_cPosition.X = NewX;
|
||||||
_RedrawCursor();
|
_RedrawCursor();
|
||||||
ResetDelayEOLWrap();
|
ResetDelayEOLWrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cursor::SetYPosition(const int NewY) noexcept
|
void Cursor::SetYPosition(const til::CoordType NewY) noexcept
|
||||||
{
|
{
|
||||||
_RedrawCursor();
|
_RedrawCursor();
|
||||||
_cPosition.Y = gsl::narrow<SHORT>(NewY);
|
_cPosition.Y = NewY;
|
||||||
_RedrawCursor();
|
_RedrawCursor();
|
||||||
ResetDelayEOLWrap();
|
ResetDelayEOLWrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cursor::IncrementXPosition(const int DeltaX) noexcept
|
void Cursor::IncrementXPosition(const til::CoordType DeltaX) noexcept
|
||||||
{
|
{
|
||||||
_RedrawCursor();
|
_RedrawCursor();
|
||||||
_cPosition.X += gsl::narrow<SHORT>(DeltaX);
|
_cPosition.X += DeltaX;
|
||||||
_RedrawCursor();
|
_RedrawCursor();
|
||||||
ResetDelayEOLWrap();
|
ResetDelayEOLWrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cursor::IncrementYPosition(const int DeltaY) noexcept
|
void Cursor::IncrementYPosition(const til::CoordType DeltaY) noexcept
|
||||||
{
|
{
|
||||||
_RedrawCursor();
|
_RedrawCursor();
|
||||||
_cPosition.Y += gsl::narrow<SHORT>(DeltaY);
|
_cPosition.Y += DeltaY;
|
||||||
_RedrawCursor();
|
_RedrawCursor();
|
||||||
ResetDelayEOLWrap();
|
ResetDelayEOLWrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cursor::DecrementXPosition(const int DeltaX) noexcept
|
void Cursor::DecrementXPosition(const til::CoordType DeltaX) noexcept
|
||||||
{
|
{
|
||||||
_RedrawCursor();
|
_RedrawCursor();
|
||||||
_cPosition.X -= gsl::narrow<SHORT>(DeltaX);
|
_cPosition.X -= DeltaX;
|
||||||
_RedrawCursor();
|
_RedrawCursor();
|
||||||
ResetDelayEOLWrap();
|
ResetDelayEOLWrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cursor::DecrementYPosition(const int DeltaY) noexcept
|
void Cursor::DecrementYPosition(const til::CoordType DeltaY) noexcept
|
||||||
{
|
{
|
||||||
_RedrawCursor();
|
_RedrawCursor();
|
||||||
_cPosition.Y -= gsl::narrow<SHORT>(DeltaY);
|
_cPosition.Y -= DeltaY;
|
||||||
_RedrawCursor();
|
_RedrawCursor();
|
||||||
ResetDelayEOLWrap();
|
ResetDelayEOLWrap();
|
||||||
}
|
}
|
||||||
@@ -284,7 +281,7 @@ void Cursor::CopyProperties(const Cursor& OtherCursor) noexcept
|
|||||||
_cursorType = OtherCursor._cursorType;
|
_cursorType = OtherCursor._cursorType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cursor::DelayEOLWrap(const COORD coordDelayedAt) noexcept
|
void Cursor::DelayEOLWrap(const til::point coordDelayedAt) noexcept
|
||||||
{
|
{
|
||||||
_coordDelayedAt = coordDelayedAt;
|
_coordDelayedAt = coordDelayedAt;
|
||||||
_fDelayedEolWrap = true;
|
_fDelayedEolWrap = true;
|
||||||
@@ -292,11 +289,11 @@ void Cursor::DelayEOLWrap(const COORD coordDelayedAt) noexcept
|
|||||||
|
|
||||||
void Cursor::ResetDelayEOLWrap() noexcept
|
void Cursor::ResetDelayEOLWrap() noexcept
|
||||||
{
|
{
|
||||||
_coordDelayedAt = { 0 };
|
_coordDelayedAt = {};
|
||||||
_fDelayedEolWrap = false;
|
_fDelayedEolWrap = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
COORD Cursor::GetDelayedAtPosition() const noexcept
|
til::point Cursor::GetDelayedAtPosition() const noexcept
|
||||||
{
|
{
|
||||||
return _coordDelayedAt;
|
return _coordDelayedAt;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public:
|
|||||||
bool IsPopupShown() const noexcept;
|
bool IsPopupShown() const noexcept;
|
||||||
bool GetDelay() const noexcept;
|
bool GetDelay() const noexcept;
|
||||||
ULONG GetSize() const noexcept;
|
ULONG GetSize() const noexcept;
|
||||||
COORD GetPosition() const noexcept;
|
til::point GetPosition() const noexcept;
|
||||||
|
|
||||||
const CursorType GetType() const noexcept;
|
const CursorType GetType() const noexcept;
|
||||||
|
|
||||||
@@ -66,19 +66,19 @@ public:
|
|||||||
void SetSize(const ULONG ulSize) noexcept;
|
void SetSize(const ULONG ulSize) noexcept;
|
||||||
void SetStyle(const ULONG ulSize, const CursorType type) noexcept;
|
void SetStyle(const ULONG ulSize, const CursorType type) noexcept;
|
||||||
|
|
||||||
void SetPosition(const COORD cPosition) noexcept;
|
void SetPosition(const til::point cPosition) noexcept;
|
||||||
void SetXPosition(const int NewX) noexcept;
|
void SetXPosition(const til::CoordType NewX) noexcept;
|
||||||
void SetYPosition(const int NewY) noexcept;
|
void SetYPosition(const til::CoordType NewY) noexcept;
|
||||||
void IncrementXPosition(const int DeltaX) noexcept;
|
void IncrementXPosition(const til::CoordType DeltaX) noexcept;
|
||||||
void IncrementYPosition(const int DeltaY) noexcept;
|
void IncrementYPosition(const til::CoordType DeltaY) noexcept;
|
||||||
void DecrementXPosition(const int DeltaX) noexcept;
|
void DecrementXPosition(const til::CoordType DeltaX) noexcept;
|
||||||
void DecrementYPosition(const int DeltaY) noexcept;
|
void DecrementYPosition(const til::CoordType DeltaY) noexcept;
|
||||||
|
|
||||||
void CopyProperties(const Cursor& OtherCursor) noexcept;
|
void CopyProperties(const Cursor& OtherCursor) noexcept;
|
||||||
|
|
||||||
void DelayEOLWrap(const COORD coordDelayedAt) noexcept;
|
void DelayEOLWrap(const til::point coordDelayedAt) noexcept;
|
||||||
void ResetDelayEOLWrap() noexcept;
|
void ResetDelayEOLWrap() noexcept;
|
||||||
COORD GetDelayedAtPosition() const noexcept;
|
til::point GetDelayedAtPosition() const noexcept;
|
||||||
bool IsDelayedEOLWrap() const noexcept;
|
bool IsDelayedEOLWrap() const noexcept;
|
||||||
|
|
||||||
void SetType(const CursorType type) noexcept;
|
void SetType(const CursorType type) noexcept;
|
||||||
@@ -90,7 +90,7 @@ private:
|
|||||||
|
|
||||||
// NOTE: If you are adding a property here, go add it to CopyProperties.
|
// NOTE: If you are adding a property here, go add it to CopyProperties.
|
||||||
|
|
||||||
COORD _cPosition; // current position on screen (in screen buffer coords).
|
til::point _cPosition; // current position on screen (in screen buffer coords).
|
||||||
|
|
||||||
bool _fHasMoved;
|
bool _fHasMoved;
|
||||||
bool _fIsVisible; // whether cursor is visible (set only through the API)
|
bool _fIsVisible; // whether cursor is visible (set only through the API)
|
||||||
@@ -102,7 +102,7 @@ private:
|
|||||||
bool _fIsPopupShown; // if a popup is being shown, turn off, stop blinking.
|
bool _fIsPopupShown; // if a popup is being shown, turn off, stop blinking.
|
||||||
|
|
||||||
bool _fDelayedEolWrap; // don't wrap at EOL till the next char comes in.
|
bool _fDelayedEolWrap; // don't wrap at EOL till the next char comes in.
|
||||||
COORD _coordDelayedAt; // coordinate the EOL wrap was delayed at.
|
til::point _coordDelayedAt; // coordinate the EOL wrap was delayed at.
|
||||||
|
|
||||||
bool _fDeferCursorRedraw; // whether we should defer redrawing the cursor or not
|
bool _fDeferCursorRedraw; // whether we should defer redrawing the cursor or not
|
||||||
bool _fHaveDeferredCursorRedraw; // have we been asked to redraw the cursor while it was being deferred?
|
bool _fHaveDeferredCursorRedraw; // have we been asked to redraw the cursor while it was being deferred?
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ Abstract:
|
|||||||
#include <intsafe.h>
|
#include <intsafe.h>
|
||||||
|
|
||||||
// private dependencies
|
// private dependencies
|
||||||
#include "../inc/operators.hpp"
|
|
||||||
#include "../inc/unicode.hpp"
|
#include "../inc/unicode.hpp"
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ Search::Search(IUiaData& uiaData,
|
|||||||
const std::wstring& str,
|
const std::wstring& str,
|
||||||
const Direction direction,
|
const Direction direction,
|
||||||
const Sensitivity sensitivity,
|
const Sensitivity sensitivity,
|
||||||
const COORD anchor) :
|
const til::point anchor) :
|
||||||
_direction(direction),
|
_direction(direction),
|
||||||
_sensitivity(sensitivity),
|
_sensitivity(sensitivity),
|
||||||
_needle(s_CreateNeedleFromString(str)),
|
_needle(s_CreateNeedleFromString(str)),
|
||||||
@@ -124,7 +124,7 @@ void Search::Color(const TextAttribute attr) const
|
|||||||
// been called and returned true.
|
// been called and returned true.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - pair containing [start, end] coord positions of text found by search
|
// - pair containing [start, end] coord positions of text found by search
|
||||||
std::pair<COORD, COORD> Search::GetFoundLocation() const noexcept
|
std::pair<til::point, til::point> Search::GetFoundLocation() const noexcept
|
||||||
{
|
{
|
||||||
return { _coordSelStart, _coordSelEnd };
|
return { _coordSelStart, _coordSelEnd };
|
||||||
}
|
}
|
||||||
@@ -140,7 +140,7 @@ std::pair<COORD, COORD> Search::GetFoundLocation() const noexcept
|
|||||||
// - direction - The intended direction of the search
|
// - direction - The intended direction of the search
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - Coordinate to start the search from.
|
// - Coordinate to start the search from.
|
||||||
COORD Search::s_GetInitialAnchor(const IUiaData& uiaData, const Direction direction)
|
til::point Search::s_GetInitialAnchor(const IUiaData& uiaData, const Direction direction)
|
||||||
{
|
{
|
||||||
const auto& textBuffer = uiaData.GetTextBuffer();
|
const auto& textBuffer = uiaData.GetTextBuffer();
|
||||||
const auto textBufferEndPosition = uiaData.GetTextBufferEndPosition();
|
const auto textBufferEndPosition = uiaData.GetTextBufferEndPosition();
|
||||||
@@ -187,10 +187,10 @@ COORD Search::s_GetInitialAnchor(const IUiaData& uiaData, const Direction direct
|
|||||||
// - end - If we found it, this is filled with the coordinate of the last character of the needle.
|
// - end - If we found it, this is filled with the coordinate of the last character of the needle.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - True if we found it. False if not.
|
// - True if we found it. False if not.
|
||||||
bool Search::_FindNeedleInHaystackAt(const COORD pos, COORD& start, COORD& end) const
|
bool Search::_FindNeedleInHaystackAt(const til::point pos, til::point& start, til::point& end) const
|
||||||
{
|
{
|
||||||
start = { 0 };
|
start = {};
|
||||||
end = { 0 };
|
end = {};
|
||||||
|
|
||||||
auto bufferPos = pos;
|
auto bufferPos = pos;
|
||||||
|
|
||||||
@@ -269,7 +269,7 @@ wchar_t Search::_ApplySensitivity(const wchar_t wch) const noexcept
|
|||||||
// - Helper to increment a coordinate in respect to the associated screen buffer
|
// - Helper to increment a coordinate in respect to the associated screen buffer
|
||||||
// Arguments
|
// Arguments
|
||||||
// - coord - Updated by function to increment one position (will wrap X and Y direction)
|
// - coord - Updated by function to increment one position (will wrap X and Y direction)
|
||||||
void Search::_IncrementCoord(COORD& coord) const noexcept
|
void Search::_IncrementCoord(til::point& coord) const noexcept
|
||||||
{
|
{
|
||||||
_uiaData.GetTextBuffer().GetSize().IncrementInBoundsCircular(coord);
|
_uiaData.GetTextBuffer().GetSize().IncrementInBoundsCircular(coord);
|
||||||
}
|
}
|
||||||
@@ -278,7 +278,7 @@ void Search::_IncrementCoord(COORD& coord) const noexcept
|
|||||||
// - Helper to decrement a coordinate in respect to the associated screen buffer
|
// - Helper to decrement a coordinate in respect to the associated screen buffer
|
||||||
// Arguments
|
// Arguments
|
||||||
// - coord - Updated by function to decrement one position (will wrap X and Y direction)
|
// - coord - Updated by function to decrement one position (will wrap X and Y direction)
|
||||||
void Search::_DecrementCoord(COORD& coord) const noexcept
|
void Search::_DecrementCoord(til::point& coord) const noexcept
|
||||||
{
|
{
|
||||||
_uiaData.GetTextBuffer().GetSize().DecrementInBoundsCircular(coord);
|
_uiaData.GetTextBuffer().GetSize().DecrementInBoundsCircular(coord);
|
||||||
}
|
}
|
||||||
@@ -314,7 +314,7 @@ void Search::_UpdateNextPosition()
|
|||||||
{
|
{
|
||||||
if (_direction == Direction::Forward)
|
if (_direction == Direction::Forward)
|
||||||
{
|
{
|
||||||
_coordNext = { 0 };
|
_coordNext = {};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -49,33 +49,33 @@ public:
|
|||||||
const std::wstring& str,
|
const std::wstring& str,
|
||||||
const Direction dir,
|
const Direction dir,
|
||||||
const Sensitivity sensitivity,
|
const Sensitivity sensitivity,
|
||||||
const COORD anchor);
|
const til::point anchor);
|
||||||
|
|
||||||
bool FindNext();
|
bool FindNext();
|
||||||
void Select() const;
|
void Select() const;
|
||||||
void Color(const TextAttribute attr) const;
|
void Color(const TextAttribute attr) const;
|
||||||
|
|
||||||
std::pair<COORD, COORD> GetFoundLocation() const noexcept;
|
std::pair<til::point, til::point> GetFoundLocation() const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
wchar_t _ApplySensitivity(const wchar_t wch) const noexcept;
|
wchar_t _ApplySensitivity(const wchar_t wch) const noexcept;
|
||||||
bool _FindNeedleInHaystackAt(const COORD pos, COORD& start, COORD& end) const;
|
bool _FindNeedleInHaystackAt(const til::point pos, til::point& start, til::point& end) const;
|
||||||
bool _CompareChars(const std::wstring_view one, const std::wstring_view two) const noexcept;
|
bool _CompareChars(const std::wstring_view one, const std::wstring_view two) const noexcept;
|
||||||
void _UpdateNextPosition();
|
void _UpdateNextPosition();
|
||||||
|
|
||||||
void _IncrementCoord(COORD& coord) const noexcept;
|
void _IncrementCoord(til::point& coord) const noexcept;
|
||||||
void _DecrementCoord(COORD& coord) const noexcept;
|
void _DecrementCoord(til::point& coord) const noexcept;
|
||||||
|
|
||||||
static COORD s_GetInitialAnchor(const Microsoft::Console::Types::IUiaData& uiaData, const Direction dir);
|
static til::point s_GetInitialAnchor(const Microsoft::Console::Types::IUiaData& uiaData, const Direction dir);
|
||||||
|
|
||||||
static std::vector<std::vector<wchar_t>> s_CreateNeedleFromString(const std::wstring& wstr);
|
static std::vector<std::vector<wchar_t>> s_CreateNeedleFromString(const std::wstring& wstr);
|
||||||
|
|
||||||
bool _reachedEnd = false;
|
bool _reachedEnd = false;
|
||||||
COORD _coordNext = { 0 };
|
til::point _coordNext;
|
||||||
COORD _coordSelStart = { 0 };
|
til::point _coordSelStart;
|
||||||
COORD _coordSelEnd = { 0 };
|
til::point _coordSelEnd;
|
||||||
|
|
||||||
const COORD _coordAnchor;
|
const til::point _coordAnchor;
|
||||||
const std::vector<std::vector<wchar_t>> _needle;
|
const std::vector<std::vector<wchar_t>> _needle;
|
||||||
const Direction _direction;
|
const Direction _direction;
|
||||||
const Sensitivity _sensitivity;
|
const Sensitivity _sensitivity;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ using PointTree = interval_tree::IntervalTree<til::point, size_t>;
|
|||||||
// Return Value:
|
// Return Value:
|
||||||
// - constructed object
|
// - constructed object
|
||||||
// Note: may throw exception
|
// Note: may throw exception
|
||||||
TextBuffer::TextBuffer(const COORD screenBufferSize,
|
TextBuffer::TextBuffer(const til::size screenBufferSize,
|
||||||
const TextAttribute defaultAttributes,
|
const TextAttribute defaultAttributes,
|
||||||
const UINT cursorSize,
|
const UINT cursorSize,
|
||||||
const bool isActiveBuffer,
|
const bool isActiveBuffer,
|
||||||
@@ -47,10 +47,10 @@ TextBuffer::TextBuffer(const COORD screenBufferSize,
|
|||||||
_currentPatternId{ 0 }
|
_currentPatternId{ 0 }
|
||||||
{
|
{
|
||||||
// initialize ROWs
|
// initialize ROWs
|
||||||
_storage.reserve(static_cast<size_t>(screenBufferSize.Y));
|
_storage.reserve(gsl::narrow<size_t>(screenBufferSize.Y));
|
||||||
for (size_t i = 0; i < static_cast<size_t>(screenBufferSize.Y); ++i)
|
for (til::CoordType i = 0; i < screenBufferSize.Y; ++i)
|
||||||
{
|
{
|
||||||
_storage.emplace_back(static_cast<SHORT>(i), screenBufferSize.X, _currentAttributes, this);
|
_storage.emplace_back(i, screenBufferSize.X, _currentAttributes, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
_UpdateSize();
|
_UpdateSize();
|
||||||
@@ -74,9 +74,9 @@ void TextBuffer::CopyProperties(const TextBuffer& OtherBuffer) noexcept
|
|||||||
// - <none>
|
// - <none>
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - Total number of rows in the buffer
|
// - Total number of rows in the buffer
|
||||||
UINT TextBuffer::TotalRowCount() const noexcept
|
til::CoordType TextBuffer::TotalRowCount() const noexcept
|
||||||
{
|
{
|
||||||
return gsl::narrow<UINT>(_storage.size());
|
return gsl::narrow_cast<til::CoordType>(_storage.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routine Description:
|
// Routine Description:
|
||||||
@@ -86,13 +86,11 @@ UINT TextBuffer::TotalRowCount() const noexcept
|
|||||||
// - Number of rows down from the first row of the buffer.
|
// - Number of rows down from the first row of the buffer.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - const reference to the requested row. Asserts if out of bounds.
|
// - const reference to the requested row. Asserts if out of bounds.
|
||||||
const ROW& TextBuffer::GetRowByOffset(const size_t index) const
|
const ROW& TextBuffer::GetRowByOffset(const til::CoordType index) const noexcept
|
||||||
{
|
{
|
||||||
const size_t totalRows = TotalRowCount();
|
|
||||||
|
|
||||||
// Rows are stored circularly, so the index you ask for is offset by the start position and mod the total of rows.
|
// Rows are stored circularly, so the index you ask for is offset by the start position and mod the total of rows.
|
||||||
const auto offsetIndex = (_firstRow + index) % totalRows;
|
const auto offsetIndex = gsl::narrow_cast<size_t>(_firstRow + index) % _storage.size();
|
||||||
return _storage.at(offsetIndex);
|
return til::at(_storage, offsetIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routine Description:
|
// Routine Description:
|
||||||
@@ -102,13 +100,11 @@ const ROW& TextBuffer::GetRowByOffset(const size_t index) const
|
|||||||
// - Number of rows down from the first row of the buffer.
|
// - Number of rows down from the first row of the buffer.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - reference to the requested row. Asserts if out of bounds.
|
// - reference to the requested row. Asserts if out of bounds.
|
||||||
ROW& TextBuffer::GetRowByOffset(const size_t index)
|
ROW& TextBuffer::GetRowByOffset(const til::CoordType index) noexcept
|
||||||
{
|
{
|
||||||
const size_t totalRows = TotalRowCount();
|
|
||||||
|
|
||||||
// Rows are stored circularly, so the index you ask for is offset by the start position and mod the total of rows.
|
// Rows are stored circularly, so the index you ask for is offset by the start position and mod the total of rows.
|
||||||
const auto offsetIndex = (_firstRow + index) % totalRows;
|
const auto offsetIndex = gsl::narrow_cast<size_t>(_firstRow + index) % _storage.size();
|
||||||
return _storage.at(offsetIndex);
|
return til::at(_storage, offsetIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routine Description:
|
// Routine Description:
|
||||||
@@ -117,7 +113,7 @@ ROW& TextBuffer::GetRowByOffset(const size_t index)
|
|||||||
// - at - X,Y position in buffer for iterator start position
|
// - at - X,Y position in buffer for iterator start position
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - Read-only iterator of text data only.
|
// - Read-only iterator of text data only.
|
||||||
TextBufferTextIterator TextBuffer::GetTextDataAt(const COORD at) const
|
TextBufferTextIterator TextBuffer::GetTextDataAt(const til::point at) const
|
||||||
{
|
{
|
||||||
return TextBufferTextIterator(GetCellDataAt(at));
|
return TextBufferTextIterator(GetCellDataAt(at));
|
||||||
}
|
}
|
||||||
@@ -128,7 +124,7 @@ TextBufferTextIterator TextBuffer::GetTextDataAt(const COORD at) const
|
|||||||
// - at - X,Y position in buffer for iterator start position
|
// - at - X,Y position in buffer for iterator start position
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - Read-only iterator of cell data.
|
// - Read-only iterator of cell data.
|
||||||
TextBufferCellIterator TextBuffer::GetCellDataAt(const COORD at) const
|
TextBufferCellIterator TextBuffer::GetCellDataAt(const til::point at) const
|
||||||
{
|
{
|
||||||
return TextBufferCellIterator(*this, at);
|
return TextBufferCellIterator(*this, at);
|
||||||
}
|
}
|
||||||
@@ -140,7 +136,7 @@ TextBufferCellIterator TextBuffer::GetCellDataAt(const COORD at) const
|
|||||||
// - at - X,Y position in buffer for iterator start position
|
// - at - X,Y position in buffer for iterator start position
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - Read-only iterator of text data only.
|
// - Read-only iterator of text data only.
|
||||||
TextBufferTextIterator TextBuffer::GetTextLineDataAt(const COORD at) const
|
TextBufferTextIterator TextBuffer::GetTextLineDataAt(const til::point at) const
|
||||||
{
|
{
|
||||||
return TextBufferTextIterator(GetCellLineDataAt(at));
|
return TextBufferTextIterator(GetCellLineDataAt(at));
|
||||||
}
|
}
|
||||||
@@ -152,9 +148,9 @@ TextBufferTextIterator TextBuffer::GetTextLineDataAt(const COORD at) const
|
|||||||
// - at - X,Y position in buffer for iterator start position
|
// - at - X,Y position in buffer for iterator start position
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - Read-only iterator of cell data.
|
// - Read-only iterator of cell data.
|
||||||
TextBufferCellIterator TextBuffer::GetCellLineDataAt(const COORD at) const
|
TextBufferCellIterator TextBuffer::GetCellLineDataAt(const til::point at) const
|
||||||
{
|
{
|
||||||
SMALL_RECT limit;
|
til::inclusive_rect limit;
|
||||||
limit.Top = at.Y;
|
limit.Top = at.Y;
|
||||||
limit.Bottom = at.Y;
|
limit.Bottom = at.Y;
|
||||||
limit.Left = 0;
|
limit.Left = 0;
|
||||||
@@ -171,7 +167,7 @@ TextBufferCellIterator TextBuffer::GetCellLineDataAt(const COORD at) const
|
|||||||
// - limit - boundaries for the iterator to operate within
|
// - limit - boundaries for the iterator to operate within
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - Read-only iterator of text data only.
|
// - Read-only iterator of text data only.
|
||||||
TextBufferTextIterator TextBuffer::GetTextDataAt(const COORD at, const Viewport limit) const
|
TextBufferTextIterator TextBuffer::GetTextDataAt(const til::point at, const Viewport limit) const
|
||||||
{
|
{
|
||||||
return TextBufferTextIterator(GetCellDataAt(at, limit));
|
return TextBufferTextIterator(GetCellDataAt(at, limit));
|
||||||
}
|
}
|
||||||
@@ -184,7 +180,7 @@ TextBufferTextIterator TextBuffer::GetTextDataAt(const COORD at, const Viewport
|
|||||||
// - limit - boundaries for the iterator to operate within
|
// - limit - boundaries for the iterator to operate within
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - Read-only iterator of cell data.
|
// - Read-only iterator of cell data.
|
||||||
TextBufferCellIterator TextBuffer::GetCellDataAt(const COORD at, const Viewport limit) const
|
TextBufferCellIterator TextBuffer::GetCellDataAt(const til::point at, const Viewport limit) const
|
||||||
{
|
{
|
||||||
return TextBufferCellIterator(*this, at, limit);
|
return TextBufferCellIterator(*this, at, limit);
|
||||||
}
|
}
|
||||||
@@ -337,7 +333,7 @@ OutputCellIterator TextBuffer::Write(const OutputCellIterator givenIt)
|
|||||||
// Return Value:
|
// Return Value:
|
||||||
// - The final position of the iterator
|
// - The final position of the iterator
|
||||||
OutputCellIterator TextBuffer::Write(const OutputCellIterator givenIt,
|
OutputCellIterator TextBuffer::Write(const OutputCellIterator givenIt,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
const std::optional<bool> wrap)
|
const std::optional<bool> wrap)
|
||||||
{
|
{
|
||||||
// Make mutable copy so we can walk.
|
// Make mutable copy so we can walk.
|
||||||
@@ -374,9 +370,9 @@ OutputCellIterator TextBuffer::Write(const OutputCellIterator givenIt,
|
|||||||
// Return Value:
|
// Return Value:
|
||||||
// - The iterator, but advanced to where we stopped writing. Use to find input consumed length or cells written length.
|
// - The iterator, but advanced to where we stopped writing. Use to find input consumed length or cells written length.
|
||||||
OutputCellIterator TextBuffer::WriteLine(const OutputCellIterator givenIt,
|
OutputCellIterator TextBuffer::WriteLine(const OutputCellIterator givenIt,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
const std::optional<bool> wrap,
|
const std::optional<bool> wrap,
|
||||||
std::optional<size_t> limitRight)
|
std::optional<til::CoordType> limitRight)
|
||||||
{
|
{
|
||||||
// If we're not in bounds, exit early.
|
// If we're not in bounds, exit early.
|
||||||
if (!GetSize().IsInBounds(target))
|
if (!GetSize().IsInBounds(target))
|
||||||
@@ -390,7 +386,7 @@ OutputCellIterator TextBuffer::WriteLine(const OutputCellIterator givenIt,
|
|||||||
|
|
||||||
// Take the cell distance written and notify that it needs to be repainted.
|
// Take the cell distance written and notify that it needs to be repainted.
|
||||||
const auto written = newIt.GetCellDistance(givenIt);
|
const auto written = newIt.GetCellDistance(givenIt);
|
||||||
const auto paint = Viewport::FromDimensions(target, { gsl::narrow<SHORT>(written), 1 });
|
const auto paint = Viewport::FromDimensions(target, { written, 1 });
|
||||||
TriggerRedraw(paint);
|
TriggerRedraw(paint);
|
||||||
|
|
||||||
return newIt;
|
return newIt;
|
||||||
@@ -467,7 +463,7 @@ bool TextBuffer::InsertCharacter(const wchar_t wch, const DbcsAttribute dbcsAttr
|
|||||||
// - <none> - Always sets to wrap
|
// - <none> - Always sets to wrap
|
||||||
//Return Value:
|
//Return Value:
|
||||||
// - <none>
|
// - <none>
|
||||||
void TextBuffer::_SetWrapOnCurrentRow()
|
void TextBuffer::_SetWrapOnCurrentRow() noexcept
|
||||||
{
|
{
|
||||||
_AdjustWrapOnCurrentRow(true);
|
_AdjustWrapOnCurrentRow(true);
|
||||||
}
|
}
|
||||||
@@ -479,10 +475,10 @@ void TextBuffer::_SetWrapOnCurrentRow()
|
|||||||
// - fSet - True if this row has a wrap. False otherwise.
|
// - fSet - True if this row has a wrap. False otherwise.
|
||||||
//Return Value:
|
//Return Value:
|
||||||
// - <none>
|
// - <none>
|
||||||
void TextBuffer::_AdjustWrapOnCurrentRow(const bool fSet)
|
void TextBuffer::_AdjustWrapOnCurrentRow(const bool fSet) noexcept
|
||||||
{
|
{
|
||||||
// The vertical position of the cursor represents the current row we're manipulating.
|
// The vertical position of the cursor represents the current row we're manipulating.
|
||||||
const UINT uiCurrentRowOffset = GetCursor().GetPosition().Y;
|
const auto uiCurrentRowOffset = GetCursor().GetPosition().Y;
|
||||||
|
|
||||||
// Set the wrap status as appropriate
|
// Set the wrap status as appropriate
|
||||||
GetRowByOffset(uiCurrentRowOffset).SetWrapForced(fSet);
|
GetRowByOffset(uiCurrentRowOffset).SetWrapForced(fSet);
|
||||||
@@ -501,7 +497,7 @@ bool TextBuffer::IncrementCursor()
|
|||||||
// Cursor position is stored as logical array indices (starts at 0) for the window
|
// Cursor position is stored as logical array indices (starts at 0) for the window
|
||||||
// Buffer Size is specified as the "length" of the array. It would say 80 for valid values of 0-79.
|
// Buffer Size is specified as the "length" of the array. It would say 80 for valid values of 0-79.
|
||||||
// So subtract 1 from buffer size in each direction to find the index of the final column in the buffer
|
// So subtract 1 from buffer size in each direction to find the index of the final column in the buffer
|
||||||
const short iFinalColumnIndex = GetLineWidth(GetCursor().GetPosition().Y) - 1;
|
const auto iFinalColumnIndex = GetLineWidth(GetCursor().GetPosition().Y) - 1;
|
||||||
|
|
||||||
// Move the cursor one position to the right
|
// Move the cursor one position to the right
|
||||||
GetCursor().IncrementXPosition(1);
|
GetCursor().IncrementXPosition(1);
|
||||||
@@ -604,17 +600,17 @@ bool TextBuffer::IncrementCircularBuffer(const bool inVtMode)
|
|||||||
// - The viewport
|
// - The viewport
|
||||||
//Return value:
|
//Return value:
|
||||||
// - Coordinate position (relative to the text buffer)
|
// - Coordinate position (relative to the text buffer)
|
||||||
COORD TextBuffer::GetLastNonSpaceCharacter(std::optional<const Microsoft::Console::Types::Viewport> viewOptional) const
|
til::point TextBuffer::GetLastNonSpaceCharacter(std::optional<const Microsoft::Console::Types::Viewport> viewOptional) const
|
||||||
{
|
{
|
||||||
const auto viewport = viewOptional.has_value() ? viewOptional.value() : GetSize();
|
const auto viewport = viewOptional.has_value() ? viewOptional.value() : GetSize();
|
||||||
|
|
||||||
COORD coordEndOfText = { 0 };
|
til::point coordEndOfText;
|
||||||
// Search the given viewport by starting at the bottom.
|
// Search the given viewport by starting at the bottom.
|
||||||
coordEndOfText.Y = viewport.BottomInclusive();
|
coordEndOfText.Y = viewport.BottomInclusive();
|
||||||
|
|
||||||
const auto& currRow = GetRowByOffset(coordEndOfText.Y);
|
const auto& currRow = GetRowByOffset(coordEndOfText.Y);
|
||||||
// The X position of the end of the valid text is the Right draw boundary (which is one beyond the final valid character)
|
// The X position of the end of the valid text is the Right draw boundary (which is one beyond the final valid character)
|
||||||
coordEndOfText.X = gsl::narrow<short>(currRow.GetCharRow().MeasureRight()) - 1;
|
coordEndOfText.X = currRow.GetCharRow().MeasureRight() - 1;
|
||||||
|
|
||||||
// If the X coordinate turns out to be -1, the row was empty, we need to search backwards for the real end of text.
|
// If the X coordinate turns out to be -1, the row was empty, we need to search backwards for the real end of text.
|
||||||
const auto viewportTop = viewport.Top();
|
const auto viewportTop = viewport.Top();
|
||||||
@@ -625,13 +621,13 @@ COORD TextBuffer::GetLastNonSpaceCharacter(std::optional<const Microsoft::Consol
|
|||||||
const auto& backupRow = GetRowByOffset(coordEndOfText.Y);
|
const auto& backupRow = GetRowByOffset(coordEndOfText.Y);
|
||||||
// We need to back up to the previous row if this line is empty, AND there are more rows
|
// We need to back up to the previous row if this line is empty, AND there are more rows
|
||||||
|
|
||||||
coordEndOfText.X = gsl::narrow<short>(backupRow.GetCharRow().MeasureRight()) - 1;
|
coordEndOfText.X = backupRow.GetCharRow().MeasureRight() - 1;
|
||||||
fDoBackUp = (coordEndOfText.X < 0 && coordEndOfText.Y > viewportTop);
|
fDoBackUp = (coordEndOfText.X < 0 && coordEndOfText.Y > viewportTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't allow negative results
|
// don't allow negative results
|
||||||
coordEndOfText.Y = std::max(coordEndOfText.Y, 0i16);
|
coordEndOfText.Y = std::max(coordEndOfText.Y, 0);
|
||||||
coordEndOfText.X = std::max(coordEndOfText.X, 0i16);
|
coordEndOfText.X = std::max(coordEndOfText.X, 0);
|
||||||
|
|
||||||
return coordEndOfText;
|
return coordEndOfText;
|
||||||
}
|
}
|
||||||
@@ -643,7 +639,7 @@ COORD TextBuffer::GetLastNonSpaceCharacter(std::optional<const Microsoft::Consol
|
|||||||
// Return Value:
|
// Return Value:
|
||||||
// - Coordinate position in screen coordinates of the character just before the cursor.
|
// - Coordinate position in screen coordinates of the character just before the cursor.
|
||||||
// - NOTE: Will return 0,0 if already in the top left corner
|
// - NOTE: Will return 0,0 if already in the top left corner
|
||||||
COORD TextBuffer::_GetPreviousFromCursor() const
|
til::point TextBuffer::_GetPreviousFromCursor() const noexcept
|
||||||
{
|
{
|
||||||
auto coordPosition = GetCursor().GetPosition();
|
auto coordPosition = GetCursor().GetPosition();
|
||||||
|
|
||||||
@@ -668,7 +664,7 @@ COORD TextBuffer::_GetPreviousFromCursor() const
|
|||||||
return coordPosition;
|
return coordPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHORT TextBuffer::GetFirstRowIndex() const noexcept
|
const til::CoordType TextBuffer::GetFirstRowIndex() const noexcept
|
||||||
{
|
{
|
||||||
return _firstRow;
|
return _firstRow;
|
||||||
}
|
}
|
||||||
@@ -680,15 +676,15 @@ const Viewport TextBuffer::GetSize() const noexcept
|
|||||||
|
|
||||||
void TextBuffer::_UpdateSize()
|
void TextBuffer::_UpdateSize()
|
||||||
{
|
{
|
||||||
_size = Viewport::FromDimensions({ 0, 0 }, { gsl::narrow<SHORT>(_storage.at(0).size()), gsl::narrow<SHORT>(_storage.size()) });
|
_size = Viewport::FromDimensions({ _storage.at(0).size(), gsl::narrow<til::CoordType>(_storage.size()) });
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBuffer::_SetFirstRowIndex(const SHORT FirstRowIndex) noexcept
|
void TextBuffer::_SetFirstRowIndex(const til::CoordType FirstRowIndex) noexcept
|
||||||
{
|
{
|
||||||
_firstRow = FirstRowIndex;
|
_firstRow = FirstRowIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBuffer::ScrollRows(const SHORT firstRow, const SHORT size, const SHORT delta)
|
void TextBuffer::ScrollRows(const til::CoordType firstRow, const til::CoordType size, const til::CoordType delta)
|
||||||
{
|
{
|
||||||
// If we don't have to move anything, leave early.
|
// If we don't have to move anything, leave early.
|
||||||
if (delta == 0)
|
if (delta == 0)
|
||||||
@@ -825,9 +821,9 @@ void TextBuffer::SetCurrentLineRendition(const LineRendition lineRendition)
|
|||||||
const auto fillChar = L' ';
|
const auto fillChar = L' ';
|
||||||
auto fillAttrs = GetCurrentAttributes();
|
auto fillAttrs = GetCurrentAttributes();
|
||||||
fillAttrs.SetStandardErase();
|
fillAttrs.SetStandardErase();
|
||||||
const size_t fillOffset = GetLineWidth(rowIndex);
|
const auto fillOffset = GetLineWidth(rowIndex);
|
||||||
const auto fillLength = GetSize().Width() - fillOffset;
|
const auto fillLength = gsl::narrow<size_t>(GetSize().Width() - fillOffset);
|
||||||
const auto fillData = OutputCellIterator{ fillChar, fillAttrs, fillLength };
|
const OutputCellIterator fillData{ fillChar, fillAttrs, fillLength };
|
||||||
row.WriteCells(fillData, fillOffset, false);
|
row.WriteCells(fillData, fillOffset, false);
|
||||||
// We also need to make sure the cursor is clamped within the new width.
|
// We also need to make sure the cursor is clamped within the new width.
|
||||||
GetCursor().SetPosition(ClampPositionWithinLine(cursorPosition));
|
GetCursor().SetPosition(ClampPositionWithinLine(cursorPosition));
|
||||||
@@ -836,7 +832,7 @@ void TextBuffer::SetCurrentLineRendition(const LineRendition lineRendition)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBuffer::ResetLineRenditionRange(const size_t startRow, const size_t endRow)
|
void TextBuffer::ResetLineRenditionRange(const til::CoordType startRow, const til::CoordType endRow) noexcept
|
||||||
{
|
{
|
||||||
for (auto row = startRow; row < endRow; row++)
|
for (auto row = startRow; row < endRow; row++)
|
||||||
{
|
{
|
||||||
@@ -844,40 +840,40 @@ void TextBuffer::ResetLineRenditionRange(const size_t startRow, const size_t end
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LineRendition TextBuffer::GetLineRendition(const size_t row) const
|
LineRendition TextBuffer::GetLineRendition(const til::CoordType row) const noexcept
|
||||||
{
|
{
|
||||||
return GetRowByOffset(row).GetLineRendition();
|
return GetRowByOffset(row).GetLineRendition();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextBuffer::IsDoubleWidthLine(const size_t row) const
|
bool TextBuffer::IsDoubleWidthLine(const til::CoordType row) const noexcept
|
||||||
{
|
{
|
||||||
return GetLineRendition(row) != LineRendition::SingleWidth;
|
return GetLineRendition(row) != LineRendition::SingleWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHORT TextBuffer::GetLineWidth(const size_t row) const
|
til::CoordType TextBuffer::GetLineWidth(const til::CoordType row) const noexcept
|
||||||
{
|
{
|
||||||
// Use shift right to quickly divide the width by 2 for double width lines.
|
// Use shift right to quickly divide the width by 2 for double width lines.
|
||||||
const SHORT scale = IsDoubleWidthLine(row) ? 1 : 0;
|
const auto scale = IsDoubleWidthLine(row) ? 1 : 0;
|
||||||
return GetSize().Width() >> scale;
|
return GetSize().Width() >> scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
COORD TextBuffer::ClampPositionWithinLine(const COORD position) const
|
til::point TextBuffer::ClampPositionWithinLine(const til::point position) const noexcept
|
||||||
{
|
{
|
||||||
const SHORT rightmostColumn = GetLineWidth(position.Y) - 1;
|
const auto rightmostColumn = GetLineWidth(position.Y) - 1;
|
||||||
return { std::min(position.X, rightmostColumn), position.Y };
|
return { std::min(position.X, rightmostColumn), position.Y };
|
||||||
}
|
}
|
||||||
|
|
||||||
COORD TextBuffer::ScreenToBufferPosition(const COORD position) const
|
til::point TextBuffer::ScreenToBufferPosition(const til::point position) const noexcept
|
||||||
{
|
{
|
||||||
// Use shift right to quickly divide the X pos by 2 for double width lines.
|
// Use shift right to quickly divide the X pos by 2 for double width lines.
|
||||||
const SHORT scale = IsDoubleWidthLine(position.Y) ? 1 : 0;
|
const auto scale = IsDoubleWidthLine(position.Y) ? 1 : 0;
|
||||||
return { position.X >> scale, position.Y };
|
return { position.X >> scale, position.Y };
|
||||||
}
|
}
|
||||||
|
|
||||||
COORD TextBuffer::BufferToScreenPosition(const COORD position) const
|
til::point TextBuffer::BufferToScreenPosition(const til::point position) const noexcept
|
||||||
{
|
{
|
||||||
// Use shift left to quickly multiply the X pos by 2 for double width lines.
|
// Use shift left to quickly multiply the X pos by 2 for double width lines.
|
||||||
const SHORT scale = IsDoubleWidthLine(position.Y) ? 1 : 0;
|
const auto scale = IsDoubleWidthLine(position.Y) ? 1 : 0;
|
||||||
return { position.X << scale, position.Y };
|
return { position.X << scale, position.Y };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -900,7 +896,7 @@ void TextBuffer::Reset()
|
|||||||
// - newSize - new size of screen.
|
// - newSize - new size of screen.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - Success if successful. Invalid parameter if screen buffer size is unexpected. No memory if allocation failed.
|
// - Success if successful. Invalid parameter if screen buffer size is unexpected. No memory if allocation failed.
|
||||||
[[nodiscard]] NTSTATUS TextBuffer::ResizeTraditional(const COORD newSize) noexcept
|
[[nodiscard]] NTSTATUS TextBuffer::ResizeTraditional(const til::size newSize) noexcept
|
||||||
{
|
{
|
||||||
RETURN_HR_IF(E_INVALIDARG, newSize.X < 0 || newSize.Y < 0);
|
RETURN_HR_IF(E_INVALIDARG, newSize.X < 0 || newSize.Y < 0);
|
||||||
|
|
||||||
@@ -909,12 +905,12 @@ void TextBuffer::Reset()
|
|||||||
const auto currentSize = GetSize().Dimensions();
|
const auto currentSize = GetSize().Dimensions();
|
||||||
const auto attributes = GetCurrentAttributes();
|
const auto attributes = GetCurrentAttributes();
|
||||||
|
|
||||||
SHORT TopRow = 0; // new top row of the screen buffer
|
til::CoordType TopRow = 0; // new top row of the screen buffer
|
||||||
if (newSize.Y <= GetCursor().GetPosition().Y)
|
if (newSize.Y <= GetCursor().GetPosition().Y)
|
||||||
{
|
{
|
||||||
TopRow = GetCursor().GetPosition().Y - newSize.Y + 1;
|
TopRow = GetCursor().GetPosition().Y - newSize.Y + 1;
|
||||||
}
|
}
|
||||||
const SHORT TopRowIndex = (GetFirstRowIndex() + TopRow) % currentSize.Y;
|
const auto TopRowIndex = (GetFirstRowIndex() + TopRow) % currentSize.Y;
|
||||||
|
|
||||||
// rotate rows until the top row is at index 0
|
// rotate rows until the top row is at index 0
|
||||||
for (auto i = 0; i < TopRowIndex; i++)
|
for (auto i = 0; i < TopRowIndex; i++)
|
||||||
@@ -934,7 +930,7 @@ void TextBuffer::Reset()
|
|||||||
// add rows if we're growing
|
// add rows if we're growing
|
||||||
while (_storage.size() < static_cast<size_t>(newSize.Y))
|
while (_storage.size() < static_cast<size_t>(newSize.Y))
|
||||||
{
|
{
|
||||||
_storage.emplace_back(static_cast<short>(_storage.size()), newSize.X, attributes, this);
|
_storage.emplace_back(gsl::narrow_cast<til::CoordType>(_storage.size()), newSize.X, attributes, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now that we've tampered with the row placement, refresh all the row IDs.
|
// Now that we've tampered with the row placement, refresh all the row IDs.
|
||||||
@@ -983,7 +979,7 @@ void TextBuffer::TriggerRedraw(const Viewport& viewport)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBuffer::TriggerRedrawCursor(const COORD position)
|
void TextBuffer::TriggerRedrawCursor(const til::point position)
|
||||||
{
|
{
|
||||||
if (_isActiveBuffer)
|
if (_isActiveBuffer)
|
||||||
{
|
{
|
||||||
@@ -1007,7 +1003,7 @@ void TextBuffer::TriggerScroll()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextBuffer::TriggerScroll(const COORD delta)
|
void TextBuffer::TriggerScroll(const til::point delta)
|
||||||
{
|
{
|
||||||
if (_isActiveBuffer)
|
if (_isActiveBuffer)
|
||||||
{
|
{
|
||||||
@@ -1032,10 +1028,10 @@ void TextBuffer::TriggerNewTextNotification(const std::wstring_view newText)
|
|||||||
// any high unicode (UnicodeStorage) runs while we're already looping through the rows.
|
// any high unicode (UnicodeStorage) runs while we're already looping through the rows.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - newRowWidth - Optional new value for the row width.
|
// - newRowWidth - Optional new value for the row width.
|
||||||
void TextBuffer::_RefreshRowIDs(std::optional<SHORT> newRowWidth)
|
void TextBuffer::_RefreshRowIDs(std::optional<til::CoordType> newRowWidth)
|
||||||
{
|
{
|
||||||
std::unordered_map<SHORT, SHORT> rowMap;
|
std::unordered_map<til::CoordType, til::CoordType> rowMap;
|
||||||
SHORT i = 0;
|
til::CoordType i = 0;
|
||||||
for (auto& it : _storage)
|
for (auto& it : _storage)
|
||||||
{
|
{
|
||||||
// Build a map so we can update Unicode Storage
|
// Build a map so we can update Unicode Storage
|
||||||
@@ -1065,7 +1061,7 @@ void TextBuffer::_RefreshRowIDs(std::optional<SHORT> newRowWidth)
|
|||||||
// - <none>
|
// - <none>
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - reference to the first row.
|
// - reference to the first row.
|
||||||
ROW& TextBuffer::_GetFirstRow()
|
ROW& TextBuffer::_GetFirstRow() noexcept
|
||||||
{
|
{
|
||||||
return GetRowByOffset(0);
|
return GetRowByOffset(0);
|
||||||
}
|
}
|
||||||
@@ -1099,23 +1095,23 @@ ROW& TextBuffer::_GetPrevRowNoWrap(const ROW& Row)
|
|||||||
// - wordDelimiters: the delimiters defined as a part of the DelimiterClass::DelimiterChar
|
// - wordDelimiters: the delimiters defined as a part of the DelimiterClass::DelimiterChar
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - the delimiter class for the given char
|
// - the delimiter class for the given char
|
||||||
const DelimiterClass TextBuffer::_GetDelimiterClassAt(const COORD pos, const std::wstring_view wordDelimiters) const
|
DelimiterClass TextBuffer::_GetDelimiterClassAt(const til::point pos, const std::wstring_view wordDelimiters) const
|
||||||
{
|
{
|
||||||
return GetRowByOffset(pos.Y).GetCharRow().DelimiterClassAt(pos.X, wordDelimiters);
|
return GetRowByOffset(pos.Y).GetCharRow().DelimiterClassAt(pos.X, wordDelimiters);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Get the COORD for the beginning of the word you are on
|
// - Get the til::point for the beginning of the word you are on
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - target - a COORD on the word you are currently on
|
// - target - a til::point on the word you are currently on
|
||||||
// - wordDelimiters - what characters are we considering for the separation of words
|
// - wordDelimiters - what characters are we considering for the separation of words
|
||||||
// - accessibilityMode - when enabled, we continue expanding left until we are at the beginning of a readable word.
|
// - accessibilityMode - when enabled, we continue expanding left until we are at the beginning of a readable word.
|
||||||
// Otherwise, expand left until a character of a new delimiter class is found
|
// Otherwise, expand left until a character of a new delimiter class is found
|
||||||
// (or a row boundary is encountered)
|
// (or a row boundary is encountered)
|
||||||
// - limitOptional - (optional) the last possible position in the buffer that can be explored. This can be used to improve performance.
|
// - limitOptional - (optional) the last possible position in the buffer that can be explored. This can be used to improve performance.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The COORD for the first character on the "word" (inclusive)
|
// - The til::point for the first character on the "word" (inclusive)
|
||||||
const COORD TextBuffer::GetWordStart(const COORD target, const std::wstring_view wordDelimiters, bool accessibilityMode, std::optional<til::point> limitOptional) const
|
til::point TextBuffer::GetWordStart(const til::point target, const std::wstring_view wordDelimiters, bool accessibilityMode, std::optional<til::point> limitOptional) const
|
||||||
{
|
{
|
||||||
// Consider a buffer with this text in it:
|
// Consider a buffer with this text in it:
|
||||||
// " word other "
|
// " word other "
|
||||||
@@ -1130,7 +1126,7 @@ const COORD TextBuffer::GetWordStart(const COORD target, const std::wstring_view
|
|||||||
#pragma warning(suppress : 26496)
|
#pragma warning(suppress : 26496)
|
||||||
auto copy{ target };
|
auto copy{ target };
|
||||||
const auto bufferSize{ GetSize() };
|
const auto bufferSize{ GetSize() };
|
||||||
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
|
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
|
||||||
if (target == bufferSize.Origin())
|
if (target == bufferSize.Origin())
|
||||||
{
|
{
|
||||||
// can't expand left
|
// can't expand left
|
||||||
@@ -1140,12 +1136,12 @@ const COORD TextBuffer::GetWordStart(const COORD target, const std::wstring_view
|
|||||||
{
|
{
|
||||||
// GH#7664: Treat EndExclusive as EndInclusive so
|
// GH#7664: Treat EndExclusive as EndInclusive so
|
||||||
// that it actually points to a space in the buffer
|
// that it actually points to a space in the buffer
|
||||||
copy = { bufferSize.RightInclusive(), bufferSize.BottomInclusive() };
|
copy = bufferSize.BottomRightInclusive();
|
||||||
}
|
}
|
||||||
else if (bufferSize.CompareInBounds(target, limit.to_win32_coord(), true) >= 0)
|
else if (bufferSize.CompareInBounds(target, limit, true) >= 0)
|
||||||
{
|
{
|
||||||
// if at/past the limit --> clamp to limit
|
// if at/past the limit --> clamp to limit
|
||||||
copy = limitOptional->to_win32_coord();
|
copy = limitOptional.value_or(bufferSize.BottomRightInclusive());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (accessibilityMode)
|
if (accessibilityMode)
|
||||||
@@ -1159,13 +1155,13 @@ const COORD TextBuffer::GetWordStart(const COORD target, const std::wstring_view
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Helper method for GetWordStart(). Get the COORD for the beginning of the word (accessibility definition) you are on
|
// - Helper method for GetWordStart(). Get the til::point for the beginning of the word (accessibility definition) you are on
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - target - a COORD on the word you are currently on
|
// - target - a til::point on the word you are currently on
|
||||||
// - wordDelimiters - what characters are we considering for the separation of words
|
// - wordDelimiters - what characters are we considering for the separation of words
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The COORD for the first character on the current/previous READABLE "word" (inclusive)
|
// - The til::point for the first character on the current/previous READABLE "word" (inclusive)
|
||||||
const COORD TextBuffer::_GetWordStartForAccessibility(const COORD target, const std::wstring_view wordDelimiters) const
|
til::point TextBuffer::_GetWordStartForAccessibility(const til::point target, const std::wstring_view wordDelimiters) const
|
||||||
{
|
{
|
||||||
auto result = target;
|
auto result = target;
|
||||||
const auto bufferSize = GetSize();
|
const auto bufferSize = GetSize();
|
||||||
@@ -1204,13 +1200,13 @@ const COORD TextBuffer::_GetWordStartForAccessibility(const COORD target, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Helper method for GetWordStart(). Get the COORD for the beginning of the word (selection definition) you are on
|
// - Helper method for GetWordStart(). Get the til::point for the beginning of the word (selection definition) you are on
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - target - a COORD on the word you are currently on
|
// - target - a til::point on the word you are currently on
|
||||||
// - wordDelimiters - what characters are we considering for the separation of words
|
// - wordDelimiters - what characters are we considering for the separation of words
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The COORD for the first character on the current word or delimiter run (stopped by the left margin)
|
// - The til::point for the first character on the current word or delimiter run (stopped by the left margin)
|
||||||
const COORD TextBuffer::_GetWordStartForSelection(const COORD target, const std::wstring_view wordDelimiters) const
|
til::point TextBuffer::_GetWordStartForSelection(const til::point target, const std::wstring_view wordDelimiters) const
|
||||||
{
|
{
|
||||||
auto result = target;
|
auto result = target;
|
||||||
const auto bufferSize = GetSize();
|
const auto bufferSize = GetSize();
|
||||||
@@ -1233,17 +1229,17 @@ const COORD TextBuffer::_GetWordStartForSelection(const COORD target, const std:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Get the COORD for the beginning of the NEXT word
|
// - Get the til::point for the beginning of the NEXT word
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - target - a COORD on the word you are currently on
|
// - target - a til::point on the word you are currently on
|
||||||
// - wordDelimiters - what characters are we considering for the separation of words
|
// - wordDelimiters - what characters are we considering for the separation of words
|
||||||
// - accessibilityMode - when enabled, we continue expanding right until we are at the beginning of the next READABLE word
|
// - accessibilityMode - when enabled, we continue expanding right until we are at the beginning of the next READABLE word
|
||||||
// Otherwise, expand right until a character of a new delimiter class is found
|
// Otherwise, expand right until a character of a new delimiter class is found
|
||||||
// (or a row boundary is encountered)
|
// (or a row boundary is encountered)
|
||||||
// - limitOptional - (optional) the last possible position in the buffer that can be explored. This can be used to improve performance.
|
// - limitOptional - (optional) the last possible position in the buffer that can be explored. This can be used to improve performance.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The COORD for the last character on the "word" (inclusive)
|
// - The til::point for the last character on the "word" (inclusive)
|
||||||
const COORD TextBuffer::GetWordEnd(const COORD target, const std::wstring_view wordDelimiters, bool accessibilityMode, std::optional<til::point> limitOptional) const
|
til::point TextBuffer::GetWordEnd(const til::point target, const std::wstring_view wordDelimiters, bool accessibilityMode, std::optional<til::point> limitOptional) const
|
||||||
{
|
{
|
||||||
// Consider a buffer with this text in it:
|
// Consider a buffer with this text in it:
|
||||||
// " word other "
|
// " word other "
|
||||||
@@ -1257,15 +1253,15 @@ const COORD TextBuffer::GetWordEnd(const COORD target, const std::wstring_view w
|
|||||||
|
|
||||||
// Already at/past the limit. Can't move forward.
|
// Already at/past the limit. Can't move forward.
|
||||||
const auto bufferSize{ GetSize() };
|
const auto bufferSize{ GetSize() };
|
||||||
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
|
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
|
||||||
if (bufferSize.CompareInBounds(target, limit.to_win32_coord(), true) >= 0)
|
if (bufferSize.CompareInBounds(target, limit, true) >= 0)
|
||||||
{
|
{
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (accessibilityMode)
|
if (accessibilityMode)
|
||||||
{
|
{
|
||||||
return _GetWordEndForAccessibility(target, wordDelimiters, limit.to_win32_coord());
|
return _GetWordEndForAccessibility(target, wordDelimiters, limit);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1274,14 +1270,14 @@ const COORD TextBuffer::GetWordEnd(const COORD target, const std::wstring_view w
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Helper method for GetWordEnd(). Get the COORD for the beginning of the next READABLE word
|
// - Helper method for GetWordEnd(). Get the til::point for the beginning of the next READABLE word
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - target - a COORD on the word you are currently on
|
// - target - a til::point on the word you are currently on
|
||||||
// - wordDelimiters - what characters are we considering for the separation of words
|
// - wordDelimiters - what characters are we considering for the separation of words
|
||||||
// - limit - the last "valid" position in the text buffer (to improve performance)
|
// - limit - the last "valid" position in the text buffer (to improve performance)
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The COORD for the first character of the next readable "word". If no next word, return one past the end of the buffer
|
// - The til::point for the first character of the next readable "word". If no next word, return one past the end of the buffer
|
||||||
const COORD TextBuffer::_GetWordEndForAccessibility(const COORD target, const std::wstring_view wordDelimiters, const COORD limit) const
|
til::point TextBuffer::_GetWordEndForAccessibility(const til::point target, const std::wstring_view wordDelimiters, const til::point limit) const
|
||||||
{
|
{
|
||||||
const auto bufferSize{ GetSize() };
|
const auto bufferSize{ GetSize() };
|
||||||
auto result{ target };
|
auto result{ target };
|
||||||
@@ -1325,13 +1321,13 @@ const COORD TextBuffer::_GetWordEndForAccessibility(const COORD target, const st
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Helper method for GetWordEnd(). Get the COORD for the beginning of the NEXT word
|
// - Helper method for GetWordEnd(). Get the til::point for the beginning of the NEXT word
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - target - a COORD on the word you are currently on
|
// - target - a til::point on the word you are currently on
|
||||||
// - wordDelimiters - what characters are we considering for the separation of words
|
// - wordDelimiters - what characters are we considering for the separation of words
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The COORD for the last character of the current word or delimiter run (stopped by right margin)
|
// - The til::point for the last character of the current word or delimiter run (stopped by right margin)
|
||||||
const COORD TextBuffer::_GetWordEndForSelection(const COORD target, const std::wstring_view wordDelimiters) const
|
til::point TextBuffer::_GetWordEndForSelection(const til::point target, const std::wstring_view wordDelimiters) const
|
||||||
{
|
{
|
||||||
const auto bufferSize = GetSize();
|
const auto bufferSize = GetSize();
|
||||||
|
|
||||||
@@ -1380,7 +1376,7 @@ void TextBuffer::_PruneHyperlinks()
|
|||||||
// we have found all hyperlink references in the first row and put them in refs,
|
// we have found all hyperlink references in the first row and put them in refs,
|
||||||
// now we need to search the rest of the buffer (i.e. all the rows except the first)
|
// now we need to search the rest of the buffer (i.e. all the rows except the first)
|
||||||
// to see if those references are anywhere else
|
// to see if those references are anywhere else
|
||||||
for (size_t i = 1; i != total; ++i)
|
for (til::CoordType i = 1; i < total; ++i)
|
||||||
{
|
{
|
||||||
const auto nextRowRefs = GetRowByOffset(i).GetAttrRow().GetHyperlinks();
|
const auto nextRowRefs = GetRowByOffset(i).GetAttrRow().GetHyperlinks();
|
||||||
for (auto id : nextRowRefs)
|
for (auto id : nextRowRefs)
|
||||||
@@ -1408,22 +1404,22 @@ void TextBuffer::_PruneHyperlinks()
|
|||||||
// Method Description:
|
// Method Description:
|
||||||
// - Update pos to be the position of the first character of the next word. This is used for accessibility
|
// - Update pos to be the position of the first character of the next word. This is used for accessibility
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - pos - a COORD on the word you are currently on
|
// - pos - a til::point on the word you are currently on
|
||||||
// - wordDelimiters - what characters are we considering for the separation of words
|
// - wordDelimiters - what characters are we considering for the separation of words
|
||||||
// - limitOptional - (optional) the last possible position in the buffer that can be explored. This can be used to improve performance.
|
// - limitOptional - (optional) the last possible position in the buffer that can be explored. This can be used to improve performance.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
|
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
|
||||||
// - pos - The COORD for the first character on the "word" (inclusive)
|
// - pos - The til::point for the first character on the "word" (inclusive)
|
||||||
bool TextBuffer::MoveToNextWord(COORD& pos, const std::wstring_view wordDelimiters, std::optional<til::point> limitOptional) const
|
bool TextBuffer::MoveToNextWord(til::point& pos, const std::wstring_view wordDelimiters, std::optional<til::point> limitOptional) const
|
||||||
{
|
{
|
||||||
// move to the beginning of the next word
|
// move to the beginning of the next word
|
||||||
// NOTE: _GetWordEnd...() returns the exclusive position of the "end of the word"
|
// NOTE: _GetWordEnd...() returns the exclusive position of the "end of the word"
|
||||||
// This is also the inclusive start of the next word.
|
// This is also the inclusive start of the next word.
|
||||||
const auto bufferSize{ GetSize() };
|
const auto bufferSize{ GetSize() };
|
||||||
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
|
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
|
||||||
const auto copy{ _GetWordEndForAccessibility(pos, wordDelimiters, limit.to_win32_coord()) };
|
const auto copy{ _GetWordEndForAccessibility(pos, wordDelimiters, limit) };
|
||||||
|
|
||||||
if (bufferSize.CompareInBounds(copy, limit.to_win32_coord(), true) >= 0)
|
if (bufferSize.CompareInBounds(copy, limit, true) >= 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1435,12 +1431,12 @@ bool TextBuffer::MoveToNextWord(COORD& pos, const std::wstring_view wordDelimite
|
|||||||
// Method Description:
|
// Method Description:
|
||||||
// - Update pos to be the position of the first character of the previous word. This is used for accessibility
|
// - Update pos to be the position of the first character of the previous word. This is used for accessibility
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - pos - a COORD on the word you are currently on
|
// - pos - a til::point on the word you are currently on
|
||||||
// - wordDelimiters - what characters are we considering for the separation of words
|
// - wordDelimiters - what characters are we considering for the separation of words
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
|
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
|
||||||
// - pos - The COORD for the first character on the "word" (inclusive)
|
// - pos - The til::point for the first character on the "word" (inclusive)
|
||||||
bool TextBuffer::MoveToPreviousWord(COORD& pos, std::wstring_view wordDelimiters) const
|
bool TextBuffer::MoveToPreviousWord(til::point& pos, std::wstring_view wordDelimiters) const
|
||||||
{
|
{
|
||||||
// move to the beginning of the current word
|
// move to the beginning of the current word
|
||||||
auto copy{ GetWordStart(pos, wordDelimiters, true) };
|
auto copy{ GetWordStart(pos, wordDelimiters, true) };
|
||||||
@@ -1459,51 +1455,51 @@ bool TextBuffer::MoveToPreviousWord(COORD& pos, std::wstring_view wordDelimiters
|
|||||||
// Method Description:
|
// Method Description:
|
||||||
// - Update pos to be the beginning of the current glyph/character. This is used for accessibility
|
// - Update pos to be the beginning of the current glyph/character. This is used for accessibility
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - pos - a COORD on the word you are currently on
|
// - pos - a til::point on the word you are currently on
|
||||||
// - limitOptional - (optional) the last possible position in the buffer that can be explored. This can be used to improve performance.
|
// - limitOptional - (optional) the last possible position in the buffer that can be explored. This can be used to improve performance.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - pos - The COORD for the first cell of the current glyph (inclusive)
|
// - pos - The til::point for the first cell of the current glyph (inclusive)
|
||||||
const til::point TextBuffer::GetGlyphStart(const til::point pos, std::optional<til::point> limitOptional) const
|
til::point TextBuffer::GetGlyphStart(const til::point pos, std::optional<til::point> limitOptional) const
|
||||||
{
|
{
|
||||||
auto resultPos = pos.to_win32_coord();
|
auto resultPos = pos;
|
||||||
const auto bufferSize = GetSize();
|
const auto bufferSize = GetSize();
|
||||||
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
|
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
|
||||||
|
|
||||||
// Clamp pos to limit
|
// Clamp pos to limit
|
||||||
if (bufferSize.CompareInBounds(resultPos, limit.to_win32_coord(), true) > 0)
|
if (bufferSize.CompareInBounds(resultPos, limit, true) > 0)
|
||||||
{
|
{
|
||||||
resultPos = limit.to_win32_coord();
|
resultPos = limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// limit is exclusive, so we need to move back to be within valid bounds
|
// limit is exclusive, so we need to move back to be within valid bounds
|
||||||
if (resultPos != limit.to_win32_coord() && GetCellDataAt(resultPos)->DbcsAttr().IsTrailing())
|
if (resultPos != limit && GetCellDataAt(resultPos)->DbcsAttr().IsTrailing())
|
||||||
{
|
{
|
||||||
bufferSize.DecrementInBounds(resultPos, true);
|
bufferSize.DecrementInBounds(resultPos, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return til::point{ resultPos };
|
return resultPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Update pos to be the end of the current glyph/character.
|
// - Update pos to be the end of the current glyph/character.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - pos - a COORD on the word you are currently on
|
// - pos - a til::point on the word you are currently on
|
||||||
// - accessibilityMode - this is being used for accessibility; make the end exclusive.
|
// - accessibilityMode - this is being used for accessibility; make the end exclusive.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - pos - The COORD for the last cell of the current glyph (exclusive)
|
// - pos - The til::point for the last cell of the current glyph (exclusive)
|
||||||
const til::point TextBuffer::GetGlyphEnd(const til::point pos, bool accessibilityMode, std::optional<til::point> limitOptional) const
|
til::point TextBuffer::GetGlyphEnd(const til::point pos, bool accessibilityMode, std::optional<til::point> limitOptional) const
|
||||||
{
|
{
|
||||||
auto resultPos = pos.to_win32_coord();
|
auto resultPos = pos;
|
||||||
const auto bufferSize = GetSize();
|
const auto bufferSize = GetSize();
|
||||||
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
|
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
|
||||||
|
|
||||||
// Clamp pos to limit
|
// Clamp pos to limit
|
||||||
if (bufferSize.CompareInBounds(resultPos, limit.to_win32_coord(), true) > 0)
|
if (bufferSize.CompareInBounds(resultPos, limit, true) > 0)
|
||||||
{
|
{
|
||||||
resultPos = limit.to_win32_coord();
|
resultPos = limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resultPos != limit.to_win32_coord() && GetCellDataAt(resultPos)->DbcsAttr().IsLeading())
|
if (resultPos != limit && GetCellDataAt(resultPos)->DbcsAttr().IsLeading())
|
||||||
{
|
{
|
||||||
bufferSize.IncrementInBounds(resultPos, true);
|
bufferSize.IncrementInBounds(resultPos, true);
|
||||||
}
|
}
|
||||||
@@ -1513,24 +1509,24 @@ const til::point TextBuffer::GetGlyphEnd(const til::point pos, bool accessibilit
|
|||||||
{
|
{
|
||||||
bufferSize.IncrementInBounds(resultPos, true);
|
bufferSize.IncrementInBounds(resultPos, true);
|
||||||
}
|
}
|
||||||
return til::point{ resultPos };
|
return resultPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Update pos to be the beginning of the next glyph/character. This is used for accessibility
|
// - Update pos to be the beginning of the next glyph/character. This is used for accessibility
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - pos - a COORD on the word you are currently on
|
// - pos - a til::point on the word you are currently on
|
||||||
// - allowExclusiveEnd - allow result to be the exclusive limit (one past limit)
|
// - allowExclusiveEnd - allow result to be the exclusive limit (one past limit)
|
||||||
// - limit - boundaries for the iterator to operate within
|
// - limit - boundaries for the iterator to operate within
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
|
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
|
||||||
// - pos - The COORD for the first cell of the current glyph (inclusive)
|
// - pos - The til::point for the first cell of the current glyph (inclusive)
|
||||||
bool TextBuffer::MoveToNextGlyph(til::point& pos, bool allowExclusiveEnd, std::optional<til::point> limitOptional) const
|
bool TextBuffer::MoveToNextGlyph(til::point& pos, bool allowExclusiveEnd, std::optional<til::point> limitOptional) const
|
||||||
{
|
{
|
||||||
const auto bufferSize = GetSize();
|
const auto bufferSize = GetSize();
|
||||||
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
|
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
|
||||||
|
|
||||||
const auto distanceToLimit{ bufferSize.CompareInBounds(pos.to_win32_coord(), limit.to_win32_coord(), true) };
|
const auto distanceToLimit{ bufferSize.CompareInBounds(pos, limit, true) };
|
||||||
if (distanceToLimit >= 0)
|
if (distanceToLimit >= 0)
|
||||||
{
|
{
|
||||||
// Corner Case: we're on/past the limit
|
// Corner Case: we're on/past the limit
|
||||||
@@ -1547,7 +1543,7 @@ bool TextBuffer::MoveToNextGlyph(til::point& pos, bool allowExclusiveEnd, std::o
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try to move forward, but if we hit the buffer boundary, we fail to move.
|
// Try to move forward, but if we hit the buffer boundary, we fail to move.
|
||||||
auto iter{ GetCellDataAt(pos.to_win32_coord(), bufferSize) };
|
auto iter{ GetCellDataAt(pos, bufferSize) };
|
||||||
const bool success{ ++iter };
|
const bool success{ ++iter };
|
||||||
|
|
||||||
// Move again if we're on a wide glyph
|
// Move again if we're on a wide glyph
|
||||||
@@ -1556,24 +1552,24 @@ bool TextBuffer::MoveToNextGlyph(til::point& pos, bool allowExclusiveEnd, std::o
|
|||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = til::point{ iter.Pos() };
|
pos = iter.Pos();
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Update pos to be the beginning of the previous glyph/character. This is used for accessibility
|
// - Update pos to be the beginning of the previous glyph/character. This is used for accessibility
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - pos - a COORD on the word you are currently on
|
// - pos - a til::point on the word you are currently on
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
|
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
|
||||||
// - pos - The COORD for the first cell of the previous glyph (inclusive)
|
// - pos - The til::point for the first cell of the previous glyph (inclusive)
|
||||||
bool TextBuffer::MoveToPreviousGlyph(til::point& pos, std::optional<til::point> limitOptional) const
|
bool TextBuffer::MoveToPreviousGlyph(til::point& pos, std::optional<til::point> limitOptional) const
|
||||||
{
|
{
|
||||||
auto resultPos = pos.to_win32_coord();
|
auto resultPos = pos;
|
||||||
const auto bufferSize = GetSize();
|
const auto bufferSize = GetSize();
|
||||||
const auto limit{ limitOptional.value_or(til::point{ bufferSize.EndExclusive() }) };
|
const auto limit{ limitOptional.value_or(bufferSize.EndExclusive()) };
|
||||||
|
|
||||||
if (bufferSize.CompareInBounds(pos.to_win32_coord(), limit.to_win32_coord(), true) > 0)
|
if (bufferSize.CompareInBounds(pos, limit, true) > 0)
|
||||||
{
|
{
|
||||||
// we're past the end
|
// we're past the end
|
||||||
// clamp us to the limit
|
// clamp us to the limit
|
||||||
@@ -1588,7 +1584,7 @@ bool TextBuffer::MoveToPreviousGlyph(til::point& pos, std::optional<til::point>
|
|||||||
bufferSize.DecrementInBounds(resultPos, true);
|
bufferSize.DecrementInBounds(resultPos, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = til::point{ resultPos };
|
pos = resultPos;
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1606,9 +1602,9 @@ bool TextBuffer::MoveToPreviousGlyph(til::point& pos, std::optional<til::point>
|
|||||||
// the buffer rather than the screen.
|
// the buffer rather than the screen.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - the delimiter class for the given char
|
// - the delimiter class for the given char
|
||||||
const std::vector<SMALL_RECT> TextBuffer::GetTextRects(COORD start, COORD end, bool blockSelection, bool bufferCoordinates) const
|
const std::vector<til::inclusive_rect> TextBuffer::GetTextRects(til::point start, til::point end, bool blockSelection, bool bufferCoordinates) const
|
||||||
{
|
{
|
||||||
std::vector<SMALL_RECT> textRects;
|
std::vector<til::inclusive_rect> textRects;
|
||||||
|
|
||||||
const auto bufferSize = GetSize();
|
const auto bufferSize = GetSize();
|
||||||
|
|
||||||
@@ -1619,11 +1615,11 @@ const std::vector<SMALL_RECT> TextBuffer::GetTextRects(COORD start, COORD end, b
|
|||||||
std::make_tuple(start, end) :
|
std::make_tuple(start, end) :
|
||||||
std::make_tuple(end, start);
|
std::make_tuple(end, start);
|
||||||
|
|
||||||
const auto textRectSize = base::ClampedNumeric<short>(1) + lowerCoord.Y - higherCoord.Y;
|
const auto textRectSize = 1 + lowerCoord.Y - higherCoord.Y;
|
||||||
textRects.reserve(textRectSize);
|
textRects.reserve(textRectSize);
|
||||||
for (auto row = higherCoord.Y; row <= lowerCoord.Y; row++)
|
for (auto row = higherCoord.Y; row <= lowerCoord.Y; row++)
|
||||||
{
|
{
|
||||||
SMALL_RECT textRow;
|
til::inclusive_rect textRow;
|
||||||
|
|
||||||
textRow.Top = row;
|
textRow.Top = row;
|
||||||
textRow.Bottom = row;
|
textRow.Bottom = row;
|
||||||
@@ -1661,12 +1657,12 @@ const std::vector<SMALL_RECT> TextBuffer::GetTextRects(COORD start, COORD end, b
|
|||||||
// - selectionRow: the selection row to be expanded
|
// - selectionRow: the selection row to be expanded
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - modifies selectionRow's Left and Right values to expand properly
|
// - modifies selectionRow's Left and Right values to expand properly
|
||||||
void TextBuffer::_ExpandTextRow(SMALL_RECT& textRow) const
|
void TextBuffer::_ExpandTextRow(til::inclusive_rect& textRow) const
|
||||||
{
|
{
|
||||||
const auto bufferSize = GetSize();
|
const auto bufferSize = GetSize();
|
||||||
|
|
||||||
// expand left side of rect
|
// expand left side of rect
|
||||||
COORD targetPoint{ textRow.Left, textRow.Top };
|
til::point targetPoint{ textRow.Left, textRow.Top };
|
||||||
if (GetCellDataAt(targetPoint)->DbcsAttr().IsTrailing())
|
if (GetCellDataAt(targetPoint)->DbcsAttr().IsTrailing())
|
||||||
{
|
{
|
||||||
if (targetPoint.X == bufferSize.Left())
|
if (targetPoint.X == bufferSize.Left())
|
||||||
@@ -1708,7 +1704,7 @@ void TextBuffer::_ExpandTextRow(SMALL_RECT& textRow) const
|
|||||||
// - The text, background color, and foreground color data of the selected region of the text buffer.
|
// - The text, background color, and foreground color data of the selected region of the text buffer.
|
||||||
const TextBuffer::TextAndColor TextBuffer::GetText(const bool includeCRLF,
|
const TextBuffer::TextAndColor TextBuffer::GetText(const bool includeCRLF,
|
||||||
const bool trimTrailingWhitespace,
|
const bool trimTrailingWhitespace,
|
||||||
const std::vector<SMALL_RECT>& selectionRects,
|
const std::vector<til::inclusive_rect>& selectionRects,
|
||||||
std::function<std::pair<COLORREF, COLORREF>(const TextAttribute&)> GetAttributeColors,
|
std::function<std::pair<COLORREF, COLORREF>(const TextAttribute&)> GetAttributeColors,
|
||||||
const bool formatWrappedRows) const
|
const bool formatWrappedRows) const
|
||||||
{
|
{
|
||||||
@@ -1725,9 +1721,9 @@ const TextBuffer::TextAndColor TextBuffer::GetText(const bool includeCRLF,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for each row in the selection
|
// for each row in the selection
|
||||||
for (UINT i = 0; i < rows; i++)
|
for (size_t i = 0; i < rows; i++)
|
||||||
{
|
{
|
||||||
const UINT iRow = selectionRects.at(i).Top;
|
const auto iRow = selectionRects.at(i).Top;
|
||||||
|
|
||||||
const auto highlight = Viewport::FromInclusive(selectionRects.at(i));
|
const auto highlight = Viewport::FromInclusive(selectionRects.at(i));
|
||||||
|
|
||||||
@@ -2243,22 +2239,22 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
|
|||||||
const auto cOldCursorPos = oldCursor.GetPosition();
|
const auto cOldCursorPos = oldCursor.GetPosition();
|
||||||
const auto cOldLastChar = oldBuffer.GetLastNonSpaceCharacter(lastCharacterViewport);
|
const auto cOldLastChar = oldBuffer.GetLastNonSpaceCharacter(lastCharacterViewport);
|
||||||
|
|
||||||
const short cOldRowsTotal = cOldLastChar.Y + 1;
|
const auto cOldRowsTotal = cOldLastChar.Y + 1;
|
||||||
|
|
||||||
COORD cNewCursorPos = { 0 };
|
til::point cNewCursorPos;
|
||||||
auto fFoundCursorPos = false;
|
auto fFoundCursorPos = false;
|
||||||
auto foundOldMutable = false;
|
auto foundOldMutable = false;
|
||||||
auto foundOldVisible = false;
|
auto foundOldVisible = false;
|
||||||
auto hr = S_OK;
|
auto hr = S_OK;
|
||||||
// Loop through all the rows of the old buffer and reprint them into the new buffer
|
// Loop through all the rows of the old buffer and reprint them into the new buffer
|
||||||
short iOldRow = 0;
|
til::CoordType iOldRow = 0;
|
||||||
for (; iOldRow < cOldRowsTotal; iOldRow++)
|
for (; iOldRow < cOldRowsTotal; iOldRow++)
|
||||||
{
|
{
|
||||||
// Fetch the row and its "right" which is the last printable character.
|
// Fetch the row and its "right" which is the last printable character.
|
||||||
const auto& row = oldBuffer.GetRowByOffset(iOldRow);
|
const auto& row = oldBuffer.GetRowByOffset(iOldRow);
|
||||||
const auto cOldColsTotal = oldBuffer.GetLineWidth(iOldRow);
|
const auto cOldColsTotal = oldBuffer.GetLineWidth(iOldRow);
|
||||||
const auto& charRow = row.GetCharRow();
|
const auto& charRow = row.GetCharRow();
|
||||||
auto iRight = gsl::narrow_cast<short>(charRow.MeasureRight());
|
auto iRight = charRow.MeasureRight();
|
||||||
|
|
||||||
// If we're starting a new row, try and preserve the line rendition
|
// If we're starting a new row, try and preserve the line rendition
|
||||||
// from the row in the original buffer.
|
// from the row in the original buffer.
|
||||||
@@ -2296,7 +2292,7 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
|
|||||||
// Loop through every character in the current row (up to
|
// Loop through every character in the current row (up to
|
||||||
// the "right" boundary, which is one past the final valid
|
// the "right" boundary, which is one past the final valid
|
||||||
// character)
|
// character)
|
||||||
short iOldCol = 0;
|
til::CoordType iOldCol = 0;
|
||||||
const auto copyRight = iRight;
|
const auto copyRight = iRight;
|
||||||
for (; iOldCol < copyRight; iOldCol++)
|
for (; iOldCol < copyRight; iOldCol++)
|
||||||
{
|
{
|
||||||
@@ -2439,7 +2435,7 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
|
|||||||
const auto coordNewCursor = newCursor.GetPosition();
|
const auto coordNewCursor = newCursor.GetPosition();
|
||||||
if (coordNewCursor.X == 0 && coordNewCursor.Y > 0)
|
if (coordNewCursor.X == 0 && coordNewCursor.Y > 0)
|
||||||
{
|
{
|
||||||
if (newBuffer.GetRowByOffset(gsl::narrow_cast<size_t>(coordNewCursor.Y) - 1).WasWrapForced())
|
if (newBuffer.GetRowByOffset(coordNewCursor.Y - 1).WasWrapForced())
|
||||||
{
|
{
|
||||||
hr = newBuffer.NewlineCursor() ? hr : E_OUTOFMEMORY;
|
hr = newBuffer.NewlineCursor() ? hr : E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
@@ -2693,17 +2689,17 @@ void TextBuffer::CopyPatterns(const TextBuffer& OtherBuffer)
|
|||||||
// - The lastRow to search
|
// - The lastRow to search
|
||||||
// Return value:
|
// Return value:
|
||||||
// - An interval tree containing the patterns found
|
// - An interval tree containing the patterns found
|
||||||
PointTree TextBuffer::GetPatterns(const size_t firstRow, const size_t lastRow) const
|
PointTree TextBuffer::GetPatterns(const til::CoordType firstRow, const til::CoordType lastRow) const
|
||||||
{
|
{
|
||||||
PointTree::interval_vector intervals;
|
PointTree::interval_vector intervals;
|
||||||
|
|
||||||
std::wstring concatAll;
|
std::wstring concatAll;
|
||||||
const auto rowSize = GetRowByOffset(0).size();
|
const auto rowSize = GetRowByOffset(0).size();
|
||||||
concatAll.reserve(rowSize * (lastRow - firstRow + 1));
|
concatAll.reserve(gsl::narrow_cast<size_t>(rowSize) * gsl::narrow_cast<size_t>(lastRow - firstRow + 1));
|
||||||
|
|
||||||
// to deal with text that spans multiple lines, we will first concatenate
|
// to deal with text that spans multiple lines, we will first concatenate
|
||||||
// all the text into one string and find the patterns in that string
|
// all the text into one string and find the patterns in that string
|
||||||
for (auto i = firstRow; i <= lastRow; ++i)
|
for (til::CoordType i = firstRow; i <= lastRow; ++i)
|
||||||
{
|
{
|
||||||
auto& row = GetRowByOffset(i);
|
auto& row = GetRowByOffset(i);
|
||||||
concatAll += row.GetText();
|
concatAll += row.GetText();
|
||||||
@@ -2718,21 +2714,21 @@ PointTree TextBuffer::GetPatterns(const size_t firstRow, const size_t lastRow) c
|
|||||||
auto words_begin = std::wsregex_iterator(concatAll.begin(), concatAll.end(), regexObj);
|
auto words_begin = std::wsregex_iterator(concatAll.begin(), concatAll.end(), regexObj);
|
||||||
auto words_end = std::wsregex_iterator();
|
auto words_end = std::wsregex_iterator();
|
||||||
|
|
||||||
size_t lenUpToThis = 0;
|
til::CoordType lenUpToThis = 0;
|
||||||
for (auto i = words_begin; i != words_end; ++i)
|
for (auto i = words_begin; i != words_end; ++i)
|
||||||
{
|
{
|
||||||
// record the locations -
|
// record the locations -
|
||||||
// when we find a match, the prefix is text that is between this
|
// when we find a match, the prefix is text that is between this
|
||||||
// match and the previous match, so we use the size of the prefix
|
// match and the previous match, so we use the size of the prefix
|
||||||
// along with the size of the match to determine the locations
|
// along with the size of the match to determine the locations
|
||||||
size_t prefixSize = 0;
|
til::CoordType prefixSize = 0;
|
||||||
for (const auto parsedGlyph : Utf16Parser::Parse(i->prefix().str()))
|
for (const auto parsedGlyph : Utf16Parser::Parse(i->prefix().str()))
|
||||||
{
|
{
|
||||||
const std::wstring_view glyph{ parsedGlyph.data(), parsedGlyph.size() };
|
const std::wstring_view glyph{ parsedGlyph.data(), parsedGlyph.size() };
|
||||||
prefixSize += IsGlyphFullWidth(glyph) ? 2 : 1;
|
prefixSize += IsGlyphFullWidth(glyph) ? 2 : 1;
|
||||||
}
|
}
|
||||||
const auto start = lenUpToThis + prefixSize;
|
const auto start = lenUpToThis + prefixSize;
|
||||||
size_t matchSize = 0;
|
til::CoordType matchSize = 0;
|
||||||
for (const auto parsedGlyph : Utf16Parser::Parse(i->str()))
|
for (const auto parsedGlyph : Utf16Parser::Parse(i->str()))
|
||||||
{
|
{
|
||||||
const std::wstring_view glyph{ parsedGlyph.data(), parsedGlyph.size() };
|
const std::wstring_view glyph{ parsedGlyph.data(), parsedGlyph.size() };
|
||||||
@@ -2741,8 +2737,8 @@ PointTree TextBuffer::GetPatterns(const size_t firstRow, const size_t lastRow) c
|
|||||||
const auto end = start + matchSize;
|
const auto end = start + matchSize;
|
||||||
lenUpToThis = end;
|
lenUpToThis = end;
|
||||||
|
|
||||||
const til::point startCoord{ gsl::narrow<SHORT>(start % rowSize), gsl::narrow<SHORT>(start / rowSize) };
|
const til::point startCoord{ start % rowSize, start / rowSize };
|
||||||
const til::point endCoord{ gsl::narrow<SHORT>(end % rowSize), gsl::narrow<SHORT>(end / rowSize) };
|
const til::point endCoord{ end % rowSize, end / rowSize };
|
||||||
|
|
||||||
// store the intervals
|
// store the intervals
|
||||||
// NOTE: these intervals are relative to the VIEWPORT not the buffer
|
// NOTE: these intervals are relative to the VIEWPORT not the buffer
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ namespace Microsoft::Console::Render
|
|||||||
class TextBuffer final
|
class TextBuffer final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TextBuffer(const COORD screenBufferSize,
|
TextBuffer(const til::size screenBufferSize,
|
||||||
const TextAttribute defaultAttributes,
|
const TextAttribute defaultAttributes,
|
||||||
const UINT cursorSize,
|
const UINT cursorSize,
|
||||||
const bool isActiveBuffer,
|
const bool isActiveBuffer,
|
||||||
@@ -79,27 +79,27 @@ public:
|
|||||||
void CopyProperties(const TextBuffer& OtherBuffer) noexcept;
|
void CopyProperties(const TextBuffer& OtherBuffer) noexcept;
|
||||||
|
|
||||||
// row manipulation
|
// row manipulation
|
||||||
const ROW& GetRowByOffset(const size_t index) const;
|
const ROW& GetRowByOffset(const til::CoordType index) const noexcept;
|
||||||
ROW& GetRowByOffset(const size_t index);
|
ROW& GetRowByOffset(const til::CoordType index) noexcept;
|
||||||
|
|
||||||
TextBufferCellIterator GetCellDataAt(const COORD at) const;
|
TextBufferCellIterator GetCellDataAt(const til::point at) const;
|
||||||
TextBufferCellIterator GetCellLineDataAt(const COORD at) const;
|
TextBufferCellIterator GetCellLineDataAt(const til::point at) const;
|
||||||
TextBufferCellIterator GetCellDataAt(const COORD at, const Microsoft::Console::Types::Viewport limit) const;
|
TextBufferCellIterator GetCellDataAt(const til::point at, const Microsoft::Console::Types::Viewport limit) const;
|
||||||
TextBufferTextIterator GetTextDataAt(const COORD at) const;
|
TextBufferTextIterator GetTextDataAt(const til::point at) const;
|
||||||
TextBufferTextIterator GetTextLineDataAt(const COORD at) const;
|
TextBufferTextIterator GetTextLineDataAt(const til::point at) const;
|
||||||
TextBufferTextIterator GetTextDataAt(const COORD at, const Microsoft::Console::Types::Viewport limit) const;
|
TextBufferTextIterator GetTextDataAt(const til::point at, const Microsoft::Console::Types::Viewport limit) const;
|
||||||
|
|
||||||
// Text insertion functions
|
// Text insertion functions
|
||||||
OutputCellIterator Write(const OutputCellIterator givenIt);
|
OutputCellIterator Write(const OutputCellIterator givenIt);
|
||||||
|
|
||||||
OutputCellIterator Write(const OutputCellIterator givenIt,
|
OutputCellIterator Write(const OutputCellIterator givenIt,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
const std::optional<bool> wrap = true);
|
const std::optional<bool> wrap = true);
|
||||||
|
|
||||||
OutputCellIterator WriteLine(const OutputCellIterator givenIt,
|
OutputCellIterator WriteLine(const OutputCellIterator givenIt,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
const std::optional<bool> setWrap = std::nullopt,
|
const std::optional<bool> setWrap = std::nullopt,
|
||||||
const std::optional<size_t> limitRight = std::nullopt);
|
const std::optional<til::CoordType> limitRight = std::nullopt);
|
||||||
|
|
||||||
bool InsertCharacter(const wchar_t wch, const DbcsAttribute dbcsAttribute, const TextAttribute attr);
|
bool InsertCharacter(const wchar_t wch, const DbcsAttribute dbcsAttribute, const TextAttribute attr);
|
||||||
bool InsertCharacter(const std::wstring_view chars, const DbcsAttribute dbcsAttribute, const TextAttribute attr);
|
bool InsertCharacter(const std::wstring_view chars, const DbcsAttribute dbcsAttribute, const TextAttribute attr);
|
||||||
@@ -109,36 +109,36 @@ public:
|
|||||||
// Scroll needs access to this to quickly rotate around the buffer.
|
// Scroll needs access to this to quickly rotate around the buffer.
|
||||||
bool IncrementCircularBuffer(const bool inVtMode = false);
|
bool IncrementCircularBuffer(const bool inVtMode = false);
|
||||||
|
|
||||||
COORD GetLastNonSpaceCharacter(std::optional<const Microsoft::Console::Types::Viewport> viewOptional = std::nullopt) const;
|
til::point GetLastNonSpaceCharacter(std::optional<const Microsoft::Console::Types::Viewport> viewOptional = std::nullopt) const;
|
||||||
|
|
||||||
Cursor& GetCursor() noexcept;
|
Cursor& GetCursor() noexcept;
|
||||||
const Cursor& GetCursor() const noexcept;
|
const Cursor& GetCursor() const noexcept;
|
||||||
|
|
||||||
const SHORT GetFirstRowIndex() const noexcept;
|
const til::CoordType GetFirstRowIndex() const noexcept;
|
||||||
|
|
||||||
const Microsoft::Console::Types::Viewport GetSize() const noexcept;
|
const Microsoft::Console::Types::Viewport GetSize() const noexcept;
|
||||||
|
|
||||||
void ScrollRows(const SHORT firstRow, const SHORT size, const SHORT delta);
|
void ScrollRows(const til::CoordType firstRow, const til::CoordType size, const til::CoordType delta);
|
||||||
|
|
||||||
UINT TotalRowCount() const noexcept;
|
til::CoordType TotalRowCount() const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] TextAttribute GetCurrentAttributes() const noexcept;
|
[[nodiscard]] TextAttribute GetCurrentAttributes() const noexcept;
|
||||||
|
|
||||||
void SetCurrentAttributes(const TextAttribute& currentAttributes) noexcept;
|
void SetCurrentAttributes(const TextAttribute& currentAttributes) noexcept;
|
||||||
|
|
||||||
void SetCurrentLineRendition(const LineRendition lineRendition);
|
void SetCurrentLineRendition(const LineRendition lineRendition);
|
||||||
void ResetLineRenditionRange(const size_t startRow, const size_t endRow);
|
void ResetLineRenditionRange(const til::CoordType startRow, const til::CoordType endRow) noexcept;
|
||||||
LineRendition GetLineRendition(const size_t row) const;
|
LineRendition GetLineRendition(const til::CoordType row) const noexcept;
|
||||||
bool IsDoubleWidthLine(const size_t row) const;
|
bool IsDoubleWidthLine(const til::CoordType row) const noexcept;
|
||||||
|
|
||||||
SHORT GetLineWidth(const size_t row) const;
|
til::CoordType GetLineWidth(const til::CoordType row) const noexcept;
|
||||||
COORD ClampPositionWithinLine(const COORD position) const;
|
til::point ClampPositionWithinLine(const til::point position) const noexcept;
|
||||||
COORD ScreenToBufferPosition(const COORD position) const;
|
til::point ScreenToBufferPosition(const til::point position) const noexcept;
|
||||||
COORD BufferToScreenPosition(const COORD position) const;
|
til::point BufferToScreenPosition(const til::point position) const noexcept;
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
[[nodiscard]] HRESULT ResizeTraditional(const COORD newSize) noexcept;
|
[[nodiscard]] HRESULT ResizeTraditional(const til::size newSize) noexcept;
|
||||||
|
|
||||||
const UnicodeStorage& GetUnicodeStorage() const noexcept;
|
const UnicodeStorage& GetUnicodeStorage() const noexcept;
|
||||||
UnicodeStorage& GetUnicodeStorage() noexcept;
|
UnicodeStorage& GetUnicodeStorage() noexcept;
|
||||||
@@ -149,23 +149,23 @@ public:
|
|||||||
Microsoft::Console::Render::Renderer& GetRenderer() noexcept;
|
Microsoft::Console::Render::Renderer& GetRenderer() noexcept;
|
||||||
|
|
||||||
void TriggerRedraw(const Microsoft::Console::Types::Viewport& viewport);
|
void TriggerRedraw(const Microsoft::Console::Types::Viewport& viewport);
|
||||||
void TriggerRedrawCursor(const COORD position);
|
void TriggerRedrawCursor(const til::point position);
|
||||||
void TriggerRedrawAll();
|
void TriggerRedrawAll();
|
||||||
void TriggerScroll();
|
void TriggerScroll();
|
||||||
void TriggerScroll(const COORD delta);
|
void TriggerScroll(const til::point delta);
|
||||||
void TriggerNewTextNotification(const std::wstring_view newText);
|
void TriggerNewTextNotification(const std::wstring_view newText);
|
||||||
|
|
||||||
const COORD GetWordStart(const COORD target, const std::wstring_view wordDelimiters, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
|
til::point GetWordStart(const til::point target, const std::wstring_view wordDelimiters, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||||
const COORD GetWordEnd(const COORD target, const std::wstring_view wordDelimiters, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
|
til::point GetWordEnd(const til::point target, const std::wstring_view wordDelimiters, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||||
bool MoveToNextWord(COORD& pos, const std::wstring_view wordDelimiters, std::optional<til::point> limitOptional = std::nullopt) const;
|
bool MoveToNextWord(til::point& pos, const std::wstring_view wordDelimiters, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||||
bool MoveToPreviousWord(COORD& pos, const std::wstring_view wordDelimiters) const;
|
bool MoveToPreviousWord(til::point& pos, const std::wstring_view wordDelimiters) const;
|
||||||
|
|
||||||
const til::point GetGlyphStart(const til::point pos, std::optional<til::point> limitOptional = std::nullopt) const;
|
til::point GetGlyphStart(const til::point pos, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||||
const til::point GetGlyphEnd(const til::point pos, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
|
til::point GetGlyphEnd(const til::point pos, bool accessibilityMode = false, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||||
bool MoveToNextGlyph(til::point& pos, bool allowBottomExclusive = false, std::optional<til::point> limitOptional = std::nullopt) const;
|
bool MoveToNextGlyph(til::point& pos, bool allowBottomExclusive = false, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||||
bool MoveToPreviousGlyph(til::point& pos, std::optional<til::point> limitOptional = std::nullopt) const;
|
bool MoveToPreviousGlyph(til::point& pos, std::optional<til::point> limitOptional = std::nullopt) const;
|
||||||
|
|
||||||
const std::vector<SMALL_RECT> GetTextRects(COORD start, COORD end, bool blockSelection, bool bufferCoordinates) const;
|
const std::vector<til::inclusive_rect> GetTextRects(til::point start, til::point end, bool blockSelection, bool bufferCoordinates) const;
|
||||||
|
|
||||||
void AddHyperlinkToMap(std::wstring_view uri, uint16_t id);
|
void AddHyperlinkToMap(std::wstring_view uri, uint16_t id);
|
||||||
std::wstring GetHyperlinkUriFromId(uint16_t id) const;
|
std::wstring GetHyperlinkUriFromId(uint16_t id) const;
|
||||||
@@ -184,7 +184,7 @@ public:
|
|||||||
|
|
||||||
const TextAndColor GetText(const bool includeCRLF,
|
const TextAndColor GetText(const bool includeCRLF,
|
||||||
const bool trimTrailingWhitespace,
|
const bool trimTrailingWhitespace,
|
||||||
const std::vector<SMALL_RECT>& textRects,
|
const std::vector<til::inclusive_rect>& textRects,
|
||||||
std::function<std::pair<COLORREF, COLORREF>(const TextAttribute&)> GetAttributeColors = nullptr,
|
std::function<std::pair<COLORREF, COLORREF>(const TextAttribute&)> GetAttributeColors = nullptr,
|
||||||
const bool formatWrappedRows = false) const;
|
const bool formatWrappedRows = false) const;
|
||||||
|
|
||||||
@@ -200,8 +200,8 @@ public:
|
|||||||
|
|
||||||
struct PositionInformation
|
struct PositionInformation
|
||||||
{
|
{
|
||||||
short mutableViewportTop{ 0 };
|
til::CoordType mutableViewportTop{ 0 };
|
||||||
short visibleViewportTop{ 0 };
|
til::CoordType visibleViewportTop{ 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
static HRESULT Reflow(TextBuffer& oldBuffer,
|
static HRESULT Reflow(TextBuffer& oldBuffer,
|
||||||
@@ -212,7 +212,7 @@ public:
|
|||||||
const size_t AddPatternRecognizer(const std::wstring_view regexString);
|
const size_t AddPatternRecognizer(const std::wstring_view regexString);
|
||||||
void ClearPatternRecognizers() noexcept;
|
void ClearPatternRecognizers() noexcept;
|
||||||
void CopyPatterns(const TextBuffer& OtherBuffer);
|
void CopyPatterns(const TextBuffer& OtherBuffer);
|
||||||
interval_tree::IntervalTree<til::point, size_t> GetPatterns(const size_t firstRow, const size_t lastRow) const;
|
interval_tree::IntervalTree<til::point, size_t> GetPatterns(const til::CoordType firstRow, const til::CoordType lastRow) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _UpdateSize();
|
void _UpdateSize();
|
||||||
@@ -220,7 +220,7 @@ private:
|
|||||||
std::vector<ROW> _storage;
|
std::vector<ROW> _storage;
|
||||||
Cursor _cursor;
|
Cursor _cursor;
|
||||||
|
|
||||||
SHORT _firstRow; // indexes top row (not necessarily 0)
|
til::CoordType _firstRow; // indexes top row (not necessarily 0)
|
||||||
|
|
||||||
TextAttribute _currentAttributes;
|
TextAttribute _currentAttributes;
|
||||||
|
|
||||||
@@ -234,29 +234,29 @@ private:
|
|||||||
std::unordered_map<std::wstring, uint16_t> _hyperlinkCustomIdMap;
|
std::unordered_map<std::wstring, uint16_t> _hyperlinkCustomIdMap;
|
||||||
uint16_t _currentHyperlinkId;
|
uint16_t _currentHyperlinkId;
|
||||||
|
|
||||||
void _RefreshRowIDs(std::optional<SHORT> newRowWidth);
|
void _RefreshRowIDs(std::optional<til::CoordType> newRowWidth);
|
||||||
|
|
||||||
void _SetFirstRowIndex(const SHORT FirstRowIndex) noexcept;
|
void _SetFirstRowIndex(const til::CoordType FirstRowIndex) noexcept;
|
||||||
|
|
||||||
COORD _GetPreviousFromCursor() const;
|
til::point _GetPreviousFromCursor() const noexcept;
|
||||||
|
|
||||||
void _SetWrapOnCurrentRow();
|
void _SetWrapOnCurrentRow() noexcept;
|
||||||
void _AdjustWrapOnCurrentRow(const bool fSet);
|
void _AdjustWrapOnCurrentRow(const bool fSet) noexcept;
|
||||||
|
|
||||||
// Assist with maintaining proper buffer state for Double Byte character sequences
|
// Assist with maintaining proper buffer state for Double Byte character sequences
|
||||||
bool _PrepareForDoubleByteSequence(const DbcsAttribute dbcsAttribute);
|
bool _PrepareForDoubleByteSequence(const DbcsAttribute dbcsAttribute);
|
||||||
bool _AssertValidDoubleByteSequence(const DbcsAttribute dbcsAttribute);
|
bool _AssertValidDoubleByteSequence(const DbcsAttribute dbcsAttribute);
|
||||||
|
|
||||||
ROW& _GetFirstRow();
|
ROW& _GetFirstRow() noexcept;
|
||||||
ROW& _GetPrevRowNoWrap(const ROW& row);
|
ROW& _GetPrevRowNoWrap(const ROW& row);
|
||||||
|
|
||||||
void _ExpandTextRow(SMALL_RECT& selectionRow) const;
|
void _ExpandTextRow(til::inclusive_rect& selectionRow) const;
|
||||||
|
|
||||||
const DelimiterClass _GetDelimiterClassAt(const COORD pos, const std::wstring_view wordDelimiters) const;
|
DelimiterClass _GetDelimiterClassAt(const til::point pos, const std::wstring_view wordDelimiters) const;
|
||||||
const COORD _GetWordStartForAccessibility(const COORD target, const std::wstring_view wordDelimiters) const;
|
til::point _GetWordStartForAccessibility(const til::point target, const std::wstring_view wordDelimiters) const;
|
||||||
const COORD _GetWordStartForSelection(const COORD target, const std::wstring_view wordDelimiters) const;
|
til::point _GetWordStartForSelection(const til::point target, const std::wstring_view wordDelimiters) const;
|
||||||
const COORD _GetWordEndForAccessibility(const COORD target, const std::wstring_view wordDelimiters, const COORD limit) const;
|
til::point _GetWordEndForAccessibility(const til::point target, const std::wstring_view wordDelimiters, const til::point limit) const;
|
||||||
const COORD _GetWordEndForSelection(const COORD target, const std::wstring_view wordDelimiters) const;
|
til::point _GetWordEndForSelection(const til::point target, const std::wstring_view wordDelimiters) const;
|
||||||
|
|
||||||
void _PruneHyperlinks();
|
void _PruneHyperlinks();
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ using namespace Microsoft::Console::Types;
|
|||||||
// Arguments:
|
// Arguments:
|
||||||
// - buffer - Text buffer to seek through
|
// - buffer - Text buffer to seek through
|
||||||
// - pos - Starting position to retrieve text data from (within screen buffer bounds)
|
// - pos - Starting position to retrieve text data from (within screen buffer bounds)
|
||||||
TextBufferCellIterator::TextBufferCellIterator(const TextBuffer& buffer, COORD pos) :
|
TextBufferCellIterator::TextBufferCellIterator(const TextBuffer& buffer, til::point pos) :
|
||||||
TextBufferCellIterator(buffer, pos, buffer.GetSize())
|
TextBufferCellIterator(buffer, pos, buffer.GetSize())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ TextBufferCellIterator::TextBufferCellIterator(const TextBuffer& buffer, COORD p
|
|||||||
// - buffer - Pointer to screen buffer to seek through
|
// - buffer - Pointer to screen buffer to seek through
|
||||||
// - pos - Starting position to retrieve text data from (within screen buffer bounds)
|
// - pos - Starting position to retrieve text data from (within screen buffer bounds)
|
||||||
// - limits - Viewport limits to restrict the iterator within the buffer bounds (smaller than the buffer itself)
|
// - limits - Viewport limits to restrict the iterator within the buffer bounds (smaller than the buffer itself)
|
||||||
TextBufferCellIterator::TextBufferCellIterator(const TextBuffer& buffer, COORD pos, const Viewport limits) :
|
TextBufferCellIterator::TextBufferCellIterator(const TextBuffer& buffer, til::point pos, const Viewport limits) :
|
||||||
_buffer(buffer),
|
_buffer(buffer),
|
||||||
_pos(pos),
|
_pos(pos),
|
||||||
_pRow(s_GetRow(buffer, pos)),
|
_pRow(s_GetRow(buffer, pos)),
|
||||||
@@ -126,7 +126,7 @@ TextBufferCellIterator& TextBufferCellIterator::operator+=(const ptrdiff_t& move
|
|||||||
const auto oldX = _pos.X;
|
const auto oldX = _pos.X;
|
||||||
const auto oldY = _pos.Y;
|
const auto oldY = _pos.Y;
|
||||||
|
|
||||||
// Under MSVC writing the individual members of a COORD generates worse assembly
|
// Under MSVC writing the individual members of a til::point generates worse assembly
|
||||||
// compared to having them be local variables. This causes a performance impact.
|
// compared to having them be local variables. This causes a performance impact.
|
||||||
auto newX = oldX;
|
auto newX = oldX;
|
||||||
auto newY = oldY;
|
auto newY = oldY;
|
||||||
@@ -289,7 +289,7 @@ ptrdiff_t TextBufferCellIterator::operator-(const TextBufferCellIterator& it)
|
|||||||
// - Sets the coordinate position that this iterator will inspect within the text buffer on dereference.
|
// - Sets the coordinate position that this iterator will inspect within the text buffer on dereference.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - newPos - The new coordinate position.
|
// - newPos - The new coordinate position.
|
||||||
void TextBufferCellIterator::_SetPos(const COORD newPos)
|
void TextBufferCellIterator::_SetPos(const til::point newPos)
|
||||||
{
|
{
|
||||||
if (newPos.Y != _pos.Y)
|
if (newPos.Y != _pos.Y)
|
||||||
{
|
{
|
||||||
@@ -317,7 +317,7 @@ void TextBufferCellIterator::_SetPos(const COORD newPos)
|
|||||||
// - pos - Position inside screen buffer bounds to retrieve row
|
// - pos - Position inside screen buffer bounds to retrieve row
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - Pointer to the underlying CharRow structure
|
// - Pointer to the underlying CharRow structure
|
||||||
const ROW* TextBufferCellIterator::s_GetRow(const TextBuffer& buffer, const COORD pos)
|
const ROW* TextBufferCellIterator::s_GetRow(const TextBuffer& buffer, const til::point pos) noexcept
|
||||||
{
|
{
|
||||||
return &buffer.GetRowByOffset(pos.Y);
|
return &buffer.GetRowByOffset(pos.Y);
|
||||||
}
|
}
|
||||||
@@ -354,7 +354,7 @@ const OutputCellView* TextBufferCellIterator::operator->() const noexcept
|
|||||||
return &_view;
|
return &_view;
|
||||||
}
|
}
|
||||||
|
|
||||||
COORD TextBufferCellIterator::Pos() const noexcept
|
til::point TextBufferCellIterator::Pos() const noexcept
|
||||||
{
|
{
|
||||||
return _pos;
|
return _pos;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ class TextBuffer;
|
|||||||
class TextBufferCellIterator
|
class TextBufferCellIterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TextBufferCellIterator(const TextBuffer& buffer, COORD pos);
|
TextBufferCellIterator(const TextBuffer& buffer, til::point pos);
|
||||||
TextBufferCellIterator(const TextBuffer& buffer, COORD pos, const Microsoft::Console::Types::Viewport limits);
|
TextBufferCellIterator(const TextBuffer& buffer, til::point pos, const Microsoft::Console::Types::Viewport limits);
|
||||||
|
|
||||||
operator bool() const noexcept;
|
operator bool() const noexcept;
|
||||||
|
|
||||||
@@ -47,12 +47,12 @@ public:
|
|||||||
const OutputCellView& operator*() const noexcept;
|
const OutputCellView& operator*() const noexcept;
|
||||||
const OutputCellView* operator->() const noexcept;
|
const OutputCellView* operator->() const noexcept;
|
||||||
|
|
||||||
COORD Pos() const noexcept;
|
til::point Pos() const noexcept;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void _SetPos(const COORD newPos);
|
void _SetPos(const til::point newPos);
|
||||||
void _GenerateView();
|
void _GenerateView();
|
||||||
static const ROW* s_GetRow(const TextBuffer& buffer, const COORD pos);
|
static const ROW* s_GetRow(const TextBuffer& buffer, const til::point pos) noexcept;
|
||||||
|
|
||||||
OutputCellView _view;
|
OutputCellView _view;
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ protected:
|
|||||||
const TextBuffer& _buffer;
|
const TextBuffer& _buffer;
|
||||||
const Microsoft::Console::Types::Viewport _bounds;
|
const Microsoft::Console::Types::Viewport _bounds;
|
||||||
bool _exceeded;
|
bool _exceeded;
|
||||||
COORD _pos;
|
til::point _pos;
|
||||||
|
|
||||||
#if UNIT_TESTING
|
#if UNIT_TESTING
|
||||||
friend class TextBufferIteratorTests;
|
friend class TextBufferIteratorTests;
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ namespace
|
|||||||
|
|
||||||
struct TestBuffer
|
struct TestBuffer
|
||||||
{
|
{
|
||||||
COORD size;
|
til::size size;
|
||||||
std::vector<TestRow> rows;
|
std::vector<TestRow> rows;
|
||||||
COORD cursor;
|
til::point cursor;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TestCase
|
struct TestCase
|
||||||
@@ -737,7 +737,7 @@ class ReflowTests
|
|||||||
{
|
{
|
||||||
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);
|
||||||
|
|
||||||
size_t i{};
|
til::CoordType i{};
|
||||||
for (const auto& testRow : testBuffer.rows)
|
for (const auto& testRow : testBuffer.rows)
|
||||||
{
|
{
|
||||||
auto& row{ buffer->GetRowByOffset(i) };
|
auto& row{ buffer->GetRowByOffset(i) };
|
||||||
@@ -745,7 +745,7 @@ class ReflowTests
|
|||||||
auto& charRow{ row.GetCharRow() };
|
auto& charRow{ row.GetCharRow() };
|
||||||
row.SetWrapForced(testRow.wrap);
|
row.SetWrapForced(testRow.wrap);
|
||||||
|
|
||||||
size_t j{};
|
til::CoordType j{};
|
||||||
for (auto it{ charRow.begin() }; it != charRow.end(); ++it)
|
for (auto it{ charRow.begin() }; it != charRow.end(); ++it)
|
||||||
{
|
{
|
||||||
// Yes, we're about to manually create a buffer. It is unpleasant.
|
// Yes, we're about to manually create a buffer. It is unpleasant.
|
||||||
@@ -771,7 +771,7 @@ class ReflowTests
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::unique_ptr<TextBuffer> _textBufferByReflowingTextBuffer(TextBuffer& originalBuffer, const COORD 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, std::nullopt, std::nullopt);
|
TextBuffer::Reflow(originalBuffer, *buffer, std::nullopt, std::nullopt);
|
||||||
@@ -783,7 +783,7 @@ class ReflowTests
|
|||||||
VERIFY_ARE_EQUAL(testBuffer.cursor, buffer.GetCursor().GetPosition());
|
VERIFY_ARE_EQUAL(testBuffer.cursor, buffer.GetCursor().GetPosition());
|
||||||
VERIFY_ARE_EQUAL(testBuffer.size, buffer.GetSize().Dimensions());
|
VERIFY_ARE_EQUAL(testBuffer.size, buffer.GetSize().Dimensions());
|
||||||
|
|
||||||
size_t i{};
|
til::CoordType i{};
|
||||||
for (const auto& testRow : testBuffer.rows)
|
for (const auto& testRow : testBuffer.rows)
|
||||||
{
|
{
|
||||||
NoThrowString indexString;
|
NoThrowString indexString;
|
||||||
@@ -794,7 +794,7 @@ class ReflowTests
|
|||||||
indexString.Format(L"[Row %d]", i);
|
indexString.Format(L"[Row %d]", i);
|
||||||
VERIFY_ARE_EQUAL(testRow.wrap, row.WasWrapForced(), indexString);
|
VERIFY_ARE_EQUAL(testRow.wrap, row.WasWrapForced(), indexString);
|
||||||
|
|
||||||
size_t j{};
|
til::CoordType j{};
|
||||||
for (auto it{ charRow.begin() }; it != charRow.end(); ++it)
|
for (auto it{ charRow.begin() }; it != charRow.end(); ++it)
|
||||||
{
|
{
|
||||||
indexString.Format(L"[Cell %d, %d; Text line index %d]", it - charRow.begin(), i, j);
|
indexString.Format(L"[Cell %d, %d; Text line index %d]", it - charRow.begin(), i, j);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class UnicodeStorageTests
|
|||||||
TEST_METHOD(CanOverwriteEmoji)
|
TEST_METHOD(CanOverwriteEmoji)
|
||||||
{
|
{
|
||||||
UnicodeStorage storage;
|
UnicodeStorage storage;
|
||||||
const COORD coord{ 1, 3 };
|
const til::point coord{ 1, 3 };
|
||||||
const std::vector<wchar_t> newMoon{ 0xD83C, 0xDF11 };
|
const std::vector<wchar_t> newMoon{ 0xD83C, 0xDF11 };
|
||||||
const std::vector<wchar_t> fullMoon{ 0xD83C, 0xDF15 };
|
const std::vector<wchar_t> fullMoon{ 0xD83C, 0xDF15 };
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ Abstract:
|
|||||||
|
|
||||||
// private dependencies
|
// private dependencies
|
||||||
#include "../host/conddkrefs.h"
|
#include "../host/conddkrefs.h"
|
||||||
#include "../inc/operators.hpp"
|
|
||||||
#include "../inc/unicode.hpp"
|
#include "../inc/unicode.hpp"
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
|
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ HRESULT HwndTerminal::Initialize()
|
|||||||
RECT windowRect;
|
RECT windowRect;
|
||||||
GetWindowRect(_hwnd.get(), &windowRect);
|
GetWindowRect(_hwnd.get(), &windowRect);
|
||||||
|
|
||||||
const COORD windowSize{ gsl::narrow<short>(windowRect.right - windowRect.left), gsl::narrow<short>(windowRect.bottom - windowRect.top) };
|
const til::size windowSize{ windowRect.right - windowRect.left, windowRect.bottom - windowRect.top };
|
||||||
|
|
||||||
// Fist set up the dx engine with the window size in pixels.
|
// Fist set up the dx engine with the window size in pixels.
|
||||||
// Then, using the font, get the number of characters that can fit.
|
// Then, using the font, get the number of characters that can fit.
|
||||||
@@ -239,7 +239,7 @@ HRESULT HwndTerminal::Initialize()
|
|||||||
|
|
||||||
_renderEngine = std::move(dxEngine);
|
_renderEngine = std::move(dxEngine);
|
||||||
|
|
||||||
_terminal->Create(COORD{ 80, 25 }, 1000, *_renderer);
|
_terminal->Create({ 80, 25 }, 1000, *_renderer);
|
||||||
_terminal->SetWriteInputCallback([=](std::wstring_view input) noexcept { _WriteTextToConnection(input); });
|
_terminal->SetWriteInputCallback([=](std::wstring_view input) noexcept { _WriteTextToConnection(input); });
|
||||||
localPointerToThread->EnablePainting();
|
localPointerToThread->EnablePainting();
|
||||||
|
|
||||||
@@ -343,7 +343,7 @@ IRawElementProviderSimple* HwndTerminal::_GetUiaProvider() noexcept
|
|||||||
return _uiaProvider.Get();
|
return _uiaProvider.Get();
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT HwndTerminal::Refresh(const SIZE windowSize, _Out_ COORD* dimensions)
|
HRESULT HwndTerminal::Refresh(const til::size windowSize, _Out_ til::size* dimensions)
|
||||||
{
|
{
|
||||||
RETURN_HR_IF_NULL(E_INVALIDARG, dimensions);
|
RETURN_HR_IF_NULL(E_INVALIDARG, dimensions);
|
||||||
|
|
||||||
@@ -357,8 +357,7 @@ HRESULT HwndTerminal::Refresh(const SIZE windowSize, _Out_ COORD* dimensions)
|
|||||||
_renderer->TriggerRedrawAll();
|
_renderer->TriggerRedrawAll();
|
||||||
|
|
||||||
// Convert our new dimensions to characters
|
// Convert our new dimensions to characters
|
||||||
const auto viewInPixels = Viewport::FromDimensions({ 0, 0 },
|
const auto viewInPixels = Viewport::FromDimensions(windowSize);
|
||||||
{ gsl::narrow<short>(windowSize.cx), gsl::narrow<short>(windowSize.cy) });
|
|
||||||
const auto vp = _renderEngine->GetViewportInCharacters(viewInPixels);
|
const auto vp = _renderEngine->GetViewportInCharacters(viewInPixels);
|
||||||
|
|
||||||
// If this function succeeds with S_FALSE, then the terminal didn't
|
// If this function succeeds with S_FALSE, then the terminal didn't
|
||||||
@@ -435,7 +434,7 @@ void _stdcall TerminalSendOutput(void* terminal, LPCWSTR data)
|
|||||||
/// <param name="height">New height of the terminal in pixels</param>
|
/// <param name="height">New height of the terminal in pixels</param>
|
||||||
/// <param name="dimensions">Out parameter containing the columns and rows that fit the new size.</param>
|
/// <param name="dimensions">Out parameter containing the columns and rows that fit the new size.</param>
|
||||||
/// <returns>HRESULT of the attempted resize.</returns>
|
/// <returns>HRESULT of the attempted resize.</returns>
|
||||||
HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions)
|
HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions)
|
||||||
{
|
{
|
||||||
const auto publicTerminal = static_cast<HwndTerminal*>(terminal);
|
const auto publicTerminal = static_cast<HwndTerminal*>(terminal);
|
||||||
|
|
||||||
@@ -448,7 +447,7 @@ HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ short width, _I
|
|||||||
static_cast<int>(height),
|
static_cast<int>(height),
|
||||||
0));
|
0));
|
||||||
|
|
||||||
const SIZE windowSize{ width, height };
|
const til::size windowSize{ width, height };
|
||||||
return publicTerminal->Refresh(windowSize, dimensions);
|
return publicTerminal->Refresh(windowSize, dimensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -459,19 +458,19 @@ HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ short width, _I
|
|||||||
/// <param name="dimensionsInCharacters">New terminal size in row and column count.</param>
|
/// <param name="dimensionsInCharacters">New terminal size in row and column count.</param>
|
||||||
/// <param name="dimensionsInPixels">Out parameter with the new size of the renderer.</param>
|
/// <param name="dimensionsInPixels">Out parameter with the new size of the renderer.</param>
|
||||||
/// <returns>HRESULT of the attempted resize.</returns>
|
/// <returns>HRESULT of the attempted resize.</returns>
|
||||||
HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ COORD dimensionsInCharacters, _Out_ SIZE* dimensionsInPixels)
|
HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ til::size dimensionsInCharacters, _Out_ til::size* dimensionsInPixels)
|
||||||
{
|
{
|
||||||
RETURN_HR_IF_NULL(E_INVALIDARG, dimensionsInPixels);
|
RETURN_HR_IF_NULL(E_INVALIDARG, dimensionsInPixels);
|
||||||
|
|
||||||
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
|
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
|
||||||
|
|
||||||
const auto viewInCharacters = Viewport::FromDimensions({ 0, 0 }, { (dimensionsInCharacters.X), (dimensionsInCharacters.Y) });
|
const auto viewInCharacters = Viewport::FromDimensions(dimensionsInCharacters);
|
||||||
const auto viewInPixels = publicTerminal->_renderEngine->GetViewportInPixels(viewInCharacters);
|
const auto viewInPixels = publicTerminal->_renderEngine->GetViewportInPixels(viewInCharacters);
|
||||||
|
|
||||||
dimensionsInPixels->cx = viewInPixels.Width();
|
dimensionsInPixels->cx = viewInPixels.Width();
|
||||||
dimensionsInPixels->cy = viewInPixels.Height();
|
dimensionsInPixels->cy = viewInPixels.Height();
|
||||||
|
|
||||||
COORD unused{ 0, 0 };
|
til::size unused;
|
||||||
|
|
||||||
return TerminalTriggerResize(terminal, viewInPixels.Width(), viewInPixels.Height(), &unused);
|
return TerminalTriggerResize(terminal, viewInPixels.Width(), viewInPixels.Height(), &unused);
|
||||||
}
|
}
|
||||||
@@ -484,7 +483,7 @@ HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ CO
|
|||||||
/// <param name="height">Height of the terminal area to calculate.</param>
|
/// <param name="height">Height of the terminal area to calculate.</param>
|
||||||
/// <param name="dimensions">Out parameter containing the columns and rows that fit the new size.</param>
|
/// <param name="dimensions">Out parameter containing the columns and rows that fit the new size.</param>
|
||||||
/// <returns>HRESULT of the calculation.</returns>
|
/// <returns>HRESULT of the calculation.</returns>
|
||||||
HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions)
|
HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions)
|
||||||
{
|
{
|
||||||
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
|
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
|
||||||
|
|
||||||
@@ -548,11 +547,11 @@ try
|
|||||||
|
|
||||||
if (multiClickMapper == 3)
|
if (multiClickMapper == 3)
|
||||||
{
|
{
|
||||||
_terminal->MultiClickSelection((cursorPosition / fontSize).to_win32_coord(), ::Terminal::SelectionExpansion::Line);
|
_terminal->MultiClickSelection(cursorPosition / fontSize, ::Terminal::SelectionExpansion::Line);
|
||||||
}
|
}
|
||||||
else if (multiClickMapper == 2)
|
else if (multiClickMapper == 2)
|
||||||
{
|
{
|
||||||
_terminal->MultiClickSelection((cursorPosition / fontSize).to_win32_coord(), ::Terminal::SelectionExpansion::Word);
|
_terminal->MultiClickSelection(cursorPosition / fontSize, ::Terminal::SelectionExpansion::Word);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -593,13 +592,13 @@ try
|
|||||||
|
|
||||||
if (distanceSquared >= maxDistanceSquared)
|
if (distanceSquared >= maxDistanceSquared)
|
||||||
{
|
{
|
||||||
_terminal->SetSelectionAnchor((touchdownPoint / fontSize).to_win32_coord());
|
_terminal->SetSelectionAnchor(touchdownPoint / fontSize);
|
||||||
// stop tracking the touchdown point
|
// stop tracking the touchdown point
|
||||||
_singleClickTouchdownPos = std::nullopt;
|
_singleClickTouchdownPos = std::nullopt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->_terminal->SetSelectionEnd((cursorPosition / fontSize).to_win32_coord());
|
this->_terminal->SetSelectionEnd(cursorPosition / fontSize);
|
||||||
this->_renderer->TriggerSelection();
|
this->_renderer->TriggerSelection();
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
@@ -701,9 +700,7 @@ try
|
|||||||
wheelDelta = HIWORD(wParam);
|
wheelDelta = HIWORD(wParam);
|
||||||
|
|
||||||
// If it's a *WHEEL event, it's in screen coordinates, not window (?!)
|
// If it's a *WHEEL event, it's in screen coordinates, not window (?!)
|
||||||
auto coordsToTransform = cursorPosition.to_win32_point();
|
ScreenToClient(_hwnd.get(), cursorPosition.as_win32_point());
|
||||||
ScreenToClient(_hwnd.get(), &coordsToTransform);
|
|
||||||
cursorPosition = til::point{ coordsToTransform };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const TerminalInput::MouseButtonState state{
|
const TerminalInput::MouseButtonState state{
|
||||||
@@ -712,7 +709,7 @@ try
|
|||||||
WI_IsFlagSet(GetKeyState(VK_RBUTTON), KeyPressed)
|
WI_IsFlagSet(GetKeyState(VK_RBUTTON), KeyPressed)
|
||||||
};
|
};
|
||||||
|
|
||||||
return _terminal->SendMouseEvent((cursorPosition / fontSize).to_win32_coord(), uMsg, getControlKeyState(), wheelDelta, state);
|
return _terminal->SendMouseEvent(cursorPosition / fontSize, uMsg, getControlKeyState(), wheelDelta, state);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
@@ -780,7 +777,7 @@ void _stdcall DestroyTerminal(void* terminal)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Updates the terminal font type, size, color, as well as the background/foreground colors to a specified theme.
|
// Updates the terminal font type, size, color, as well as the background/foreground colors to a specified theme.
|
||||||
void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, short fontSize, int newDpi)
|
void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, til::CoordType fontSize, int newDpi)
|
||||||
{
|
{
|
||||||
const auto publicTerminal = static_cast<HwndTerminal*>(terminal);
|
const auto publicTerminal = static_cast<HwndTerminal*>(terminal);
|
||||||
{
|
{
|
||||||
@@ -810,8 +807,8 @@ void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR font
|
|||||||
RECT windowRect;
|
RECT windowRect;
|
||||||
GetWindowRect(publicTerminal->_hwnd.get(), &windowRect);
|
GetWindowRect(publicTerminal->_hwnd.get(), &windowRect);
|
||||||
|
|
||||||
COORD dimensions = {};
|
til::size dimensions;
|
||||||
const SIZE windowSize{ windowRect.right - windowRect.left, windowRect.bottom - windowRect.top };
|
const til::size windowSize{ windowRect.right - windowRect.left, windowRect.bottom - windowRect.top };
|
||||||
publicTerminal->Refresh(windowSize, &dimensions);
|
publicTerminal->Refresh(windowSize, &dimensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -984,21 +981,21 @@ void HwndTerminal::_StringPaste(const wchar_t* const pData) noexcept
|
|||||||
CATCH_LOG();
|
CATCH_LOG();
|
||||||
}
|
}
|
||||||
|
|
||||||
COORD HwndTerminal::GetFontSize() const noexcept
|
til::size HwndTerminal::GetFontSize() const noexcept
|
||||||
{
|
{
|
||||||
return _actualFont.GetSize();
|
return _actualFont.GetSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
RECT HwndTerminal::GetBounds() const noexcept
|
til::rect HwndTerminal::GetBounds() const noexcept
|
||||||
{
|
{
|
||||||
RECT windowRect;
|
til::rect windowRect;
|
||||||
GetWindowRect(_hwnd.get(), &windowRect);
|
GetWindowRect(_hwnd.get(), windowRect.as_win32_rect());
|
||||||
return windowRect;
|
return windowRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
RECT HwndTerminal::GetPadding() const noexcept
|
til::rect HwndTerminal::GetPadding() const noexcept
|
||||||
{
|
{
|
||||||
return { 0 };
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
double HwndTerminal::GetScaleFactor() const noexcept
|
double HwndTerminal::GetScaleFactor() const noexcept
|
||||||
@@ -1006,7 +1003,7 @@ double HwndTerminal::GetScaleFactor() const noexcept
|
|||||||
return static_cast<double>(_currentDpi) / static_cast<double>(USER_DEFAULT_SCREEN_DPI);
|
return static_cast<double>(_currentDpi) / static_cast<double>(USER_DEFAULT_SCREEN_DPI);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HwndTerminal::ChangeViewport(const SMALL_RECT NewWindow)
|
void HwndTerminal::ChangeViewport(const til::inclusive_rect& NewWindow)
|
||||||
{
|
{
|
||||||
_terminal->UserScrollViewport(NewWindow.Top);
|
_terminal->UserScrollViewport(NewWindow.Top);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,16 +27,16 @@ extern "C" {
|
|||||||
__declspec(dllexport) HRESULT _stdcall CreateTerminal(HWND parentHwnd, _Out_ void** hwnd, _Out_ void** terminal);
|
__declspec(dllexport) HRESULT _stdcall CreateTerminal(HWND parentHwnd, _Out_ void** hwnd, _Out_ void** terminal);
|
||||||
__declspec(dllexport) void _stdcall TerminalSendOutput(void* terminal, LPCWSTR data);
|
__declspec(dllexport) void _stdcall TerminalSendOutput(void* terminal, LPCWSTR data);
|
||||||
__declspec(dllexport) void _stdcall TerminalRegisterScrollCallback(void* terminal, void __stdcall callback(int, int, int));
|
__declspec(dllexport) void _stdcall TerminalRegisterScrollCallback(void* terminal, void __stdcall callback(int, int, int));
|
||||||
__declspec(dllexport) HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions);
|
__declspec(dllexport) HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions);
|
||||||
__declspec(dllexport) HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ COORD dimensions, _Out_ SIZE* dimensionsInPixels);
|
__declspec(dllexport) HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ til::size dimensions, _Out_ til::size* dimensionsInPixels);
|
||||||
__declspec(dllexport) HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions);
|
__declspec(dllexport) HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions);
|
||||||
__declspec(dllexport) void _stdcall TerminalDpiChanged(void* terminal, int newDpi);
|
__declspec(dllexport) void _stdcall TerminalDpiChanged(void* terminal, int newDpi);
|
||||||
__declspec(dllexport) void _stdcall TerminalUserScroll(void* terminal, int viewTop);
|
__declspec(dllexport) void _stdcall TerminalUserScroll(void* terminal, int viewTop);
|
||||||
__declspec(dllexport) void _stdcall TerminalClearSelection(void* terminal);
|
__declspec(dllexport) void _stdcall TerminalClearSelection(void* terminal);
|
||||||
__declspec(dllexport) const wchar_t* _stdcall TerminalGetSelection(void* terminal);
|
__declspec(dllexport) const wchar_t* _stdcall TerminalGetSelection(void* terminal);
|
||||||
__declspec(dllexport) bool _stdcall TerminalIsSelectionActive(void* terminal);
|
__declspec(dllexport) bool _stdcall TerminalIsSelectionActive(void* terminal);
|
||||||
__declspec(dllexport) void _stdcall DestroyTerminal(void* terminal);
|
__declspec(dllexport) void _stdcall DestroyTerminal(void* terminal);
|
||||||
__declspec(dllexport) void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, short fontSize, int newDpi);
|
__declspec(dllexport) void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, til::CoordType fontSize, int newDpi);
|
||||||
__declspec(dllexport) void _stdcall TerminalRegisterWriteCallback(void* terminal, const void __stdcall callback(wchar_t*));
|
__declspec(dllexport) void _stdcall TerminalRegisterWriteCallback(void* terminal, const void __stdcall callback(wchar_t*));
|
||||||
__declspec(dllexport) void _stdcall TerminalSendKeyEvent(void* terminal, WORD vkey, WORD scanCode, WORD flags, bool keyDown);
|
__declspec(dllexport) void _stdcall TerminalSendKeyEvent(void* terminal, WORD vkey, WORD scanCode, WORD flags, bool keyDown);
|
||||||
__declspec(dllexport) void _stdcall TerminalSendCharEvent(void* terminal, wchar_t ch, WORD flags, WORD scanCode);
|
__declspec(dllexport) void _stdcall TerminalSendCharEvent(void* terminal, wchar_t ch, WORD flags, WORD scanCode);
|
||||||
@@ -60,7 +60,7 @@ public:
|
|||||||
HRESULT Initialize();
|
HRESULT Initialize();
|
||||||
void Teardown() noexcept;
|
void Teardown() noexcept;
|
||||||
void SendOutput(std::wstring_view data);
|
void SendOutput(std::wstring_view data);
|
||||||
HRESULT Refresh(const SIZE windowSize, _Out_ COORD* dimensions);
|
HRESULT Refresh(const til::size windowSize, _Out_ til::size* dimensions);
|
||||||
void RegisterScrollCallback(std::function<void(int, int, int)> callback);
|
void RegisterScrollCallback(std::function<void(int, int, int)> callback);
|
||||||
void RegisterWriteCallback(const void _stdcall callback(wchar_t*));
|
void RegisterWriteCallback(const void _stdcall callback(wchar_t*));
|
||||||
::Microsoft::Console::Types::IUiaData* GetUiaData() const noexcept;
|
::Microsoft::Console::Types::IUiaData* GetUiaData() const noexcept;
|
||||||
@@ -91,9 +91,9 @@ private:
|
|||||||
std::optional<til::point> _singleClickTouchdownPos;
|
std::optional<til::point> _singleClickTouchdownPos;
|
||||||
|
|
||||||
friend HRESULT _stdcall CreateTerminal(HWND parentHwnd, _Out_ void** hwnd, _Out_ void** terminal);
|
friend HRESULT _stdcall CreateTerminal(HWND parentHwnd, _Out_ void** hwnd, _Out_ void** terminal);
|
||||||
friend HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions);
|
friend HRESULT _stdcall TerminalTriggerResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions);
|
||||||
friend HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ COORD dimensions, _Out_ SIZE* dimensionsInPixels);
|
friend HRESULT _stdcall TerminalTriggerResizeWithDimension(_In_ void* terminal, _In_ til::size dimensions, _Out_ til::size* dimensionsInPixels);
|
||||||
friend HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ short width, _In_ short height, _Out_ COORD* dimensions);
|
friend HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions);
|
||||||
friend void _stdcall TerminalDpiChanged(void* terminal, int newDpi);
|
friend void _stdcall TerminalDpiChanged(void* terminal, int newDpi);
|
||||||
friend void _stdcall TerminalUserScroll(void* terminal, int viewTop);
|
friend void _stdcall TerminalUserScroll(void* terminal, int viewTop);
|
||||||
friend void _stdcall TerminalClearSelection(void* terminal);
|
friend void _stdcall TerminalClearSelection(void* terminal);
|
||||||
@@ -101,7 +101,7 @@ private:
|
|||||||
friend bool _stdcall TerminalIsSelectionActive(void* terminal);
|
friend bool _stdcall TerminalIsSelectionActive(void* terminal);
|
||||||
friend void _stdcall TerminalSendKeyEvent(void* terminal, WORD vkey, WORD scanCode, WORD flags, bool keyDown);
|
friend void _stdcall TerminalSendKeyEvent(void* terminal, WORD vkey, WORD scanCode, WORD flags, bool keyDown);
|
||||||
friend void _stdcall TerminalSendCharEvent(void* terminal, wchar_t ch, WORD scanCode, WORD flags);
|
friend void _stdcall TerminalSendCharEvent(void* terminal, wchar_t ch, WORD scanCode, WORD flags);
|
||||||
friend void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, short fontSize, int newDpi);
|
friend void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, til::CoordType fontSize, int newDpi);
|
||||||
friend void _stdcall TerminalBlinkCursor(void* terminal);
|
friend void _stdcall TerminalBlinkCursor(void* terminal);
|
||||||
friend void _stdcall TerminalSetCursorVisible(void* terminal, const bool visible);
|
friend void _stdcall TerminalSetCursorVisible(void* terminal, const bool visible);
|
||||||
friend void _stdcall TerminalSetFocus(void* terminal);
|
friend void _stdcall TerminalSetFocus(void* terminal);
|
||||||
@@ -128,10 +128,10 @@ private:
|
|||||||
void _SendCharEvent(wchar_t ch, WORD scanCode, WORD flags) noexcept;
|
void _SendCharEvent(wchar_t ch, WORD scanCode, WORD flags) noexcept;
|
||||||
|
|
||||||
// Inherited via IControlAccessibilityInfo
|
// Inherited via IControlAccessibilityInfo
|
||||||
COORD GetFontSize() const noexcept override;
|
til::size GetFontSize() const noexcept override;
|
||||||
RECT GetBounds() const noexcept override;
|
til::rect GetBounds() const noexcept override;
|
||||||
double GetScaleFactor() const noexcept override;
|
double GetScaleFactor() const noexcept override;
|
||||||
void ChangeViewport(const SMALL_RECT NewWindow) override;
|
void ChangeViewport(const til::inclusive_rect& NewWindow) override;
|
||||||
HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) noexcept override;
|
HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) noexcept override;
|
||||||
RECT GetPadding() const noexcept override;
|
til::rect GetPadding() const noexcept override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1084,8 +1084,8 @@ namespace winrt::TerminalApp::implementation
|
|||||||
L".",
|
L".",
|
||||||
L"Azure",
|
L"Azure",
|
||||||
nullptr,
|
nullptr,
|
||||||
::base::saturated_cast<uint32_t>(settings.InitialRows()),
|
settings.InitialRows(),
|
||||||
::base::saturated_cast<uint32_t>(settings.InitialCols()),
|
settings.InitialCols(),
|
||||||
winrt::guid());
|
winrt::guid());
|
||||||
|
|
||||||
if constexpr (Feature_VtPassthroughMode::IsEnabled())
|
if constexpr (Feature_VtPassthroughMode::IsEnabled())
|
||||||
@@ -1135,8 +1135,8 @@ namespace winrt::TerminalApp::implementation
|
|||||||
newWorkingDirectory,
|
newWorkingDirectory,
|
||||||
settings.StartingTitle(),
|
settings.StartingTitle(),
|
||||||
envMap.GetView(),
|
envMap.GetView(),
|
||||||
::base::saturated_cast<uint32_t>(settings.InitialRows()),
|
settings.InitialRows(),
|
||||||
::base::saturated_cast<uint32_t>(settings.InitialCols()),
|
settings.InitialCols(),
|
||||||
winrt::guid());
|
winrt::guid());
|
||||||
|
|
||||||
valueSet.Insert(L"passthroughMode", Windows::Foundation::PropertyValue::CreateBoolean(settings.VtPassthrough()));
|
valueSet.Insert(L"passthroughMode", Windows::Foundation::PropertyValue::CreateBoolean(settings.VtPassthrough()));
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ using namespace winrt;
|
|||||||
using namespace winrt::Windows::Foundation;
|
using namespace winrt::Windows::Foundation;
|
||||||
using namespace winrt::Microsoft::Terminal::TerminalConnection;
|
using namespace winrt::Microsoft::Terminal::TerminalConnection;
|
||||||
|
|
||||||
static COORD GetConsoleScreenSize(HANDLE outputHandle)
|
static til::point GetConsoleScreenSize(HANDLE outputHandle)
|
||||||
{
|
{
|
||||||
CONSOLE_SCREEN_BUFFER_INFOEX csbiex{};
|
CONSOLE_SCREEN_BUFFER_INFOEX csbiex{};
|
||||||
csbiex.cbSize = sizeof(csbiex);
|
csbiex.cbSize = sizeof(csbiex);
|
||||||
|
|||||||
@@ -75,8 +75,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|||||||
{
|
{
|
||||||
if (settings)
|
if (settings)
|
||||||
{
|
{
|
||||||
_initialRows = winrt::unbox_value_or<uint32_t>(settings.TryLookup(L"initialRows").try_as<Windows::Foundation::IPropertyValue>(), _initialRows);
|
_initialRows = gsl::narrow<til::CoordType>(winrt::unbox_value_or<uint32_t>(settings.TryLookup(L"initialRows").try_as<Windows::Foundation::IPropertyValue>(), _initialRows));
|
||||||
_initialCols = winrt::unbox_value_or<uint32_t>(settings.TryLookup(L"initialCols").try_as<Windows::Foundation::IPropertyValue>(), _initialCols);
|
_initialCols = gsl::narrow<til::CoordType>(winrt::unbox_value_or<uint32_t>(settings.TryLookup(L"initialCols").try_as<Windows::Foundation::IPropertyValue>(), _initialCols));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|||||||
WINRT_CALLBACK(TerminalOutput, TerminalOutputHandler);
|
WINRT_CALLBACK(TerminalOutput, TerminalOutputHandler);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t _initialRows{};
|
til::CoordType _initialRows{};
|
||||||
uint32_t _initialCols{};
|
til::CoordType _initialCols{};
|
||||||
|
|
||||||
enum class AzureState
|
enum class AzureState
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -293,7 +293,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|||||||
{
|
{
|
||||||
_transitionToState(ConnectionState::Connecting);
|
_transitionToState(ConnectionState::Connecting);
|
||||||
|
|
||||||
const COORD dimensions{ gsl::narrow_cast<SHORT>(_initialCols), gsl::narrow_cast<SHORT>(_initialRows) };
|
const til::size dimensions{ gsl::narrow<til::CoordType>(_initialCols), gsl::narrow<til::CoordType>(_initialRows) };
|
||||||
|
|
||||||
// If we do not have pipes already, then this is a fresh connection... not an inbound one that is a received
|
// If we do not have pipes already, then this is a fresh connection... not an inbound one that is a received
|
||||||
// handoff from an already-started PTY process.
|
// handoff from an already-started PTY process.
|
||||||
@@ -309,7 +309,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
THROW_IF_FAILED(_CreatePseudoConsoleAndPipes(dimensions, flags, &_inPipe, &_outPipe, &_hPC));
|
THROW_IF_FAILED(_CreatePseudoConsoleAndPipes(til::unwrap_coord_size(dimensions), flags, &_inPipe, &_outPipe, &_hPC));
|
||||||
|
|
||||||
if (_initialParentHwnd != 0)
|
if (_initialParentHwnd != 0)
|
||||||
{
|
{
|
||||||
@@ -338,7 +338,7 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|||||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||||
TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance));
|
TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance));
|
||||||
|
|
||||||
THROW_IF_FAILED(ConptyResizePseudoConsole(_hPC.get(), dimensions));
|
THROW_IF_FAILED(ConptyResizePseudoConsole(_hPC.get(), til::unwrap_coord_size(dimensions)));
|
||||||
THROW_IF_FAILED(ConptyReparentPseudoConsole(_hPC.get(), reinterpret_cast<HWND>(_initialParentHwnd)));
|
THROW_IF_FAILED(ConptyReparentPseudoConsole(_hPC.get(), reinterpret_cast<HWND>(_initialParentHwnd)));
|
||||||
|
|
||||||
if (_initialVisibility)
|
if (_initialVisibility)
|
||||||
|
|||||||
@@ -67,8 +67,8 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
|||||||
void _indicateExitWithStatus(unsigned int status) noexcept;
|
void _indicateExitWithStatus(unsigned int status) noexcept;
|
||||||
void _ClientTerminated() noexcept;
|
void _ClientTerminated() noexcept;
|
||||||
|
|
||||||
uint32_t _initialRows{};
|
til::CoordType _initialRows{};
|
||||||
uint32_t _initialCols{};
|
til::CoordType _initialCols{};
|
||||||
uint64_t _initialParentHwnd{ 0 };
|
uint64_t _initialParentHwnd{ 0 };
|
||||||
hstring _commandline{};
|
hstring _commandline{};
|
||||||
hstring _startingDirectory{};
|
hstring _startingDirectory{};
|
||||||
|
|||||||
@@ -250,8 +250,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
// and react accordingly.
|
// and react accordingly.
|
||||||
_updateFont(true);
|
_updateFont(true);
|
||||||
|
|
||||||
const COORD windowSize{ static_cast<short>(windowWidth),
|
const til::size windowSize{ static_cast<til::CoordType>(windowWidth),
|
||||||
static_cast<short>(windowHeight) };
|
static_cast<til::CoordType>(windowHeight) };
|
||||||
|
|
||||||
// First set up the dx engine with the window size in pixels.
|
// First set up the dx engine with the window size in pixels.
|
||||||
// Then, using the font, get the number of characters that can fit.
|
// Then, using the font, get the number of characters that can fit.
|
||||||
@@ -444,7 +444,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
const short wheelDelta,
|
const short wheelDelta,
|
||||||
const TerminalInput::MouseButtonState state)
|
const TerminalInput::MouseButtonState state)
|
||||||
{
|
{
|
||||||
return _terminal->SendMouseEvent(viewportPos.to_win32_coord(), uiButton, states, wheelDelta, state);
|
return _terminal->SendMouseEvent(viewportPos, uiButton, states, wheelDelta, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControlCore::UserScrollViewport(const int viewTop)
|
void ControlCore::UserScrollViewport(const int viewTop)
|
||||||
@@ -568,12 +568,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
_lastHoveredCell = terminalPosition;
|
_lastHoveredCell = terminalPosition;
|
||||||
uint16_t newId{ 0u };
|
uint16_t newId{ 0u };
|
||||||
// we can't use auto here because we're pre-declaring newInterval.
|
// we can't use auto here because we're pre-declaring newInterval.
|
||||||
decltype(_terminal->GetHyperlinkIntervalFromPosition(COORD{})) newInterval{ std::nullopt };
|
decltype(_terminal->GetHyperlinkIntervalFromPosition({})) newInterval{ std::nullopt };
|
||||||
if (terminalPosition.has_value())
|
if (terminalPosition.has_value())
|
||||||
{
|
{
|
||||||
auto lock = _terminal->LockForReading(); // Lock for the duration of our reads.
|
auto lock = _terminal->LockForReading(); // Lock for the duration of our reads.
|
||||||
newId = _terminal->GetHyperlinkIdAtPosition(terminalPosition->to_win32_coord());
|
newId = _terminal->GetHyperlinkIdAtPosition(*terminalPosition);
|
||||||
newInterval = _terminal->GetHyperlinkIntervalFromPosition(terminalPosition->to_win32_coord());
|
newInterval = _terminal->GetHyperlinkIntervalFromPosition(*terminalPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the hyperlink ID changed or the interval changed, trigger a redraw all
|
// If the hyperlink ID changed or the interval changed, trigger a redraw all
|
||||||
@@ -603,7 +603,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
{
|
{
|
||||||
// Lock for the duration of our reads.
|
// Lock for the duration of our reads.
|
||||||
auto lock = _terminal->LockForReading();
|
auto lock = _terminal->LockForReading();
|
||||||
return winrt::hstring{ _terminal->GetHyperlinkAtPosition(til::point{ pos }.to_win32_coord()) };
|
return winrt::hstring{ _terminal->GetHyperlinkAtPosition(til::point{ pos }) };
|
||||||
}
|
}
|
||||||
|
|
||||||
winrt::hstring ControlCore::HoveredUriText() const
|
winrt::hstring ControlCore::HoveredUriText() const
|
||||||
@@ -611,7 +611,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
auto lock = _terminal->LockForReading(); // Lock for the duration of our reads.
|
auto lock = _terminal->LockForReading(); // Lock for the duration of our reads.
|
||||||
if (_lastHoveredCell.has_value())
|
if (_lastHoveredCell.has_value())
|
||||||
{
|
{
|
||||||
return winrt::hstring{ _terminal->GetHyperlinkAtPosition(_lastHoveredCell->to_win32_coord()) };
|
return winrt::hstring{ _terminal->GetHyperlinkAtPosition(*_lastHoveredCell) };
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -781,7 +781,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
bool ControlCore::_setFontSizeUnderLock(int fontSize)
|
bool ControlCore::_setFontSizeUnderLock(int fontSize)
|
||||||
{
|
{
|
||||||
// Make sure we have a non-zero font size
|
// Make sure we have a non-zero font size
|
||||||
const auto newSize = std::max<short>(gsl::narrow_cast<short>(fontSize), 1);
|
const auto newSize = std::max(fontSize, 1);
|
||||||
const auto fontFace = _settings->FontFace();
|
const auto fontFace = _settings->FontFace();
|
||||||
const auto fontWeight = _settings->FontWeight();
|
const auto fontWeight = _settings->FontWeight();
|
||||||
_actualFont = { fontFace, 0, fontWeight.Weight, { 0, newSize }, CP_UTF8, false };
|
_actualFont = { fontFace, 0, fontWeight.Weight, { 0, newSize }, CP_UTF8, false };
|
||||||
@@ -837,8 +837,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
// - <none>
|
// - <none>
|
||||||
void ControlCore::_refreshSizeUnderLock()
|
void ControlCore::_refreshSizeUnderLock()
|
||||||
{
|
{
|
||||||
auto cx = gsl::narrow_cast<short>(_panelWidth * _compositionScale);
|
auto cx = gsl::narrow_cast<til::CoordType>(_panelWidth * _compositionScale);
|
||||||
auto cy = gsl::narrow_cast<short>(_panelHeight * _compositionScale);
|
auto cy = gsl::narrow_cast<til::CoordType>(_panelHeight * _compositionScale);
|
||||||
|
|
||||||
// Don't actually resize so small that a single character wouldn't fit
|
// Don't actually resize so small that a single character wouldn't fit
|
||||||
// in either dimension. The buffer really doesn't like being size 0.
|
// in either dimension. The buffer really doesn't like being size 0.
|
||||||
@@ -906,17 +906,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
_refreshSizeUnderLock();
|
_refreshSizeUnderLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControlCore::SetSelectionAnchor(const til::point& position)
|
void ControlCore::SetSelectionAnchor(const til::point position)
|
||||||
{
|
{
|
||||||
auto lock = _terminal->LockForWriting();
|
auto lock = _terminal->LockForWriting();
|
||||||
_terminal->SetSelectionAnchor(position.to_win32_coord());
|
_terminal->SetSelectionAnchor(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Sets selection's end position to match supplied cursor position, e.g. while mouse dragging.
|
// - Sets selection's end position to match supplied cursor position, e.g. while mouse dragging.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - position: the point in terminal coordinates (in cells, not pixels)
|
// - position: the point in terminal coordinates (in cells, not pixels)
|
||||||
void ControlCore::SetEndSelectionPoint(const til::point& position)
|
void ControlCore::SetEndSelectionPoint(const til::point position)
|
||||||
{
|
{
|
||||||
if (!_terminal->IsSelectionActive())
|
if (!_terminal->IsSelectionActive())
|
||||||
{
|
{
|
||||||
@@ -933,7 +933,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
};
|
};
|
||||||
|
|
||||||
// save location (for rendering) + render
|
// save location (for rendering) + render
|
||||||
_terminal->SetSelectionEnd(terminalPosition.to_win32_coord());
|
_terminal->SetSelectionEnd(terminalPosition);
|
||||||
_renderer->TriggerSelection();
|
_renderer->TriggerSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1488,7 +1488,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto lock = _terminal->LockForReading();
|
auto lock = _terminal->LockForReading();
|
||||||
return til::point{ _terminal->GetCursorPosition() }.to_core_point();
|
return _terminal->GetCursorPosition().to_core_point();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This one's really pushing the boundary of what counts as "encapsulation".
|
// This one's really pushing the boundary of what counts as "encapsulation".
|
||||||
@@ -1540,7 +1540,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
{
|
{
|
||||||
// If shift is pressed and there is a selection we extend it using
|
// If shift is pressed and there is a selection we extend it using
|
||||||
// the selection mode (expand the "end" selection point)
|
// the selection mode (expand the "end" selection point)
|
||||||
_terminal->SetSelectionEnd(terminalPosition.to_win32_coord(), mode);
|
_terminal->SetSelectionEnd(terminalPosition, mode);
|
||||||
selectionNeedsToBeCopied = true;
|
selectionNeedsToBeCopied = true;
|
||||||
}
|
}
|
||||||
else if (mode != ::Terminal::SelectionExpansion::Char || shiftEnabled)
|
else if (mode != ::Terminal::SelectionExpansion::Char || shiftEnabled)
|
||||||
@@ -1548,7 +1548,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
// If we are handling a double / triple-click or shift+single click
|
// If we are handling a double / triple-click or shift+single click
|
||||||
// we establish selection using the selected mode
|
// we establish selection using the selected mode
|
||||||
// (expand both "start" and "end" selection points)
|
// (expand both "start" and "end" selection points)
|
||||||
_terminal->MultiClickSelection(terminalPosition.to_win32_coord(), mode);
|
_terminal->MultiClickSelection(terminalPosition, mode);
|
||||||
selectionNeedsToBeCopied = true;
|
selectionNeedsToBeCopied = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -151,8 +151,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
bool HasSelection() const;
|
bool HasSelection() const;
|
||||||
bool CopyOnSelect() const;
|
bool CopyOnSelect() const;
|
||||||
Windows::Foundation::Collections::IVector<winrt::hstring> SelectedText(bool trimTrailingWhitespace) const;
|
Windows::Foundation::Collections::IVector<winrt::hstring> SelectedText(bool trimTrailingWhitespace) const;
|
||||||
void SetSelectionAnchor(const til::point& position);
|
void SetSelectionAnchor(const til::point position);
|
||||||
void SetEndSelectionPoint(const til::point& position);
|
void SetEndSelectionPoint(const til::point position);
|
||||||
|
|
||||||
void Search(const winrt::hstring& text,
|
void Search(const winrt::hstring& text,
|
||||||
const bool goForward,
|
const bool goForward,
|
||||||
|
|||||||
@@ -615,7 +615,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
// Get the size of the font, which is in pixels
|
// Get the size of the font, which is in pixels
|
||||||
const til::size fontSize{ _core->GetFont().GetSize() };
|
const til::size fontSize{ _core->GetFont().GetSize() };
|
||||||
// Convert the location in pixels to characters within the current viewport.
|
// Convert the location in pixels to characters within the current viewport.
|
||||||
return til::point{ pixelPosition / fontSize };
|
return pixelPosition / fontSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ControlInteractivity::_sendMouseEventHelper(const til::point terminalPosition,
|
bool ControlInteractivity::_sendMouseEventHelper(const til::point terminalPosition,
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
// terminal.
|
// terminal.
|
||||||
bool _selectionNeedsToBeCopied;
|
bool _selectionNeedsToBeCopied;
|
||||||
|
|
||||||
std::optional<COORD> _lastHoveredCell{ std::nullopt };
|
std::optional<til::point> _lastHoveredCell{ std::nullopt };
|
||||||
// Track the last hyperlink ID we hovered over
|
// Track the last hyperlink ID we hovered over
|
||||||
uint16_t _lastHoveredId{ 0 };
|
uint16_t _lastHoveredId{ 0 };
|
||||||
|
|
||||||
|
|||||||
@@ -146,14 +146,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
#pragma region IControlAccessibilityInfo
|
#pragma region IControlAccessibilityInfo
|
||||||
COORD InteractivityAutomationPeer::GetFontSize() const noexcept
|
til::size InteractivityAutomationPeer::GetFontSize() const noexcept
|
||||||
{
|
{
|
||||||
return til::size{ til::math::rounding, _interactivity->Core().FontSize() }.to_win32_coord();
|
return { til::math::rounding, _interactivity->Core().FontSize() };
|
||||||
}
|
}
|
||||||
|
|
||||||
RECT InteractivityAutomationPeer::GetBounds() const noexcept
|
til::rect InteractivityAutomationPeer::GetBounds() const noexcept
|
||||||
{
|
{
|
||||||
return _controlBounds.to_win32_rect();
|
return _controlBounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT InteractivityAutomationPeer::GetHostUiaProvider(IRawElementProviderSimple** provider)
|
HRESULT InteractivityAutomationPeer::GetHostUiaProvider(IRawElementProviderSimple** provider)
|
||||||
@@ -164,9 +164,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
RECT InteractivityAutomationPeer::GetPadding() const noexcept
|
til::rect InteractivityAutomationPeer::GetPadding() const noexcept
|
||||||
{
|
{
|
||||||
return _controlPadding.to_win32_rect();
|
return _controlPadding;
|
||||||
}
|
}
|
||||||
|
|
||||||
double InteractivityAutomationPeer::GetScaleFactor() const noexcept
|
double InteractivityAutomationPeer::GetScaleFactor() const noexcept
|
||||||
@@ -174,7 +174,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
return DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel();
|
return DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InteractivityAutomationPeer::ChangeViewport(const SMALL_RECT NewWindow)
|
void InteractivityAutomationPeer::ChangeViewport(const til::inclusive_rect& NewWindow)
|
||||||
{
|
{
|
||||||
_interactivity->UpdateScrollbar(NewWindow.Top);
|
_interactivity->UpdateScrollbar(NewWindow.Top);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,11 +63,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
|
|
||||||
#pragma region IControlAccessibilityInfo Pattern
|
#pragma region IControlAccessibilityInfo Pattern
|
||||||
// Inherited via IControlAccessibilityInfo
|
// Inherited via IControlAccessibilityInfo
|
||||||
virtual COORD GetFontSize() const noexcept override;
|
virtual til::size GetFontSize() const noexcept override;
|
||||||
virtual RECT GetBounds() const noexcept override;
|
virtual til::rect GetBounds() const noexcept override;
|
||||||
virtual RECT GetPadding() const noexcept override;
|
virtual til::rect GetPadding() const noexcept override;
|
||||||
virtual double GetScaleFactor() const noexcept override;
|
virtual double GetScaleFactor() const noexcept override;
|
||||||
virtual void ChangeViewport(SMALL_RECT NewWindow) override;
|
virtual void ChangeViewport(const til::inclusive_rect& NewWindow) override;
|
||||||
virtual HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) override;
|
virtual HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) override;
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
|
|||||||
@@ -637,7 +637,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
// clever way around asking the core for this.
|
// clever way around asking the core for this.
|
||||||
til::point TermControl::GetFontSize() const
|
til::point TermControl::GetFontSize() const
|
||||||
{
|
{
|
||||||
return til::point{ til::math::rounding, _core.FontSize().Width, _core.FontSize().Height };
|
return { til::math::rounding, _core.FontSize().Width, _core.FontSize().Height };
|
||||||
}
|
}
|
||||||
|
|
||||||
const Windows::UI::Xaml::Thickness TermControl::GetPadding()
|
const Windows::UI::Xaml::Thickness TermControl::GetPadding()
|
||||||
@@ -1969,7 +1969,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
// The family is only used to determine if the font is truetype or
|
// The family is only used to determine if the font is truetype or
|
||||||
// not, but DX doesn't use that info at all.
|
// not, but DX doesn't use that info at all.
|
||||||
// The Codepage is additionally not actually used by the DX engine at all.
|
// The Codepage is additionally not actually used by the DX engine at all.
|
||||||
FontInfo actualFont = { fontFace, 0, fontWeight.Weight, { 0, gsl::narrow_cast<short>(fontSize) }, CP_UTF8, false };
|
FontInfo actualFont = { fontFace, 0, fontWeight.Weight, { 0, fontSize }, CP_UTF8, false };
|
||||||
FontInfoDesired desiredFont = { actualFont };
|
FontInfoDesired desiredFont = { actualFont };
|
||||||
|
|
||||||
// Create a DX engine and initialize it with our font and DPI. We'll
|
// Create a DX engine and initialize it with our font and DPI. We'll
|
||||||
|
|||||||
@@ -17,10 +17,10 @@ namespace Microsoft::Terminal::Core
|
|||||||
ITerminalInput& operator=(ITerminalInput&&) = default;
|
ITerminalInput& operator=(ITerminalInput&&) = default;
|
||||||
|
|
||||||
virtual bool SendKeyEvent(const WORD vkey, const WORD scanCode, const ControlKeyStates states, const bool keyDown) = 0;
|
virtual bool SendKeyEvent(const WORD vkey, const WORD scanCode, const ControlKeyStates states, const bool keyDown) = 0;
|
||||||
virtual bool SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state) = 0;
|
virtual bool SendMouseEvent(const til::point viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state) = 0;
|
||||||
virtual bool SendCharEvent(const wchar_t ch, const WORD scanCode, const ControlKeyStates states) = 0;
|
virtual bool SendCharEvent(const wchar_t ch, const WORD scanCode, const ControlKeyStates states) = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual HRESULT UserResize(const COORD size) noexcept = 0;
|
[[nodiscard]] virtual HRESULT UserResize(const til::size size) noexcept = 0;
|
||||||
virtual void UserScrollViewport(const int viewTop) = 0;
|
virtual void UserScrollViewport(const int viewTop) = 0;
|
||||||
virtual int GetScrollOffset() = 0;
|
virtual int GetScrollOffset() = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -66,12 +66,12 @@ Terminal::Terminal() :
|
|||||||
_renderSettings.SetColorAlias(ColorAlias::DefaultBackground, TextColor::DEFAULT_BACKGROUND, RGB(0, 0, 0));
|
_renderSettings.SetColorAlias(ColorAlias::DefaultBackground, TextColor::DEFAULT_BACKGROUND, RGB(0, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Terminal::Create(COORD viewportSize, SHORT scrollbackLines, Renderer& renderer)
|
void Terminal::Create(til::size viewportSize, til::CoordType scrollbackLines, Renderer& renderer)
|
||||||
{
|
{
|
||||||
_mutableViewport = Viewport::FromDimensions({ 0, 0 }, viewportSize);
|
_mutableViewport = Viewport::FromDimensions({ 0, 0 }, viewportSize);
|
||||||
_scrollbackLines = scrollbackLines;
|
_scrollbackLines = scrollbackLines;
|
||||||
const COORD bufferSize{ viewportSize.X,
|
const til::size bufferSize{ viewportSize.X,
|
||||||
Utils::ClampToShortMax(viewportSize.Y + scrollbackLines, 1) };
|
Utils::ClampToShortMax(viewportSize.Y + 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);
|
||||||
@@ -97,8 +97,8 @@ void Terminal::Create(COORD viewportSize, SHORT scrollbackLines, Renderer& rende
|
|||||||
void Terminal::CreateFromSettings(ICoreSettings settings,
|
void Terminal::CreateFromSettings(ICoreSettings settings,
|
||||||
Renderer& renderer)
|
Renderer& renderer)
|
||||||
{
|
{
|
||||||
const COORD viewportSize{ Utils::ClampToShortMax(settings.InitialCols(), 1),
|
const til::size viewportSize{ Utils::ClampToShortMax(settings.InitialCols(), 1),
|
||||||
Utils::ClampToShortMax(settings.InitialRows(), 1) };
|
Utils::ClampToShortMax(settings.InitialRows(), 1) };
|
||||||
|
|
||||||
// TODO:MSFT:20642297 - Support infinite scrollback here, if HistorySize is -1
|
// TODO:MSFT:20642297 - Support infinite scrollback here, if HistorySize is -1
|
||||||
Create(viewportSize, Utils::ClampToShortMax(settings.HistorySize(), 0), renderer);
|
Create(viewportSize, Utils::ClampToShortMax(settings.HistorySize(), 0), renderer);
|
||||||
@@ -243,7 +243,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
|
|||||||
// - S_OK if we successfully resized the terminal, S_FALSE if there was
|
// - S_OK if we successfully resized the terminal, S_FALSE if there was
|
||||||
// nothing to do (the viewportSize is the same as our current size), or an
|
// nothing to do (the viewportSize is the same as our current size), or an
|
||||||
// appropriate HRESULT for failing to resize.
|
// appropriate HRESULT for failing to resize.
|
||||||
[[nodiscard]] HRESULT Terminal::UserResize(const COORD viewportSize) noexcept
|
[[nodiscard]] HRESULT Terminal::UserResize(const til::size viewportSize) noexcept
|
||||||
{
|
{
|
||||||
const auto oldDimensions = _GetMutableViewport().Dimensions();
|
const auto oldDimensions = _GetMutableViewport().Dimensions();
|
||||||
if (viewportSize == oldDimensions)
|
if (viewportSize == oldDimensions)
|
||||||
@@ -258,7 +258,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
|
|||||||
if (_inAltBuffer())
|
if (_inAltBuffer())
|
||||||
{
|
{
|
||||||
// stash this resize for the future.
|
// stash this resize for the future.
|
||||||
_deferredResize = til::size{ viewportSize };
|
_deferredResize = viewportSize;
|
||||||
|
|
||||||
_altBuffer->GetCursor().StartDeferDrawing();
|
_altBuffer->GetCursor().StartDeferDrawing();
|
||||||
// we're capturing `this` here because when we exit, we want to EndDefer on the (newly created) active buffer.
|
// we're capturing `this` here because when we exit, we want to EndDefer on the (newly created) active buffer.
|
||||||
@@ -273,19 +273,19 @@ std::wstring_view Terminal::GetWorkingDirectory()
|
|||||||
// Since the _mutableViewport is no longer the size of the actual
|
// Since the _mutableViewport is no longer the size of the actual
|
||||||
// viewport, then update our _altBufferSize tracker we're using to help
|
// viewport, then update our _altBufferSize tracker we're using to help
|
||||||
// us out here.
|
// us out here.
|
||||||
_altBufferSize = til::size{ viewportSize };
|
_altBufferSize = viewportSize;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto dx = ::base::ClampSub(viewportSize.X, oldDimensions.X);
|
const auto dx = viewportSize.X - oldDimensions.X;
|
||||||
const short newBufferHeight = ::base::ClampAdd(viewportSize.Y, _scrollbackLines);
|
const auto newBufferHeight = std::clamp(viewportSize.Y + _scrollbackLines, 0, SHRT_MAX);
|
||||||
|
|
||||||
COORD bufferSize{ viewportSize.X, newBufferHeight };
|
til::size bufferSize{ viewportSize.X, newBufferHeight };
|
||||||
|
|
||||||
// This will be used to determine where the viewport should be in the new buffer.
|
// This will be used to determine where the viewport should be in the new buffer.
|
||||||
const auto oldViewportTop = _mutableViewport.Top();
|
const auto oldViewportTop = _mutableViewport.Top();
|
||||||
auto newViewportTop = oldViewportTop;
|
auto newViewportTop = oldViewportTop;
|
||||||
auto newVisibleTop = ::base::saturated_cast<short>(_VisibleStartIndex());
|
auto newVisibleTop = _VisibleStartIndex();
|
||||||
|
|
||||||
// If the original buffer had _no_ scroll offset, then we should be at the
|
// If the original buffer had _no_ scroll offset, then we should be at the
|
||||||
// bottom in the new buffer as well. Track that case now.
|
// bottom in the new buffer as well. Track that case now.
|
||||||
@@ -329,7 +329,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
|
|||||||
oldRows.mutableViewportTop = oldViewportTop;
|
oldRows.mutableViewportTop = oldViewportTop;
|
||||||
oldRows.visibleViewportTop = newVisibleTop;
|
oldRows.visibleViewportTop = newVisibleTop;
|
||||||
|
|
||||||
const std::optional<short> oldViewStart{ oldViewportTop };
|
const std::optional oldViewStart{ oldViewportTop };
|
||||||
RETURN_IF_FAILED(TextBuffer::Reflow(*_mainBuffer.get(),
|
RETURN_IF_FAILED(TextBuffer::Reflow(*_mainBuffer.get(),
|
||||||
*newTextBuffer.get(),
|
*newTextBuffer.get(),
|
||||||
_mutableViewport,
|
_mutableViewport,
|
||||||
@@ -383,7 +383,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
|
|||||||
|
|
||||||
const auto maxRow = std::max(newLastChar.Y, newCursorPos.Y);
|
const auto maxRow = std::max(newLastChar.Y, newCursorPos.Y);
|
||||||
|
|
||||||
const short proposedTopFromLastLine = ::base::ClampAdd(::base::ClampSub(maxRow, viewportSize.Y), 1);
|
const auto proposedTopFromLastLine = maxRow - viewportSize.Y + 1;
|
||||||
const auto proposedTopFromScrollback = newViewportTop;
|
const auto proposedTopFromScrollback = newViewportTop;
|
||||||
|
|
||||||
auto proposedTop = std::max(proposedTopFromLastLine,
|
auto proposedTop = std::max(proposedTopFromLastLine,
|
||||||
@@ -433,7 +433,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
|
|||||||
|
|
||||||
// Make sure the proposed viewport is within the bounds of the buffer.
|
// Make sure the proposed viewport is within the bounds of the buffer.
|
||||||
// First make sure the top is >=0
|
// First make sure the top is >=0
|
||||||
proposedTop = std::max(static_cast<short>(0), proposedTop);
|
proposedTop = std::max(0, proposedTop);
|
||||||
|
|
||||||
// If the new bottom would be below the bottom of the buffer, then slide the
|
// If the new bottom would be below the bottom of the buffer, then slide the
|
||||||
// top up so that we'll still fit within the buffer.
|
// top up so that we'll still fit within the buffer.
|
||||||
@@ -452,7 +452,7 @@ std::wstring_view Terminal::GetWorkingDirectory()
|
|||||||
// Make sure that we don't scroll past the mutableViewport at the bottom of the buffer
|
// Make sure that we don't scroll past the mutableViewport at the bottom of the buffer
|
||||||
newVisibleTop = std::min(newVisibleTop, _mutableViewport.Top());
|
newVisibleTop = std::min(newVisibleTop, _mutableViewport.Top());
|
||||||
// Make sure we don't scroll past the top of the scrollback
|
// Make sure we don't scroll past the top of the scrollback
|
||||||
newVisibleTop = std::max<short>(newVisibleTop, 0);
|
newVisibleTop = std::max(newVisibleTop, 0);
|
||||||
|
|
||||||
// If the old scrolloffset was 0, then we weren't scrolled back at all
|
// If the old scrolloffset was 0, then we weren't scrolled back at all
|
||||||
// before, and shouldn't be now either.
|
// before, and shouldn't be now either.
|
||||||
@@ -555,7 +555,7 @@ bool Terminal::ShouldSendAlternateScroll(const unsigned int uiButton,
|
|||||||
// - Given a coord, get the URI at that location
|
// - Given a coord, get the URI at that location
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - The position
|
// - The position
|
||||||
std::wstring Terminal::GetHyperlinkAtPosition(const COORD position)
|
std::wstring Terminal::GetHyperlinkAtPosition(const til::point position)
|
||||||
{
|
{
|
||||||
auto attr = _activeBuffer().GetCellDataAt(_ConvertToBufferCell(position))->TextAttr();
|
auto attr = _activeBuffer().GetCellDataAt(_ConvertToBufferCell(position))->TextAttr();
|
||||||
if (attr.IsHyperlink())
|
if (attr.IsHyperlink())
|
||||||
@@ -571,8 +571,8 @@ std::wstring Terminal::GetHyperlinkAtPosition(const COORD position)
|
|||||||
const auto end = result->stop;
|
const auto end = result->stop;
|
||||||
std::wstring uri;
|
std::wstring uri;
|
||||||
|
|
||||||
const auto startIter = _activeBuffer().GetCellDataAt(_ConvertToBufferCell(start.to_win32_coord()));
|
const auto startIter = _activeBuffer().GetCellDataAt(_ConvertToBufferCell(start));
|
||||||
const auto endIter = _activeBuffer().GetCellDataAt(_ConvertToBufferCell(end.to_win32_coord()));
|
const auto endIter = _activeBuffer().GetCellDataAt(_ConvertToBufferCell(end));
|
||||||
for (auto iter = startIter; iter != endIter; ++iter)
|
for (auto iter = startIter; iter != endIter; ++iter)
|
||||||
{
|
{
|
||||||
uri += iter->Chars();
|
uri += iter->Chars();
|
||||||
@@ -588,7 +588,7 @@ std::wstring Terminal::GetHyperlinkAtPosition(const COORD position)
|
|||||||
// - The position of the text
|
// - The position of the text
|
||||||
// Return value:
|
// Return value:
|
||||||
// - The hyperlink ID
|
// - The hyperlink ID
|
||||||
uint16_t Terminal::GetHyperlinkIdAtPosition(const COORD position)
|
uint16_t Terminal::GetHyperlinkIdAtPosition(const til::point position)
|
||||||
{
|
{
|
||||||
return _activeBuffer().GetCellDataAt(_ConvertToBufferCell(position))->TextAttr().GetHyperlinkId();
|
return _activeBuffer().GetCellDataAt(_ConvertToBufferCell(position))->TextAttr().GetHyperlinkId();
|
||||||
}
|
}
|
||||||
@@ -599,9 +599,9 @@ uint16_t Terminal::GetHyperlinkIdAtPosition(const COORD position)
|
|||||||
// - The position
|
// - The position
|
||||||
// Return value:
|
// Return value:
|
||||||
// - The interval representing the start and end coordinates
|
// - The interval representing the start and end coordinates
|
||||||
std::optional<PointTree::interval> Terminal::GetHyperlinkIntervalFromPosition(const COORD position)
|
std::optional<PointTree::interval> Terminal::GetHyperlinkIntervalFromPosition(const til::point position)
|
||||||
{
|
{
|
||||||
const auto results = _patternIntervalTree.findOverlapping(til::point{ position.X + 1, position.Y }, til::point{ position });
|
const auto results = _patternIntervalTree.findOverlapping({ position.X + 1, position.Y }, position);
|
||||||
if (results.size() > 0)
|
if (results.size() > 0)
|
||||||
{
|
{
|
||||||
for (const auto& result : results)
|
for (const auto& result : results)
|
||||||
@@ -716,16 +716,14 @@ bool Terminal::SendKeyEvent(const WORD vkey,
|
|||||||
// Return Value:
|
// Return Value:
|
||||||
// - true if we translated the key event, and it should not be processed any further.
|
// - true if we translated the key event, and it should not be processed any further.
|
||||||
// - false if we did not translate the key, and it should be processed into a character.
|
// - false if we did not translate the key, and it should be processed into a character.
|
||||||
bool Terminal::SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const TerminalInput::MouseButtonState state)
|
bool Terminal::SendMouseEvent(til::point viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const TerminalInput::MouseButtonState state)
|
||||||
{
|
{
|
||||||
// GH#6401: VT applications should be able to receive mouse events from outside the
|
// GH#6401: VT applications should be able to receive mouse events from outside the
|
||||||
// terminal buffer. This is likely to happen when the user drags the cursor offscreen.
|
// terminal buffer. This is likely to happen when the user drags the cursor offscreen.
|
||||||
// We shouldn't throw away perfectly good events when they're offscreen, so we just
|
// We shouldn't throw away perfectly good events when they're offscreen, so we just
|
||||||
// clamp them to be within the range [(0, 0), (W, H)].
|
// clamp them to be within the range [(0, 0), (W, H)].
|
||||||
#pragma warning(suppress : 26496) // analysis can't tell we're assigning through a reference below
|
_GetMutableViewport().ToOrigin().Clamp(viewportPos);
|
||||||
auto clampedPos{ viewportPos };
|
return _terminalInput->HandleMouse(viewportPos, uiButton, GET_KEYSTATE_WPARAM(states.Value()), wheelDelta, state);
|
||||||
_GetMutableViewport().ToOrigin().Clamp(clampedPos);
|
|
||||||
return _terminalInput->HandleMouse(til::point{ clampedPos }, uiButton, GET_KEYSTATE_WPARAM(states.Value()), wheelDelta, state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
@@ -784,8 +782,8 @@ void Terminal::_InvalidatePatternTree(interval_tree::IntervalTree<til::point, si
|
|||||||
{
|
{
|
||||||
const auto vis = _VisibleStartIndex();
|
const auto vis = _VisibleStartIndex();
|
||||||
auto invalidate = [=](const PointTree::interval& interval) {
|
auto invalidate = [=](const PointTree::interval& interval) {
|
||||||
COORD startCoord{ gsl::narrow<SHORT>(interval.start.x), gsl::narrow<SHORT>(interval.start.y + vis) };
|
til::point startCoord{ interval.start.x, interval.start.y + vis };
|
||||||
COORD endCoord{ gsl::narrow<SHORT>(interval.stop.x), gsl::narrow<SHORT>(interval.stop.y + vis) };
|
til::point endCoord{ interval.stop.x, interval.stop.y + vis };
|
||||||
_InvalidateFromCoords(startCoord, endCoord);
|
_InvalidateFromCoords(startCoord, endCoord);
|
||||||
};
|
};
|
||||||
tree.visit_all(invalidate);
|
tree.visit_all(invalidate);
|
||||||
@@ -795,30 +793,30 @@ void Terminal::_InvalidatePatternTree(interval_tree::IntervalTree<til::point, si
|
|||||||
// - Given start and end coords, invalidates all the regions between them
|
// - Given start and end coords, invalidates all the regions between them
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - The start and end coords
|
// - The start and end coords
|
||||||
void Terminal::_InvalidateFromCoords(const COORD start, const COORD end)
|
void Terminal::_InvalidateFromCoords(const til::point start, const til::point end)
|
||||||
{
|
{
|
||||||
if (start.Y == end.Y)
|
if (start.Y == end.Y)
|
||||||
{
|
{
|
||||||
SMALL_RECT region{ start.X, start.Y, end.X, end.Y };
|
til::inclusive_rect region{ start.X, start.Y, end.X, end.Y };
|
||||||
_activeBuffer().TriggerRedraw(Viewport::FromInclusive(region));
|
_activeBuffer().TriggerRedraw(Viewport::FromInclusive(region));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const auto rowSize = gsl::narrow<SHORT>(_activeBuffer().GetRowByOffset(0).size());
|
const auto rowSize = _activeBuffer().GetRowByOffset(0).size();
|
||||||
|
|
||||||
// invalidate the first line
|
// invalidate the first line
|
||||||
SMALL_RECT region{ start.X, start.Y, gsl::narrow<short>(rowSize - 1), gsl::narrow<short>(start.Y) };
|
til::inclusive_rect region{ start.X, start.Y, rowSize - 1, start.Y };
|
||||||
_activeBuffer().TriggerRedraw(Viewport::FromInclusive(region));
|
_activeBuffer().TriggerRedraw(Viewport::FromInclusive(region));
|
||||||
|
|
||||||
if ((end.Y - start.Y) > 1)
|
if ((end.Y - start.Y) > 1)
|
||||||
{
|
{
|
||||||
// invalidate the lines in between the first and last line
|
// invalidate the lines in between the first and last line
|
||||||
region = SMALL_RECT{ 0, start.Y + 1, gsl::narrow<short>(rowSize - 1), gsl::narrow<short>(end.Y - 1) };
|
region = til::inclusive_rect{ 0, start.Y + 1, rowSize - 1, end.Y - 1 };
|
||||||
_activeBuffer().TriggerRedraw(Viewport::FromInclusive(region));
|
_activeBuffer().TriggerRedraw(Viewport::FromInclusive(region));
|
||||||
}
|
}
|
||||||
|
|
||||||
// invalidate the last line
|
// invalidate the last line
|
||||||
region = SMALL_RECT{ 0, end.Y, end.X, end.Y };
|
region = til::inclusive_rect{ 0, end.Y, end.X, end.Y };
|
||||||
_activeBuffer().TriggerRedraw(Viewport::FromInclusive(region));
|
_activeBuffer().TriggerRedraw(Viewport::FromInclusive(region));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -977,11 +975,11 @@ Viewport Terminal::_GetMutableViewport() const noexcept
|
|||||||
// GH#3493: if we're in the alt buffer, then it's possible that the mutable
|
// GH#3493: if we're in the alt buffer, then it's possible that the mutable
|
||||||
// viewport's size hasn't been updated yet. In that case, use the
|
// viewport's size hasn't been updated yet. In that case, use the
|
||||||
// temporarily stashed _altBufferSize instead.
|
// temporarily stashed _altBufferSize instead.
|
||||||
return _inAltBuffer() ? Viewport::FromDimensions(_altBufferSize.to_win32_coord()) :
|
return _inAltBuffer() ? Viewport::FromDimensions(_altBufferSize) :
|
||||||
_mutableViewport;
|
_mutableViewport;
|
||||||
}
|
}
|
||||||
|
|
||||||
short Terminal::GetBufferHeight() const noexcept
|
til::CoordType Terminal::GetBufferHeight() const noexcept
|
||||||
{
|
{
|
||||||
return _GetMutableViewport().BottomExclusive();
|
return _GetMutableViewport().BottomExclusive();
|
||||||
}
|
}
|
||||||
@@ -1015,8 +1013,8 @@ Viewport Terminal::_GetVisibleViewport() const noexcept
|
|||||||
// GH#3493: if we're in the alt buffer, then it's possible that the mutable
|
// GH#3493: if we're in the alt buffer, then it's possible that the mutable
|
||||||
// viewport's size hasn't been updated yet. In that case, use the
|
// viewport's size hasn't been updated yet. In that case, use the
|
||||||
// temporarily stashed _altBufferSize instead.
|
// temporarily stashed _altBufferSize instead.
|
||||||
const COORD origin{ 0, gsl::narrow<short>(_VisibleStartIndex()) };
|
const til::point origin{ 0, _VisibleStartIndex() };
|
||||||
const auto size{ _inAltBuffer() ? _altBufferSize.to_win32_coord() :
|
const auto size{ _inAltBuffer() ? _altBufferSize :
|
||||||
_mutableViewport.Dimensions() };
|
_mutableViewport.Dimensions() };
|
||||||
return Viewport::FromDimensions(origin,
|
return Viewport::FromDimensions(origin,
|
||||||
size);
|
size);
|
||||||
@@ -1060,7 +1058,7 @@ void Terminal::_WriteBuffer(const std::wstring_view& stringView)
|
|||||||
{
|
{
|
||||||
// If "wch" was a surrogate character, we just consumed 2 code units above.
|
// If "wch" was a surrogate character, we just consumed 2 code units above.
|
||||||
// -> Increment "i" by 1 in that case and thus by 2 in total in this iteration.
|
// -> Increment "i" by 1 in that case and thus by 2 in total in this iteration.
|
||||||
proposedCursorPosition.X += gsl::narrow<SHORT>(cellDistance);
|
proposedCursorPosition.X += cellDistance;
|
||||||
i += inputDistance - 1;
|
i += inputDistance - 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1099,7 +1097,7 @@ void Terminal::_WriteBuffer(const std::wstring_view& stringView)
|
|||||||
cursor.EndDeferDrawing();
|
cursor.EndDeferDrawing();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Terminal::_AdjustCursorPosition(const COORD proposedPosition)
|
void Terminal::_AdjustCursorPosition(const til::point proposedPosition)
|
||||||
{
|
{
|
||||||
#pragma warning(suppress : 26496) // cpp core checks wants this const but it's modified below.
|
#pragma warning(suppress : 26496) // cpp core checks wants this const but it's modified below.
|
||||||
auto proposedCursorPosition = proposedPosition;
|
auto proposedCursorPosition = proposedPosition;
|
||||||
@@ -1108,7 +1106,7 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition)
|
|||||||
|
|
||||||
// If we're about to scroll past the bottom of the buffer, instead cycle the
|
// If we're about to scroll past the bottom of the buffer, instead cycle the
|
||||||
// buffer.
|
// buffer.
|
||||||
SHORT rowsPushedOffTopOfBuffer = 0;
|
til::CoordType rowsPushedOffTopOfBuffer = 0;
|
||||||
const auto newRows = std::max(0, proposedCursorPosition.Y - bufferSize.Height() + 1);
|
const auto newRows = std::max(0, proposedCursorPosition.Y - bufferSize.Height() + 1);
|
||||||
if (proposedCursorPosition.Y >= bufferSize.Height())
|
if (proposedCursorPosition.Y >= bufferSize.Height())
|
||||||
{
|
{
|
||||||
@@ -1163,7 +1161,7 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition)
|
|||||||
// In the alt buffer, we never need to adjust _mutableViewport, which is the viewport of the main buffer.
|
// In the alt buffer, we never need to adjust _mutableViewport, which is the viewport of the main buffer.
|
||||||
if (newViewTop != _mutableViewport.Top())
|
if (newViewTop != _mutableViewport.Top())
|
||||||
{
|
{
|
||||||
_mutableViewport = Viewport::FromDimensions({ 0, gsl::narrow<short>(newViewTop) },
|
_mutableViewport = Viewport::FromDimensions({ 0, newViewTop },
|
||||||
_mutableViewport.Dimensions());
|
_mutableViewport.Dimensions());
|
||||||
updatedViewport = true;
|
updatedViewport = true;
|
||||||
}
|
}
|
||||||
@@ -1203,7 +1201,7 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition)
|
|||||||
// We have to report the delta here because we might have circled the text buffer.
|
// We have to report the delta here because we might have circled the text buffer.
|
||||||
// That didn't change the viewport and therefore the TriggerScroll(void)
|
// That didn't change the viewport and therefore the TriggerScroll(void)
|
||||||
// method can't detect the delta on its own.
|
// method can't detect the delta on its own.
|
||||||
COORD delta{ 0, gsl::narrow_cast<short>(-rowsPushedOffTopOfBuffer) };
|
til::point delta{ 0, -rowsPushedOffTopOfBuffer };
|
||||||
_activeBuffer().TriggerScroll(delta);
|
_activeBuffer().TriggerScroll(delta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,8 +69,8 @@ public:
|
|||||||
Terminal& operator=(const Terminal&) = default;
|
Terminal& operator=(const Terminal&) = default;
|
||||||
Terminal& operator=(Terminal&&) = default;
|
Terminal& operator=(Terminal&&) = default;
|
||||||
|
|
||||||
void Create(COORD viewportSize,
|
void Create(til::size viewportSize,
|
||||||
SHORT scrollbackLines,
|
til::CoordType scrollbackLines,
|
||||||
Microsoft::Console::Render::Renderer& renderer);
|
Microsoft::Console::Render::Renderer& renderer);
|
||||||
|
|
||||||
void CreateFromSettings(winrt::Microsoft::Terminal::Core::ICoreSettings settings,
|
void CreateFromSettings(winrt::Microsoft::Terminal::Core::ICoreSettings settings,
|
||||||
@@ -94,7 +94,7 @@ public:
|
|||||||
[[nodiscard]] std::unique_lock<til::ticket_lock> LockForWriting();
|
[[nodiscard]] std::unique_lock<til::ticket_lock> LockForWriting();
|
||||||
til::ticket_lock& GetReadWriteLock() noexcept;
|
til::ticket_lock& GetReadWriteLock() noexcept;
|
||||||
|
|
||||||
short GetBufferHeight() const noexcept;
|
til::CoordType GetBufferHeight() const noexcept;
|
||||||
|
|
||||||
int ViewStartIndex() const noexcept;
|
int ViewStartIndex() const noexcept;
|
||||||
int ViewEndIndex() const noexcept;
|
int ViewEndIndex() const noexcept;
|
||||||
@@ -118,7 +118,7 @@ public:
|
|||||||
void LineFeed(const bool withReturn) override;
|
void LineFeed(const bool withReturn) override;
|
||||||
void SetWindowTitle(const std::wstring_view title) override;
|
void SetWindowTitle(const std::wstring_view title) override;
|
||||||
CursorType GetUserDefaultCursorStyle() const override;
|
CursorType GetUserDefaultCursorStyle() const override;
|
||||||
bool ResizeWindow(const size_t width, const size_t height) override;
|
bool ResizeWindow(const til::CoordType width, const til::CoordType height) override;
|
||||||
void SetConsoleOutputCP(const unsigned int codepage) override;
|
void SetConsoleOutputCP(const unsigned int codepage) override;
|
||||||
unsigned int GetConsoleOutputCP() const override;
|
unsigned int GetConsoleOutputCP() const override;
|
||||||
void EnableXtermBracketedPasteMode(const bool enabled) override;
|
void EnableXtermBracketedPasteMode(const bool enabled) override;
|
||||||
@@ -137,10 +137,10 @@ public:
|
|||||||
#pragma region ITerminalInput
|
#pragma region ITerminalInput
|
||||||
// These methods are defined in Terminal.cpp
|
// These methods are defined in Terminal.cpp
|
||||||
bool SendKeyEvent(const WORD vkey, const WORD scanCode, const Microsoft::Terminal::Core::ControlKeyStates states, const bool keyDown) override;
|
bool SendKeyEvent(const WORD vkey, const WORD scanCode, const Microsoft::Terminal::Core::ControlKeyStates states, const bool keyDown) override;
|
||||||
bool SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state) override;
|
bool SendMouseEvent(const til::point viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state) override;
|
||||||
bool SendCharEvent(const wchar_t ch, const WORD scanCode, const ControlKeyStates states) override;
|
bool SendCharEvent(const wchar_t ch, const WORD scanCode, const ControlKeyStates states) override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT UserResize(const COORD viewportSize) noexcept override;
|
[[nodiscard]] HRESULT UserResize(const til::size viewportSize) noexcept override;
|
||||||
void UserScrollViewport(const int viewTop) override;
|
void UserScrollViewport(const int viewTop) override;
|
||||||
int GetScrollOffset() noexcept override;
|
int GetScrollOffset() noexcept override;
|
||||||
|
|
||||||
@@ -150,14 +150,14 @@ public:
|
|||||||
|
|
||||||
void FocusChanged(const bool focused) noexcept override;
|
void FocusChanged(const bool focused) noexcept override;
|
||||||
|
|
||||||
std::wstring GetHyperlinkAtPosition(const COORD position);
|
std::wstring GetHyperlinkAtPosition(const til::point position);
|
||||||
uint16_t GetHyperlinkIdAtPosition(const COORD position);
|
uint16_t GetHyperlinkIdAtPosition(const til::point position);
|
||||||
std::optional<interval_tree::IntervalTree<til::point, size_t>::interval> GetHyperlinkIntervalFromPosition(const COORD position);
|
std::optional<interval_tree::IntervalTree<til::point, size_t>::interval> GetHyperlinkIntervalFromPosition(const til::point position);
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
#pragma region IBaseData(base to IRenderData and IUiaData)
|
#pragma region IBaseData(base to IRenderData and IUiaData)
|
||||||
Microsoft::Console::Types::Viewport GetViewport() noexcept override;
|
Microsoft::Console::Types::Viewport GetViewport() noexcept override;
|
||||||
COORD GetTextBufferEndPosition() const noexcept override;
|
til::point GetTextBufferEndPosition() const noexcept override;
|
||||||
const TextBuffer& GetTextBuffer() const noexcept override;
|
const TextBuffer& GetTextBuffer() const noexcept override;
|
||||||
const FontInfo& GetFontInfo() const noexcept override;
|
const FontInfo& GetFontInfo() const noexcept override;
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ public:
|
|||||||
|
|
||||||
#pragma region IRenderData
|
#pragma region IRenderData
|
||||||
// These methods are defined in TerminalRenderData.cpp
|
// These methods are defined in TerminalRenderData.cpp
|
||||||
COORD GetCursorPosition() const noexcept override;
|
til::point GetCursorPosition() const noexcept override;
|
||||||
bool IsCursorVisible() const noexcept override;
|
bool IsCursorVisible() const noexcept override;
|
||||||
bool IsCursorOn() const noexcept override;
|
bool IsCursorOn() const noexcept override;
|
||||||
ULONG GetCursorHeight() const noexcept override;
|
ULONG GetCursorHeight() const noexcept override;
|
||||||
@@ -178,7 +178,7 @@ public:
|
|||||||
const bool IsGridLineDrawingAllowed() noexcept override;
|
const bool IsGridLineDrawingAllowed() noexcept override;
|
||||||
const std::wstring GetHyperlinkUri(uint16_t id) const noexcept override;
|
const std::wstring GetHyperlinkUri(uint16_t id) const noexcept override;
|
||||||
const std::wstring GetHyperlinkCustomId(uint16_t id) const noexcept override;
|
const std::wstring GetHyperlinkCustomId(uint16_t id) const noexcept override;
|
||||||
const std::vector<size_t> GetPatternId(const COORD location) const noexcept override;
|
const std::vector<size_t> GetPatternId(const til::point location) const noexcept override;
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
#pragma region IUiaData
|
#pragma region IUiaData
|
||||||
@@ -187,11 +187,11 @@ public:
|
|||||||
const bool IsSelectionActive() const noexcept override;
|
const bool IsSelectionActive() const noexcept override;
|
||||||
const bool IsBlockSelection() const noexcept override;
|
const bool IsBlockSelection() const noexcept override;
|
||||||
void ClearSelection() override;
|
void ClearSelection() override;
|
||||||
void SelectNewRegion(const COORD coordStart, const COORD coordEnd) override;
|
void SelectNewRegion(const til::point coordStart, const til::point coordEnd) override;
|
||||||
const COORD GetSelectionAnchor() const noexcept override;
|
const til::point GetSelectionAnchor() const noexcept override;
|
||||||
const COORD GetSelectionEnd() const noexcept override;
|
const til::point GetSelectionEnd() const noexcept override;
|
||||||
const std::wstring_view GetConsoleTitle() const noexcept override;
|
const std::wstring_view GetConsoleTitle() const noexcept override;
|
||||||
void ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute) override;
|
void ColorSelection(const til::point coordSelectionStart, const til::point coordSelectionEnd, const TextAttribute) override;
|
||||||
const bool IsUiaDataInitialized() const noexcept override;
|
const bool IsUiaDataInitialized() const noexcept override;
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
@@ -237,9 +237,9 @@ public:
|
|||||||
Viewport,
|
Viewport,
|
||||||
Buffer
|
Buffer
|
||||||
};
|
};
|
||||||
void MultiClickSelection(const COORD viewportPos, SelectionExpansion expansionMode);
|
void MultiClickSelection(const til::point viewportPos, SelectionExpansion expansionMode);
|
||||||
void SetSelectionAnchor(const COORD position);
|
void SetSelectionAnchor(const til::point position);
|
||||||
void SetSelectionEnd(const COORD position, std::optional<SelectionExpansion> newExpansionMode = std::nullopt);
|
void SetSelectionEnd(const til::point position, std::optional<SelectionExpansion> newExpansionMode = std::nullopt);
|
||||||
void SetBlockSelection(const bool isEnabled) noexcept;
|
void SetBlockSelection(const bool isEnabled) noexcept;
|
||||||
void UpdateSelection(SelectionDirection direction, SelectionExpansion mode, ControlKeyStates mods);
|
void UpdateSelection(SelectionDirection direction, SelectionExpansion mode, ControlKeyStates mods);
|
||||||
void SelectAll();
|
void SelectAll();
|
||||||
@@ -303,14 +303,14 @@ private:
|
|||||||
FontInfo _fontInfo{ DEFAULT_FONT_FACE, TMPF_TRUETYPE, 10, { 0, DEFAULT_FONT_SIZE }, CP_UTF8, false };
|
FontInfo _fontInfo{ DEFAULT_FONT_FACE, TMPF_TRUETYPE, 10, { 0, DEFAULT_FONT_SIZE }, CP_UTF8, false };
|
||||||
#pragma region Text Selection
|
#pragma region Text Selection
|
||||||
// a selection is represented as a range between two COORDs (start and end)
|
// a selection is represented as a range between two COORDs (start and end)
|
||||||
// the pivot is the COORD that remains selected when you extend a selection in any direction
|
// the pivot is the til::point that remains selected when you extend a selection in any direction
|
||||||
// this is particularly useful when a word selection is extended over its starting point
|
// this is particularly useful when a word selection is extended over its starting point
|
||||||
// see TerminalSelection.cpp for more information
|
// see TerminalSelection.cpp for more information
|
||||||
struct SelectionAnchors
|
struct SelectionAnchors
|
||||||
{
|
{
|
||||||
COORD start;
|
til::point start;
|
||||||
COORD end;
|
til::point end;
|
||||||
COORD pivot;
|
til::point pivot;
|
||||||
};
|
};
|
||||||
std::optional<SelectionAnchors> _selection;
|
std::optional<SelectionAnchors> _selection;
|
||||||
bool _blockSelection;
|
bool _blockSelection;
|
||||||
@@ -322,7 +322,7 @@ private:
|
|||||||
std::unique_ptr<TextBuffer> _mainBuffer;
|
std::unique_ptr<TextBuffer> _mainBuffer;
|
||||||
std::unique_ptr<TextBuffer> _altBuffer;
|
std::unique_ptr<TextBuffer> _altBuffer;
|
||||||
Microsoft::Console::Types::Viewport _mutableViewport;
|
Microsoft::Console::Types::Viewport _mutableViewport;
|
||||||
SHORT _scrollbackLines;
|
til::CoordType _scrollbackLines;
|
||||||
bool _detectURLs{ false };
|
bool _detectURLs{ false };
|
||||||
|
|
||||||
til::size _altBufferSize;
|
til::size _altBufferSize;
|
||||||
@@ -346,7 +346,7 @@ private:
|
|||||||
|
|
||||||
interval_tree::IntervalTree<til::point, size_t> _patternIntervalTree;
|
interval_tree::IntervalTree<til::point, size_t> _patternIntervalTree;
|
||||||
void _InvalidatePatternTree(interval_tree::IntervalTree<til::point, size_t>& tree);
|
void _InvalidatePatternTree(interval_tree::IntervalTree<til::point, size_t>& tree);
|
||||||
void _InvalidateFromCoords(const COORD start, const COORD end);
|
void _InvalidateFromCoords(const til::point start, const til::point end);
|
||||||
|
|
||||||
// Since virtual keys are non-zero, you assume that this field is empty/invalid if it is.
|
// Since virtual keys are non-zero, you assume that this field is empty/invalid if it is.
|
||||||
struct KeyEventCodes
|
struct KeyEventCodes
|
||||||
@@ -372,7 +372,7 @@ private:
|
|||||||
|
|
||||||
void _WriteBuffer(const std::wstring_view& stringView);
|
void _WriteBuffer(const std::wstring_view& stringView);
|
||||||
|
|
||||||
void _AdjustCursorPosition(const COORD proposedPosition);
|
void _AdjustCursorPosition(const til::point proposedPosition);
|
||||||
|
|
||||||
void _NotifyScrollEvent() noexcept;
|
void _NotifyScrollEvent() noexcept;
|
||||||
|
|
||||||
@@ -384,14 +384,14 @@ private:
|
|||||||
|
|
||||||
#pragma region TextSelection
|
#pragma region TextSelection
|
||||||
// These methods are defined in TerminalSelection.cpp
|
// These methods are defined in TerminalSelection.cpp
|
||||||
std::vector<SMALL_RECT> _GetSelectionRects() const noexcept;
|
std::vector<til::inclusive_rect> _GetSelectionRects() const noexcept;
|
||||||
std::pair<COORD, COORD> _PivotSelection(const COORD targetPos, bool& targetStart) const;
|
std::pair<til::point, til::point> _PivotSelection(const til::point targetPos, bool& targetStart) const;
|
||||||
std::pair<COORD, COORD> _ExpandSelectionAnchors(std::pair<COORD, COORD> anchors) const;
|
std::pair<til::point, til::point> _ExpandSelectionAnchors(std::pair<til::point, til::point> anchors) const;
|
||||||
COORD _ConvertToBufferCell(const COORD viewportPos) const;
|
til::point _ConvertToBufferCell(const til::point viewportPos) const;
|
||||||
void _MoveByChar(SelectionDirection direction, COORD& pos);
|
void _MoveByChar(SelectionDirection direction, til::point& pos);
|
||||||
void _MoveByWord(SelectionDirection direction, COORD& pos);
|
void _MoveByWord(SelectionDirection direction, til::point& pos);
|
||||||
void _MoveByViewport(SelectionDirection direction, COORD& pos);
|
void _MoveByViewport(SelectionDirection direction, til::point& pos);
|
||||||
void _MoveByBuffer(SelectionDirection direction, COORD& pos);
|
void _MoveByBuffer(SelectionDirection direction, til::point& pos);
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
#ifdef UNIT_TESTING
|
#ifdef UNIT_TESTING
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ void Terminal::SetViewportPosition(const til::point position)
|
|||||||
if (!_inAltBuffer())
|
if (!_inAltBuffer())
|
||||||
{
|
{
|
||||||
const auto dimensions = _GetMutableViewport().Dimensions();
|
const auto dimensions = _GetMutableViewport().Dimensions();
|
||||||
_mutableViewport = Viewport::FromDimensions(position.to_win32_coord(), dimensions);
|
_mutableViewport = Viewport::FromDimensions(position, dimensions);
|
||||||
Terminal::_NotifyScrollEvent();
|
Terminal::_NotifyScrollEvent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,7 +106,7 @@ CursorType Terminal::GetUserDefaultCursorStyle() const
|
|||||||
return _defaultCursorShape;
|
return _defaultCursorShape;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Terminal::ResizeWindow(const size_t /*width*/, const size_t /*height*/)
|
bool Terminal::ResizeWindow(const til::CoordType /*width*/, const til::CoordType /*height*/)
|
||||||
{
|
{
|
||||||
// TODO: This will be needed to support various resizing sequences. See also GH#1860.
|
// TODO: This will be needed to support various resizing sequences. See also GH#1860.
|
||||||
return false;
|
return false;
|
||||||
@@ -196,7 +196,7 @@ void Terminal::PlayMidiNote(const int noteNumber, const int velocity, const std:
|
|||||||
void Terminal::UseAlternateScreenBuffer()
|
void Terminal::UseAlternateScreenBuffer()
|
||||||
{
|
{
|
||||||
// the new alt buffer is exactly the size of the viewport.
|
// the new alt buffer is exactly the size of the viewport.
|
||||||
_altBufferSize = til::size{ _mutableViewport.Dimensions() };
|
_altBufferSize = _mutableViewport.Dimensions();
|
||||||
|
|
||||||
const auto cursorSize = _mainBuffer->GetCursor().GetSize();
|
const auto cursorSize = _mainBuffer->GetCursor().GetSize();
|
||||||
|
|
||||||
@@ -204,7 +204,7 @@ void Terminal::UseAlternateScreenBuffer()
|
|||||||
_mainBuffer->ClearPatternRecognizers();
|
_mainBuffer->ClearPatternRecognizers();
|
||||||
|
|
||||||
// Create a new alt buffer
|
// Create a new alt buffer
|
||||||
_altBuffer = std::make_unique<TextBuffer>(_altBufferSize.to_win32_coord(),
|
_altBuffer = std::make_unique<TextBuffer>(_altBufferSize,
|
||||||
TextAttribute{},
|
TextAttribute{},
|
||||||
cursorSize,
|
cursorSize,
|
||||||
true,
|
true,
|
||||||
@@ -275,7 +275,7 @@ void Terminal::UseMainScreenBuffer()
|
|||||||
|
|
||||||
if (_deferredResize.has_value())
|
if (_deferredResize.has_value())
|
||||||
{
|
{
|
||||||
LOG_IF_FAILED(UserResize(_deferredResize.value().to_win32_coord()));
|
LOG_IF_FAILED(UserResize(_deferredResize.value()));
|
||||||
_deferredResize = std::nullopt;
|
_deferredResize = std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,9 +43,9 @@ using namespace Microsoft::Terminal::Core;
|
|||||||
// - Helper to determine the selected region of the buffer. Used for rendering.
|
// - Helper to determine the selected region of the buffer. Used for rendering.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - A vector of rectangles representing the regions to select, line by line. They are absolute coordinates relative to the buffer origin.
|
// - A vector of rectangles representing the regions to select, line by line. They are absolute coordinates relative to the buffer origin.
|
||||||
std::vector<SMALL_RECT> Terminal::_GetSelectionRects() const noexcept
|
std::vector<til::inclusive_rect> Terminal::_GetSelectionRects() const noexcept
|
||||||
{
|
{
|
||||||
std::vector<SMALL_RECT> result;
|
std::vector<til::inclusive_rect> result;
|
||||||
|
|
||||||
if (!IsSelectionActive())
|
if (!IsSelectionActive())
|
||||||
{
|
{
|
||||||
@@ -66,7 +66,7 @@ std::vector<SMALL_RECT> Terminal::_GetSelectionRects() const noexcept
|
|||||||
// - None
|
// - None
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - None
|
// - None
|
||||||
const COORD Terminal::GetSelectionAnchor() const noexcept
|
const til::point Terminal::GetSelectionAnchor() const noexcept
|
||||||
{
|
{
|
||||||
return _selection->start;
|
return _selection->start;
|
||||||
}
|
}
|
||||||
@@ -77,7 +77,7 @@ const COORD Terminal::GetSelectionAnchor() const noexcept
|
|||||||
// - None
|
// - None
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - None
|
// - None
|
||||||
const COORD Terminal::GetSelectionEnd() const noexcept
|
const til::point Terminal::GetSelectionEnd() const noexcept
|
||||||
{
|
{
|
||||||
return _selection->end;
|
return _selection->end;
|
||||||
}
|
}
|
||||||
@@ -101,7 +101,7 @@ const bool Terminal::IsBlockSelection() const noexcept
|
|||||||
// Arguments:
|
// Arguments:
|
||||||
// - viewportPos: the (x,y) coordinate on the visible viewport
|
// - viewportPos: the (x,y) coordinate on the visible viewport
|
||||||
// - expansionMode: the SelectionExpansion to dictate the boundaries of the selection anchors
|
// - expansionMode: the SelectionExpansion to dictate the boundaries of the selection anchors
|
||||||
void Terminal::MultiClickSelection(const COORD viewportPos, SelectionExpansion expansionMode)
|
void Terminal::MultiClickSelection(const til::point viewportPos, SelectionExpansion expansionMode)
|
||||||
{
|
{
|
||||||
// set the selection pivot to expand the selection using SetSelectionEnd()
|
// set the selection pivot to expand the selection using SetSelectionEnd()
|
||||||
_selection = SelectionAnchors{};
|
_selection = SelectionAnchors{};
|
||||||
@@ -119,7 +119,7 @@ void Terminal::MultiClickSelection(const COORD viewportPos, SelectionExpansion e
|
|||||||
// - Record the position of the beginning of a selection
|
// - Record the position of the beginning of a selection
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// - position: the (x,y) coordinate on the visible viewport
|
// - position: the (x,y) coordinate on the visible viewport
|
||||||
void Terminal::SetSelectionAnchor(const COORD viewportPos)
|
void Terminal::SetSelectionAnchor(const til::point viewportPos)
|
||||||
{
|
{
|
||||||
_selection = SelectionAnchors{};
|
_selection = SelectionAnchors{};
|
||||||
_selection->pivot = _ConvertToBufferCell(viewportPos);
|
_selection->pivot = _ConvertToBufferCell(viewportPos);
|
||||||
@@ -136,7 +136,7 @@ void Terminal::SetSelectionAnchor(const COORD viewportPos)
|
|||||||
// Arguments:
|
// Arguments:
|
||||||
// - viewportPos: the (x,y) coordinate on the visible viewport
|
// - viewportPos: the (x,y) coordinate on the visible viewport
|
||||||
// - newExpansionMode: overwrites the _multiClickSelectionMode for this function call. Used for ShiftClick
|
// - newExpansionMode: overwrites the _multiClickSelectionMode for this function call. Used for ShiftClick
|
||||||
void Terminal::SetSelectionEnd(const COORD viewportPos, std::optional<SelectionExpansion> newExpansionMode)
|
void Terminal::SetSelectionEnd(const til::point viewportPos, std::optional<SelectionExpansion> newExpansionMode)
|
||||||
{
|
{
|
||||||
if (!_selection.has_value())
|
if (!_selection.has_value())
|
||||||
{
|
{
|
||||||
@@ -180,7 +180,7 @@ void Terminal::SetSelectionEnd(const COORD viewportPos, std::optional<SelectionE
|
|||||||
// - targetStart: if true, target will be the new start. Otherwise, target will be the new end.
|
// - targetStart: if true, target will be the new start. Otherwise, target will be the new end.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - the new start/end for a selection
|
// - the new start/end for a selection
|
||||||
std::pair<COORD, COORD> Terminal::_PivotSelection(const COORD targetPos, bool& targetStart) const
|
std::pair<til::point, til::point> Terminal::_PivotSelection(const til::point targetPos, bool& targetStart) const
|
||||||
{
|
{
|
||||||
if (targetStart = _activeBuffer().GetSize().CompareInBounds(targetPos, _selection->pivot) <= 0)
|
if (targetStart = _activeBuffer().GetSize().CompareInBounds(targetPos, _selection->pivot) <= 0)
|
||||||
{
|
{
|
||||||
@@ -202,7 +202,7 @@ std::pair<COORD, COORD> Terminal::_PivotSelection(const COORD targetPos, bool& t
|
|||||||
// - anchors: a pair of selection anchors representing a desired selection
|
// - anchors: a pair of selection anchors representing a desired selection
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - the new start/end for a selection
|
// - the new start/end for a selection
|
||||||
std::pair<COORD, COORD> Terminal::_ExpandSelectionAnchors(std::pair<COORD, COORD> anchors) const
|
std::pair<til::point, til::point> Terminal::_ExpandSelectionAnchors(std::pair<til::point, til::point> anchors) const
|
||||||
{
|
{
|
||||||
auto start = anchors.first;
|
auto start = anchors.first;
|
||||||
auto end = anchors.second;
|
auto end = anchors.second;
|
||||||
@@ -389,38 +389,39 @@ void Terminal::SelectAll()
|
|||||||
_selection->pivot = _selection->end;
|
_selection->pivot = _selection->end;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Terminal::_MoveByChar(SelectionDirection direction, COORD& pos)
|
void Terminal::_MoveByChar(SelectionDirection direction, til::point& pos)
|
||||||
{
|
{
|
||||||
switch (direction)
|
switch (direction)
|
||||||
{
|
{
|
||||||
case SelectionDirection::Left:
|
case SelectionDirection::Left:
|
||||||
_activeBuffer().GetSize().DecrementInBounds(pos);
|
_activeBuffer().GetSize().DecrementInBounds(pos);
|
||||||
pos = _activeBuffer().GetGlyphStart(til::point{ pos }).to_win32_coord();
|
pos = _activeBuffer().GetGlyphStart(pos);
|
||||||
break;
|
break;
|
||||||
case SelectionDirection::Right:
|
case SelectionDirection::Right:
|
||||||
_activeBuffer().GetSize().IncrementInBounds(pos);
|
_activeBuffer().GetSize().IncrementInBounds(pos);
|
||||||
pos = _activeBuffer().GetGlyphEnd(til::point{ pos }).to_win32_coord();
|
pos = _activeBuffer().GetGlyphEnd(pos);
|
||||||
break;
|
break;
|
||||||
case SelectionDirection::Up:
|
case SelectionDirection::Up:
|
||||||
{
|
{
|
||||||
const auto bufferSize{ _activeBuffer().GetSize() };
|
const auto bufferSize{ _activeBuffer().GetSize() };
|
||||||
pos = { pos.X, std::clamp(base::ClampSub<short, short>(pos.Y, 1).RawValue(), bufferSize.Top(), bufferSize.BottomInclusive()) };
|
pos = { pos.X, std::clamp(pos.Y - 1, bufferSize.Top(), bufferSize.BottomInclusive()) };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SelectionDirection::Down:
|
case SelectionDirection::Down:
|
||||||
{
|
{
|
||||||
const auto bufferSize{ _activeBuffer().GetSize() };
|
const auto bufferSize{ _activeBuffer().GetSize() };
|
||||||
pos = { pos.X, std::clamp(base::ClampAdd<short, short>(pos.Y, 1).RawValue(), bufferSize.Top(), bufferSize.BottomInclusive()) };
|
pos = { pos.X, std::clamp(pos.Y + 1, bufferSize.Top(), bufferSize.BottomInclusive()) };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Terminal::_MoveByWord(SelectionDirection direction, COORD& pos)
|
void Terminal::_MoveByWord(SelectionDirection direction, til::point& pos)
|
||||||
{
|
{
|
||||||
switch (direction)
|
switch (direction)
|
||||||
{
|
{
|
||||||
case SelectionDirection::Left:
|
case SelectionDirection::Left:
|
||||||
|
{
|
||||||
const auto wordStartPos{ _activeBuffer().GetWordStart(pos, _wordDelimiters) };
|
const auto wordStartPos{ _activeBuffer().GetWordStart(pos, _wordDelimiters) };
|
||||||
if (_activeBuffer().GetSize().CompareInBounds(_selection->pivot, pos) < 0)
|
if (_activeBuffer().GetSize().CompareInBounds(_selection->pivot, pos) < 0)
|
||||||
{
|
{
|
||||||
@@ -441,7 +442,9 @@ void Terminal::_MoveByWord(SelectionDirection direction, COORD& pos)
|
|||||||
pos = wordStartPos;
|
pos = wordStartPos;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case SelectionDirection::Right:
|
case SelectionDirection::Right:
|
||||||
|
{
|
||||||
const auto wordEndPos{ _activeBuffer().GetWordEnd(pos, _wordDelimiters) };
|
const auto wordEndPos{ _activeBuffer().GetWordEnd(pos, _wordDelimiters) };
|
||||||
if (_activeBuffer().GetSize().CompareInBounds(pos, _selection->pivot) < 0)
|
if (_activeBuffer().GetSize().CompareInBounds(pos, _selection->pivot) < 0)
|
||||||
{
|
{
|
||||||
@@ -462,6 +465,7 @@ void Terminal::_MoveByWord(SelectionDirection direction, COORD& pos)
|
|||||||
pos = wordEndPos;
|
pos = wordEndPos;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case SelectionDirection::Up:
|
case SelectionDirection::Up:
|
||||||
_MoveByChar(direction, pos);
|
_MoveByChar(direction, pos);
|
||||||
pos = _activeBuffer().GetWordStart(pos, _wordDelimiters);
|
pos = _activeBuffer().GetWordStart(pos, _wordDelimiters);
|
||||||
@@ -473,7 +477,7 @@ void Terminal::_MoveByWord(SelectionDirection direction, COORD& pos)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Terminal::_MoveByViewport(SelectionDirection direction, COORD& pos)
|
void Terminal::_MoveByViewport(SelectionDirection direction, til::point& pos)
|
||||||
{
|
{
|
||||||
const auto bufferSize{ _activeBuffer().GetSize() };
|
const auto bufferSize{ _activeBuffer().GetSize() };
|
||||||
switch (direction)
|
switch (direction)
|
||||||
@@ -487,22 +491,22 @@ void Terminal::_MoveByViewport(SelectionDirection direction, COORD& pos)
|
|||||||
case SelectionDirection::Up:
|
case SelectionDirection::Up:
|
||||||
{
|
{
|
||||||
const auto viewportHeight{ _GetMutableViewport().Height() };
|
const auto viewportHeight{ _GetMutableViewport().Height() };
|
||||||
const auto newY{ base::ClampSub<short, short>(pos.Y, viewportHeight) };
|
const auto newY{ pos.Y - viewportHeight };
|
||||||
pos = newY < bufferSize.Top() ? bufferSize.Origin() : COORD{ pos.X, newY };
|
pos = newY < bufferSize.Top() ? bufferSize.Origin() : til::point{ pos.X, newY };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SelectionDirection::Down:
|
case SelectionDirection::Down:
|
||||||
{
|
{
|
||||||
const auto viewportHeight{ _GetMutableViewport().Height() };
|
const auto viewportHeight{ _GetMutableViewport().Height() };
|
||||||
const auto mutableBottom{ _GetMutableViewport().BottomInclusive() };
|
const auto mutableBottom{ _GetMutableViewport().BottomInclusive() };
|
||||||
const auto newY{ base::ClampAdd<short, short>(pos.Y, viewportHeight) };
|
const auto newY{ pos.Y + viewportHeight };
|
||||||
pos = newY > mutableBottom ? COORD{ bufferSize.RightInclusive(), mutableBottom } : COORD{ pos.X, newY };
|
pos = newY > mutableBottom ? til::point{ bufferSize.RightInclusive(), mutableBottom } : til::point{ pos.X, newY };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Terminal::_MoveByBuffer(SelectionDirection direction, COORD& pos)
|
void Terminal::_MoveByBuffer(SelectionDirection direction, til::point& pos)
|
||||||
{
|
{
|
||||||
const auto bufferSize{ _activeBuffer().GetSize() };
|
const auto bufferSize{ _activeBuffer().GetSize() };
|
||||||
switch (direction)
|
switch (direction)
|
||||||
@@ -559,10 +563,10 @@ const TextBuffer::TextAndColor Terminal::RetrieveSelectedTextFromBuffer(bool sin
|
|||||||
// - viewportPos: a coordinate on the viewport
|
// - viewportPos: a coordinate on the viewport
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - the corresponding location on the buffer
|
// - the corresponding location on the buffer
|
||||||
COORD Terminal::_ConvertToBufferCell(const COORD viewportPos) const
|
til::point Terminal::_ConvertToBufferCell(const til::point viewportPos) const
|
||||||
{
|
{
|
||||||
const auto yPos = base::ClampedNumeric<short>(_VisibleStartIndex()) + viewportPos.Y;
|
const auto yPos = _VisibleStartIndex() + viewportPos.Y;
|
||||||
COORD bufferPos = { viewportPos.X, yPos };
|
til::point bufferPos = { viewportPos.X, yPos };
|
||||||
_activeBuffer().GetSize().Clamp(bufferPos);
|
_activeBuffer().GetSize().Clamp(bufferPos);
|
||||||
return bufferPos;
|
return bufferPos;
|
||||||
}
|
}
|
||||||
@@ -574,7 +578,7 @@ COORD Terminal::_ConvertToBufferCell(const COORD viewportPos) const
|
|||||||
// - coordSelectionStart - Not used
|
// - coordSelectionStart - Not used
|
||||||
// - coordSelectionEnd - Not used
|
// - coordSelectionEnd - Not used
|
||||||
// - attr - Not used.
|
// - attr - Not used.
|
||||||
void Terminal::ColorSelection(const COORD, const COORD, const TextAttribute)
|
void Terminal::ColorSelection(const til::point, const til::point, const TextAttribute)
|
||||||
{
|
{
|
||||||
THROW_HR(E_NOTIMPL);
|
THROW_HR(E_NOTIMPL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,13 +14,12 @@ Viewport Terminal::GetViewport() noexcept
|
|||||||
return _GetVisibleViewport();
|
return _GetVisibleViewport();
|
||||||
}
|
}
|
||||||
|
|
||||||
COORD Terminal::GetTextBufferEndPosition() const noexcept
|
til::point Terminal::GetTextBufferEndPosition() const noexcept
|
||||||
{
|
{
|
||||||
// We use the end line of mutableViewport as the end
|
// We use the end line of mutableViewport as the end
|
||||||
// of the text buffer, it always moves with the written
|
// of the text buffer, it always moves with the written
|
||||||
// text
|
// text
|
||||||
COORD endPosition{ _GetMutableViewport().Width() - 1, gsl::narrow<short>(ViewEndIndex()) };
|
return { _GetMutableViewport().Width() - 1, ViewEndIndex() };
|
||||||
return endPosition;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const TextBuffer& Terminal::GetTextBuffer() const noexcept
|
const TextBuffer& Terminal::GetTextBuffer() const noexcept
|
||||||
@@ -38,7 +37,7 @@ void Terminal::SetFontInfo(const FontInfo& fontInfo)
|
|||||||
_fontInfo = fontInfo;
|
_fontInfo = fontInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
COORD Terminal::GetCursorPosition() const noexcept
|
til::point Terminal::GetCursorPosition() const noexcept
|
||||||
{
|
{
|
||||||
const auto& cursor = _activeBuffer().GetCursor();
|
const auto& cursor = _activeBuffer().GetCursor();
|
||||||
return cursor.GetPosition();
|
return cursor.GetPosition();
|
||||||
@@ -104,10 +103,10 @@ const std::wstring Microsoft::Terminal::Core::Terminal::GetHyperlinkCustomId(uin
|
|||||||
// - The location
|
// - The location
|
||||||
// Return value:
|
// Return value:
|
||||||
// - The pattern IDs of the location
|
// - The pattern IDs of the location
|
||||||
const std::vector<size_t> Terminal::GetPatternId(const COORD location) const noexcept
|
const std::vector<size_t> Terminal::GetPatternId(const til::point location) const noexcept
|
||||||
{
|
{
|
||||||
// Look through our interval tree for this location
|
// Look through our interval tree for this location
|
||||||
const auto intervals = _patternIntervalTree.findOverlapping(til::point{ location.X + 1, location.Y }, til::point{ location });
|
const auto intervals = _patternIntervalTree.findOverlapping({ location.X + 1, location.Y }, location);
|
||||||
if (intervals.size() == 0)
|
if (intervals.size() == 0)
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
@@ -147,7 +146,7 @@ catch (...)
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Terminal::SelectNewRegion(const COORD coordStart, const COORD coordEnd)
|
void Terminal::SelectNewRegion(const til::point coordStart, const til::point coordEnd)
|
||||||
{
|
{
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 26496) // cpp core checks wants these const, but they're decremented below.
|
#pragma warning(disable : 26496) // cpp core checks wants these const, but they're decremented below.
|
||||||
@@ -178,8 +177,8 @@ void Terminal::SelectNewRegion(const COORD coordStart, const COORD coordEnd)
|
|||||||
_NotifyScrollEvent();
|
_NotifyScrollEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
realCoordStart.Y -= gsl::narrow<short>(_VisibleStartIndex());
|
realCoordStart.Y -= _VisibleStartIndex();
|
||||||
realCoordEnd.Y -= gsl::narrow<short>(_VisibleStartIndex());
|
realCoordEnd.Y -= _VisibleStartIndex();
|
||||||
|
|
||||||
SetSelectionAnchor(realCoordStart);
|
SetSelectionAnchor(realCoordStart);
|
||||||
SetSelectionEnd(realCoordEnd, SelectionExpansion::Char);
|
SetSelectionEnd(realCoordEnd, SelectionExpansion::Char);
|
||||||
|
|||||||
@@ -440,7 +440,7 @@ namespace ControlUnitTests
|
|||||||
Log::Comment(L"Verify the location of the selection");
|
Log::Comment(L"Verify the location of the selection");
|
||||||
// The viewport is on row 21, so the selection will be on:
|
// The viewport is on row 21, so the selection will be on:
|
||||||
// {(5, 5)+(0, 21)} to {(5, 5)+(0, 21)}
|
// {(5, 5)+(0, 21)} to {(5, 5)+(0, 21)}
|
||||||
COORD expectedAnchor{ 5, 26 };
|
til::point expectedAnchor{ 5, 26 };
|
||||||
VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionAnchor());
|
VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionAnchor());
|
||||||
VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionEnd());
|
VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionEnd());
|
||||||
|
|
||||||
@@ -453,7 +453,7 @@ namespace ControlUnitTests
|
|||||||
Log::Comment(L"Verify the location of the selection");
|
Log::Comment(L"Verify the location of the selection");
|
||||||
// The viewport is now on row 20, so the selection will be on:
|
// The viewport is now on row 20, so the selection will be on:
|
||||||
// {(5, 5)+(0, 20)} to {(5, 5)+(0, 21)}
|
// {(5, 5)+(0, 20)} to {(5, 5)+(0, 21)}
|
||||||
COORD newExpectedAnchor{ 5, 25 };
|
til::point newExpectedAnchor{ 5, 25 };
|
||||||
// Remember, the anchor is always before the end in the buffer. So yes,
|
// Remember, the anchor is always before the end in the buffer. So yes,
|
||||||
// se started the selection on 5,26, but now that's the end.
|
// se started the selection on 5,26, but now that's the end.
|
||||||
VERIFY_ARE_EQUAL(newExpectedAnchor, core->_terminal->GetSelectionAnchor());
|
VERIFY_ARE_EQUAL(newExpectedAnchor, core->_terminal->GetSelectionAnchor());
|
||||||
@@ -586,7 +586,7 @@ namespace ControlUnitTests
|
|||||||
VERIFY_ARE_EQUAL(1u, core->_terminal->GetSelectionRects().size());
|
VERIFY_ARE_EQUAL(1u, core->_terminal->GetSelectionRects().size());
|
||||||
|
|
||||||
Log::Comment(L"Verify that it started on the first cell we clicked on, not the one we dragged to");
|
Log::Comment(L"Verify that it started on the first cell we clicked on, not the one we dragged to");
|
||||||
COORD expectedAnchor{ 0, 0 };
|
til::point expectedAnchor{ 0, 0 };
|
||||||
VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionAnchor());
|
VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionAnchor());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -631,9 +631,9 @@ namespace ControlUnitTests
|
|||||||
VERIFY_ARE_EQUAL(1u, core->_terminal->GetSelectionRects().size());
|
VERIFY_ARE_EQUAL(1u, core->_terminal->GetSelectionRects().size());
|
||||||
|
|
||||||
Log::Comment(L"Verify that it started on the first cell we clicked on, not the one we dragged to");
|
Log::Comment(L"Verify that it started on the first cell we clicked on, not the one we dragged to");
|
||||||
COORD expectedAnchor{ 0, 0 };
|
til::point expectedAnchor{ 0, 0 };
|
||||||
VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionAnchor());
|
VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionAnchor());
|
||||||
COORD expectedEnd{ 2, 0 };
|
til::point expectedEnd{ 2, 0 };
|
||||||
VERIFY_ARE_EQUAL(expectedEnd, core->_terminal->GetSelectionEnd());
|
VERIFY_ARE_EQUAL(expectedEnd, core->_terminal->GetSelectionEnd());
|
||||||
|
|
||||||
interactivity->PointerReleased(noMouseDown,
|
interactivity->PointerReleased(noMouseDown,
|
||||||
@@ -801,7 +801,7 @@ namespace ControlUnitTests
|
|||||||
Log::Comment(L"Verify the location of the selection");
|
Log::Comment(L"Verify the location of the selection");
|
||||||
// The viewport is on row (historySize + 5), so the selection will be on:
|
// The viewport is on row (historySize + 5), so the selection will be on:
|
||||||
// {(5, (historySize+5))+(0, 21)} to {(5, (historySize+5))+(0, 21)}
|
// {(5, (historySize+5))+(0, 21)} to {(5, (historySize+5))+(0, 21)}
|
||||||
COORD expectedAnchor{ 5, gsl::narrow_cast<SHORT>(settings->HistorySize()) + 5 };
|
til::point expectedAnchor{ 5, settings->HistorySize() + 5 };
|
||||||
VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionAnchor());
|
VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionAnchor());
|
||||||
VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionEnd());
|
VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionEnd());
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -60,7 +60,7 @@ void ScreenSizeLimitsTest::ScrollbackHistorySizeIsClampedToBounds()
|
|||||||
// which is the *sum* of the history size plus the number of rows
|
// which is the *sum* of the history size plus the number of rows
|
||||||
// actually visible on screen at the moment.
|
// actually visible on screen at the moment.
|
||||||
|
|
||||||
const unsigned int visibleRowCount = 100;
|
static constexpr til::CoordType visibleRowCount = 100;
|
||||||
|
|
||||||
// Zero history size is acceptable.
|
// Zero history size is acceptable.
|
||||||
auto noHistorySettings = winrt::make<MockTermSettings>(0, visibleRowCount, 100);
|
auto noHistorySettings = winrt::make<MockTermSettings>(0, visibleRowCount, 100);
|
||||||
@@ -79,19 +79,19 @@ void ScreenSizeLimitsTest::ScrollbackHistorySizeIsClampedToBounds()
|
|||||||
auto maxHistorySizeSettings = winrt::make<MockTermSettings>(SHRT_MAX - visibleRowCount, visibleRowCount, 100);
|
auto maxHistorySizeSettings = winrt::make<MockTermSettings>(SHRT_MAX - visibleRowCount, visibleRowCount, 100);
|
||||||
Terminal maxHistorySizeTerminal;
|
Terminal maxHistorySizeTerminal;
|
||||||
maxHistorySizeTerminal.CreateFromSettings(maxHistorySizeSettings, renderer);
|
maxHistorySizeTerminal.CreateFromSettings(maxHistorySizeSettings, renderer);
|
||||||
VERIFY_ARE_EQUAL(maxHistorySizeTerminal.GetTextBuffer().TotalRowCount(), static_cast<unsigned int>(SHRT_MAX), L"History size == SHRT_MAX - initial row count is accepted");
|
VERIFY_ARE_EQUAL(maxHistorySizeTerminal.GetTextBuffer().TotalRowCount(), SHRT_MAX, L"History size == SHRT_MAX - initial row count is accepted");
|
||||||
|
|
||||||
// History size + initial visible rows == SHRT_MAX + 1 will be clamped slightly.
|
// History size + initial visible rows == SHRT_MAX + 1 will be clamped slightly.
|
||||||
auto justTooBigHistorySizeSettings = winrt::make<MockTermSettings>(SHRT_MAX - visibleRowCount + 1, visibleRowCount, 100);
|
auto justTooBigHistorySizeSettings = winrt::make<MockTermSettings>(SHRT_MAX - visibleRowCount + 1, visibleRowCount, 100);
|
||||||
Terminal justTooBigHistorySizeTerminal;
|
Terminal justTooBigHistorySizeTerminal;
|
||||||
justTooBigHistorySizeTerminal.CreateFromSettings(justTooBigHistorySizeSettings, renderer);
|
justTooBigHistorySizeTerminal.CreateFromSettings(justTooBigHistorySizeSettings, renderer);
|
||||||
VERIFY_ARE_EQUAL(justTooBigHistorySizeTerminal.GetTextBuffer().TotalRowCount(), static_cast<unsigned int>(SHRT_MAX), L"History size == 1 + SHRT_MAX - initial row count is clamped to SHRT_MAX - initial row count");
|
VERIFY_ARE_EQUAL(justTooBigHistorySizeTerminal.GetTextBuffer().TotalRowCount(), SHRT_MAX, L"History size == 1 + SHRT_MAX - initial row count is clamped to SHRT_MAX - initial row count");
|
||||||
|
|
||||||
// Ridiculously large history sizes are also clamped.
|
// Ridiculously large history sizes are also clamped.
|
||||||
auto farTooBigHistorySizeSettings = winrt::make<MockTermSettings>(99999999, visibleRowCount, 100);
|
auto farTooBigHistorySizeSettings = winrt::make<MockTermSettings>(99999999, visibleRowCount, 100);
|
||||||
Terminal farTooBigHistorySizeTerminal;
|
Terminal farTooBigHistorySizeTerminal;
|
||||||
farTooBigHistorySizeTerminal.CreateFromSettings(farTooBigHistorySizeSettings, renderer);
|
farTooBigHistorySizeTerminal.CreateFromSettings(farTooBigHistorySizeSettings, renderer);
|
||||||
VERIFY_ARE_EQUAL(farTooBigHistorySizeTerminal.GetTextBuffer().TotalRowCount(), static_cast<unsigned int>(SHRT_MAX), L"History size that is far too large is clamped to SHRT_MAX - initial row count");
|
VERIFY_ARE_EQUAL(farTooBigHistorySizeTerminal.GetTextBuffer().TotalRowCount(), SHRT_MAX, L"History size that is far too large is clamped to SHRT_MAX - initial row count");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenSizeLimitsTest::ResizeIsClampedToBounds()
|
void ScreenSizeLimitsTest::ResizeIsClampedToBounds()
|
||||||
@@ -102,8 +102,8 @@ void ScreenSizeLimitsTest::ResizeIsClampedToBounds()
|
|||||||
//
|
//
|
||||||
// This is a test for GH#2630, GH#2815.
|
// This is a test for GH#2630, GH#2815.
|
||||||
|
|
||||||
const unsigned int initialVisibleColCount = 50;
|
static constexpr til::CoordType initialVisibleColCount = 50;
|
||||||
const unsigned int initialVisibleRowCount = 50;
|
static constexpr til::CoordType initialVisibleRowCount = 50;
|
||||||
const auto historySize = SHRT_MAX - (initialVisibleRowCount * 2);
|
const auto historySize = SHRT_MAX - (initialVisibleRowCount * 2);
|
||||||
|
|
||||||
Log::Comment(L"Watch out - this test takes a while on debug, because "
|
Log::Comment(L"Watch out - this test takes a while on debug, because "
|
||||||
@@ -114,18 +114,18 @@ void ScreenSizeLimitsTest::ResizeIsClampedToBounds()
|
|||||||
Terminal terminal;
|
Terminal terminal;
|
||||||
DummyRenderer renderer{ &terminal };
|
DummyRenderer renderer{ &terminal };
|
||||||
terminal.CreateFromSettings(settings, renderer);
|
terminal.CreateFromSettings(settings, renderer);
|
||||||
VERIFY_ARE_EQUAL(terminal.GetTextBuffer().TotalRowCount(), static_cast<unsigned int>(historySize + initialVisibleRowCount));
|
VERIFY_ARE_EQUAL(terminal.GetTextBuffer().TotalRowCount(), historySize + initialVisibleRowCount);
|
||||||
|
|
||||||
Log::Comment(L"Resize the terminal to have exactly SHRT_MAX lines");
|
Log::Comment(L"Resize the terminal to have exactly SHRT_MAX lines");
|
||||||
VERIFY_SUCCEEDED(terminal.UserResize({ initialVisibleColCount, initialVisibleRowCount * 2 }));
|
VERIFY_SUCCEEDED(terminal.UserResize({ initialVisibleColCount, initialVisibleRowCount * 2 }));
|
||||||
|
|
||||||
VERIFY_ARE_EQUAL(terminal.GetTextBuffer().TotalRowCount(), static_cast<unsigned int>(SHRT_MAX));
|
VERIFY_ARE_EQUAL(terminal.GetTextBuffer().TotalRowCount(), SHRT_MAX);
|
||||||
|
|
||||||
Log::Comment(L"Resize the terminal to have MORE than SHRT_MAX lines - we should clamp to SHRT_MAX");
|
Log::Comment(L"Resize the terminal to have MORE than SHRT_MAX lines - we should clamp to SHRT_MAX");
|
||||||
VERIFY_SUCCEEDED(terminal.UserResize({ initialVisibleColCount, initialVisibleRowCount * 3 }));
|
VERIFY_SUCCEEDED(terminal.UserResize({ initialVisibleColCount, initialVisibleRowCount * 3 }));
|
||||||
VERIFY_ARE_EQUAL(terminal.GetTextBuffer().TotalRowCount(), static_cast<unsigned int>(SHRT_MAX));
|
VERIFY_ARE_EQUAL(terminal.GetTextBuffer().TotalRowCount(), SHRT_MAX);
|
||||||
|
|
||||||
Log::Comment(L"Resize back down to the original size");
|
Log::Comment(L"Resize back down to the original size");
|
||||||
VERIFY_SUCCEEDED(terminal.UserResize({ initialVisibleColCount, initialVisibleRowCount }));
|
VERIFY_SUCCEEDED(terminal.UserResize({ initialVisibleColCount, initialVisibleRowCount }));
|
||||||
VERIFY_ARE_EQUAL(terminal.GetTextBuffer().TotalRowCount(), static_cast<unsigned int>(historySize + initialVisibleRowCount));
|
VERIFY_ARE_EQUAL(terminal.GetTextBuffer().TotalRowCount(), historySize + initialVisibleRowCount);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace
|
|||||||
class MockScrollRenderEngine final : public RenderEngineBase
|
class MockScrollRenderEngine final : public RenderEngineBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::optional<COORD> TriggerScrollDelta() const
|
std::optional<til::point> TriggerScrollDelta() const
|
||||||
{
|
{
|
||||||
return _triggerScrollDelta;
|
return _triggerScrollDelta;
|
||||||
}
|
}
|
||||||
@@ -44,36 +44,36 @@ namespace
|
|||||||
HRESULT Present() noexcept { return S_OK; }
|
HRESULT Present() noexcept { return S_OK; }
|
||||||
HRESULT PrepareForTeardown(_Out_ bool* /*pForcePaint*/) noexcept { return S_OK; }
|
HRESULT PrepareForTeardown(_Out_ bool* /*pForcePaint*/) noexcept { return S_OK; }
|
||||||
HRESULT ScrollFrame() noexcept { return S_OK; }
|
HRESULT ScrollFrame() noexcept { return S_OK; }
|
||||||
HRESULT Invalidate(const SMALL_RECT* /*psrRegion*/) noexcept { return S_OK; }
|
HRESULT Invalidate(const til::rect* /*psrRegion*/) noexcept { return S_OK; }
|
||||||
HRESULT InvalidateCursor(const SMALL_RECT* /*psrRegion*/) noexcept { return S_OK; }
|
HRESULT InvalidateCursor(const til::rect* /*psrRegion*/) noexcept { return S_OK; }
|
||||||
HRESULT InvalidateSystem(const RECT* /*prcDirtyClient*/) noexcept { return S_OK; }
|
HRESULT InvalidateSystem(const til::rect* /*prcDirtyClient*/) noexcept { return S_OK; }
|
||||||
HRESULT InvalidateSelection(const std::vector<SMALL_RECT>& /*rectangles*/) noexcept { return S_OK; }
|
HRESULT InvalidateSelection(const std::vector<til::rect>& /*rectangles*/) noexcept { return S_OK; }
|
||||||
HRESULT InvalidateScroll(const COORD* pcoordDelta) noexcept
|
HRESULT InvalidateScroll(const til::point* pcoordDelta) noexcept
|
||||||
{
|
{
|
||||||
_triggerScrollDelta = { *pcoordDelta };
|
_triggerScrollDelta = *pcoordDelta;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
HRESULT InvalidateAll() noexcept { return S_OK; }
|
HRESULT InvalidateAll() noexcept { return S_OK; }
|
||||||
HRESULT InvalidateCircling(_Out_ bool* /*pForcePaint*/) noexcept { return S_OK; }
|
HRESULT InvalidateCircling(_Out_ bool* /*pForcePaint*/) noexcept { return S_OK; }
|
||||||
HRESULT PaintBackground() noexcept { return S_OK; }
|
HRESULT PaintBackground() noexcept { return S_OK; }
|
||||||
HRESULT PaintBufferLine(gsl::span<const Cluster> /*clusters*/, COORD /*coord*/, bool /*fTrimLeft*/, bool /*lineWrapped*/) noexcept { return S_OK; }
|
HRESULT PaintBufferLine(gsl::span<const Cluster> /*clusters*/, til::point /*coord*/, bool /*fTrimLeft*/, bool /*lineWrapped*/) noexcept { return S_OK; }
|
||||||
HRESULT PaintBufferGridLines(GridLineSet /*lines*/, COLORREF /*color*/, size_t /*cchLine*/, COORD /*coordTarget*/) noexcept { return S_OK; }
|
HRESULT PaintBufferGridLines(GridLineSet /*lines*/, COLORREF /*color*/, size_t /*cchLine*/, til::point /*coordTarget*/) noexcept { return S_OK; }
|
||||||
HRESULT PaintSelection(SMALL_RECT /*rect*/) noexcept { return S_OK; }
|
HRESULT PaintSelection(const til::rect& /*rect*/) noexcept { return S_OK; }
|
||||||
HRESULT PaintCursor(const CursorOptions& /*options*/) noexcept { return S_OK; }
|
HRESULT PaintCursor(const CursorOptions& /*options*/) noexcept { return S_OK; }
|
||||||
HRESULT UpdateDrawingBrushes(const TextAttribute& /*textAttributes*/, const RenderSettings& /*renderSettings*/, gsl::not_null<IRenderData*> /*pData*/, bool /*usingSoftFont*/, bool /*isSettingDefaultBrushes*/) noexcept { return S_OK; }
|
HRESULT UpdateDrawingBrushes(const TextAttribute& /*textAttributes*/, const RenderSettings& /*renderSettings*/, gsl::not_null<IRenderData*> /*pData*/, bool /*usingSoftFont*/, bool /*isSettingDefaultBrushes*/) noexcept { return S_OK; }
|
||||||
HRESULT UpdateFont(const FontInfoDesired& /*FontInfoDesired*/, _Out_ FontInfo& /*FontInfo*/) noexcept { return S_OK; }
|
HRESULT UpdateFont(const FontInfoDesired& /*FontInfoDesired*/, _Out_ FontInfo& /*FontInfo*/) noexcept { return S_OK; }
|
||||||
HRESULT UpdateDpi(int /*iDpi*/) noexcept { return S_OK; }
|
HRESULT UpdateDpi(int /*iDpi*/) noexcept { return S_OK; }
|
||||||
HRESULT UpdateViewport(SMALL_RECT /*srNewViewport*/) noexcept { return S_OK; }
|
HRESULT UpdateViewport(const til::inclusive_rect& /*srNewViewport*/) noexcept { return S_OK; }
|
||||||
HRESULT GetProposedFont(const FontInfoDesired& /*FontInfoDesired*/, _Out_ FontInfo& /*FontInfo*/, int /*iDpi*/) noexcept { return S_OK; }
|
HRESULT GetProposedFont(const FontInfoDesired& /*FontInfoDesired*/, _Out_ FontInfo& /*FontInfo*/, int /*iDpi*/) noexcept { return S_OK; }
|
||||||
HRESULT GetDirtyArea(gsl::span<const til::rect>& /*area*/) noexcept { return S_OK; }
|
HRESULT GetDirtyArea(gsl::span<const til::rect>& /*area*/) noexcept { return S_OK; }
|
||||||
HRESULT GetFontSize(_Out_ COORD* /*pFontSize*/) noexcept { return S_OK; }
|
HRESULT GetFontSize(_Out_ til::size* /*pFontSize*/) noexcept { return S_OK; }
|
||||||
HRESULT IsGlyphWideByFont(std::wstring_view /*glyph*/, _Out_ bool* /*pResult*/) noexcept { return S_OK; }
|
HRESULT IsGlyphWideByFont(std::wstring_view /*glyph*/, _Out_ bool* /*pResult*/) noexcept { return S_OK; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HRESULT _DoUpdateTitle(const std::wstring_view /*newTitle*/) noexcept { return S_OK; }
|
HRESULT _DoUpdateTitle(const std::wstring_view /*newTitle*/) noexcept { return S_OK; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::optional<COORD> _triggerScrollDelta;
|
std::optional<til::point> _triggerScrollDelta;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ScrollBarNotification
|
struct ScrollBarNotification
|
||||||
@@ -95,11 +95,11 @@ class TerminalCoreUnitTests::ScrollTest final
|
|||||||
// !!! DANGER: Many tests in this class expect the Terminal buffer
|
// !!! DANGER: Many tests in this class expect the Terminal buffer
|
||||||
// to be 80x32. If you change these, you'll probably inadvertently break a
|
// to be 80x32. If you change these, you'll probably inadvertently break a
|
||||||
// bunch of tests !!!
|
// bunch of tests !!!
|
||||||
static const SHORT TerminalViewWidth = 80;
|
static const til::CoordType TerminalViewWidth = 80;
|
||||||
static const SHORT TerminalViewHeight = 32;
|
static const til::CoordType TerminalViewHeight = 32;
|
||||||
// For TestNotifyScrolling, it's important that this value is ~=9000.
|
// For TestNotifyScrolling, it's important that this value is ~=9000.
|
||||||
// Something smaller like 100 won't cause the test to fail.
|
// Something smaller like 100 won't cause the test to fail.
|
||||||
static const SHORT TerminalHistoryLength = 9001;
|
static const til::CoordType TerminalHistoryLength = 9001;
|
||||||
|
|
||||||
TEST_CLASS(ScrollTest);
|
TEST_CLASS(ScrollTest);
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@ void ScrollTest::TestNotifyScrolling()
|
|||||||
VERIFY_IS_TRUE(_renderEngine->TriggerScrollDelta().has_value(),
|
VERIFY_IS_TRUE(_renderEngine->TriggerScrollDelta().has_value(),
|
||||||
fmt::format(L"Expected a 'trigger scroll' notification in Render Engine for row {}", currentRow).c_str());
|
fmt::format(L"Expected a 'trigger scroll' notification in Render Engine for row {}", currentRow).c_str());
|
||||||
|
|
||||||
COORD expectedDelta;
|
til::point expectedDelta;
|
||||||
expectedDelta.X = 0;
|
expectedDelta.X = 0;
|
||||||
expectedDelta.Y = -1;
|
expectedDelta.Y = -1;
|
||||||
VERIFY_ARE_EQUAL(expectedDelta, _renderEngine->TriggerScrollDelta().value(), fmt::format(L"Wrong value in 'trigger scroll' notification in Render Engine for row {}", currentRow).c_str());
|
VERIFY_ARE_EQUAL(expectedDelta, _renderEngine->TriggerScrollDelta().value(), fmt::format(L"Wrong value in 'trigger scroll' notification in Render Engine for row {}", currentRow).c_str());
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ namespace TerminalCoreUnitTests
|
|||||||
// - expected: the expected value of the selection rect
|
// - expected: the expected value of the selection rect
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - N/A
|
// - N/A
|
||||||
void ValidateSingleRowSelection(Terminal& term, SMALL_RECT expected)
|
void ValidateSingleRowSelection(Terminal& term, const til::inclusive_rect& expected)
|
||||||
{
|
{
|
||||||
// Simulate renderer calling TriggerSelection and acquiring selection area
|
// Simulate renderer calling TriggerSelection and acquiring selection area
|
||||||
auto selectionRects = term.GetSelectionRects();
|
auto selectionRects = term.GetSelectionRects();
|
||||||
@@ -51,7 +51,7 @@ namespace TerminalCoreUnitTests
|
|||||||
term.Create({ 100, 100 }, 0, renderer);
|
term.Create({ 100, 100 }, 0, renderer);
|
||||||
|
|
||||||
// Simulate click at (x,y) = (5,10)
|
// Simulate click at (x,y) = (5,10)
|
||||||
auto clickPos = COORD{ 5, 10 };
|
auto clickPos = til::point{ 5, 10 };
|
||||||
term.SetSelectionAnchor(clickPos);
|
term.SetSelectionAnchor(clickPos);
|
||||||
|
|
||||||
ValidateSingleRowSelection(term, { 5, 10, 5, 10 });
|
ValidateSingleRowSelection(term, { 5, 10, 5, 10 });
|
||||||
@@ -66,7 +66,7 @@ namespace TerminalCoreUnitTests
|
|||||||
// Used for two things:
|
// Used for two things:
|
||||||
// - click y-pos
|
// - click y-pos
|
||||||
// - keep track of row we're verifying
|
// - keep track of row we're verifying
|
||||||
SHORT rowValue = 10;
|
til::CoordType rowValue = 10;
|
||||||
|
|
||||||
// Simulate click at (x,y) = (5,10)
|
// Simulate click at (x,y) = (5,10)
|
||||||
term.SetSelectionAnchor({ 5, rowValue });
|
term.SetSelectionAnchor({ 5, rowValue });
|
||||||
@@ -89,17 +89,17 @@ namespace TerminalCoreUnitTests
|
|||||||
if (rowValue == 10)
|
if (rowValue == 10)
|
||||||
{
|
{
|
||||||
// Verify top line
|
// Verify top line
|
||||||
VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 5, 10, rightBoundary, 10 }));
|
VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 5, 10, rightBoundary, 10 }));
|
||||||
}
|
}
|
||||||
else if (rowValue == 20)
|
else if (rowValue == 20)
|
||||||
{
|
{
|
||||||
// Verify bottom line
|
// Verify bottom line
|
||||||
VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 0, 20, 15, 20 }));
|
VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 0, 20, 15, 20 }));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Verify other lines (full)
|
// Verify other lines (full)
|
||||||
VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 0, rowValue, rightBoundary, rowValue }));
|
VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 0, rowValue, rightBoundary, rowValue }));
|
||||||
}
|
}
|
||||||
|
|
||||||
rowValue++;
|
rowValue++;
|
||||||
@@ -108,16 +108,16 @@ namespace TerminalCoreUnitTests
|
|||||||
|
|
||||||
TEST_METHOD(OverflowTests)
|
TEST_METHOD(OverflowTests)
|
||||||
{
|
{
|
||||||
const COORD maxCoord = { SHRT_MAX, SHRT_MAX };
|
const til::point maxCoord = { SHRT_MAX, SHRT_MAX };
|
||||||
|
|
||||||
// Test SetSelectionAnchor(COORD) and SetSelectionEnd(COORD)
|
// Test SetSelectionAnchor(til::point) and SetSelectionEnd(til::point)
|
||||||
// Behavior: clamp coord to viewport.
|
// Behavior: clamp coord to viewport.
|
||||||
auto ValidateSingleClickSelection = [&](SHORT scrollback, SMALL_RECT expected) {
|
auto ValidateSingleClickSelection = [&](til::CoordType scrollback, const til::inclusive_rect& expected) {
|
||||||
Terminal term;
|
Terminal term;
|
||||||
DummyRenderer renderer{ &term };
|
DummyRenderer renderer{ &term };
|
||||||
term.Create({ 10, 10 }, scrollback, renderer);
|
term.Create({ 10, 10 }, scrollback, renderer);
|
||||||
|
|
||||||
// NOTE: SetSelectionEnd(COORD) is called within SetSelectionAnchor(COORD)
|
// NOTE: SetSelectionEnd(til::point) is called within SetSelectionAnchor(til::point)
|
||||||
term.SetSelectionAnchor(maxCoord);
|
term.SetSelectionAnchor(maxCoord);
|
||||||
ValidateSingleRowSelection(term, expected);
|
ValidateSingleRowSelection(term, expected);
|
||||||
};
|
};
|
||||||
@@ -125,7 +125,7 @@ namespace TerminalCoreUnitTests
|
|||||||
// Test a Double Click Selection
|
// Test a Double Click Selection
|
||||||
// Behavior: clamp coord to viewport.
|
// Behavior: clamp coord to viewport.
|
||||||
// Then, do double click selection.
|
// Then, do double click selection.
|
||||||
auto ValidateDoubleClickSelection = [&](SHORT scrollback, SMALL_RECT expected) {
|
auto ValidateDoubleClickSelection = [&](til::CoordType scrollback, const til::inclusive_rect& expected) {
|
||||||
Terminal term;
|
Terminal term;
|
||||||
DummyRenderer renderer{ &term };
|
DummyRenderer renderer{ &term };
|
||||||
term.Create({ 10, 10 }, scrollback, renderer);
|
term.Create({ 10, 10 }, scrollback, renderer);
|
||||||
@@ -137,7 +137,7 @@ namespace TerminalCoreUnitTests
|
|||||||
// Test a Triple Click Selection
|
// Test a Triple Click Selection
|
||||||
// Behavior: clamp coord to viewport.
|
// Behavior: clamp coord to viewport.
|
||||||
// Then, do triple click selection.
|
// Then, do triple click selection.
|
||||||
auto ValidateTripleClickSelection = [&](SHORT scrollback, SMALL_RECT expected) {
|
auto ValidateTripleClickSelection = [&](til::CoordType scrollback, const til::inclusive_rect& expected) {
|
||||||
Terminal term;
|
Terminal term;
|
||||||
DummyRenderer renderer{ &term };
|
DummyRenderer renderer{ &term };
|
||||||
term.Create({ 10, 10 }, scrollback, renderer);
|
term.Create({ 10, 10 }, scrollback, renderer);
|
||||||
@@ -155,7 +155,7 @@ namespace TerminalCoreUnitTests
|
|||||||
ValidateTripleClickSelection(0, { 0, 9, 9, 9 });
|
ValidateTripleClickSelection(0, { 0, 9, 9, 9 });
|
||||||
|
|
||||||
// Test with max scrollback
|
// Test with max scrollback
|
||||||
const SHORT expected_row = SHRT_MAX - 1;
|
const til::CoordType expected_row = SHRT_MAX - 1;
|
||||||
Log::Comment(L"Single click selection with MAXIMUM scrollback value");
|
Log::Comment(L"Single click selection with MAXIMUM scrollback value");
|
||||||
ValidateSingleClickSelection(SHRT_MAX, { 9, expected_row, 9, expected_row });
|
ValidateSingleClickSelection(SHRT_MAX, { 9, expected_row, 9, expected_row });
|
||||||
Log::Comment(L"Double click selection with MAXIMUM scrollback value");
|
Log::Comment(L"Double click selection with MAXIMUM scrollback value");
|
||||||
@@ -218,7 +218,7 @@ namespace TerminalCoreUnitTests
|
|||||||
term.Create({ 10, 10 }, 0, renderer);
|
term.Create({ 10, 10 }, 0, renderer);
|
||||||
|
|
||||||
auto viewport = term.GetViewport();
|
auto viewport = term.GetViewport();
|
||||||
const SHORT leftBoundary = 0;
|
const til::CoordType leftBoundary = 0;
|
||||||
const auto rightBoundary = viewport.RightInclusive();
|
const auto rightBoundary = viewport.RightInclusive();
|
||||||
|
|
||||||
// Simulate click at (x,y) = (5,5)
|
// Simulate click at (x,y) = (5,5)
|
||||||
@@ -227,7 +227,7 @@ namespace TerminalCoreUnitTests
|
|||||||
// Case 1: Move out of right boundary
|
// Case 1: Move out of right boundary
|
||||||
Log::Comment(L"Out of bounds: X-value too large");
|
Log::Comment(L"Out of bounds: X-value too large");
|
||||||
term.SetSelectionEnd({ 20, 5 });
|
term.SetSelectionEnd({ 20, 5 });
|
||||||
ValidateSingleRowSelection(term, SMALL_RECT({ 5, 5, rightBoundary, 5 }));
|
ValidateSingleRowSelection(term, til::inclusive_rect({ 5, 5, rightBoundary, 5 }));
|
||||||
|
|
||||||
// Case 2: Move out of left boundary
|
// Case 2: Move out of left boundary
|
||||||
Log::Comment(L"Out of bounds: X-value negative");
|
Log::Comment(L"Out of bounds: X-value negative");
|
||||||
@@ -250,17 +250,17 @@ namespace TerminalCoreUnitTests
|
|||||||
if (rowValue == 0)
|
if (rowValue == 0)
|
||||||
{
|
{
|
||||||
// Verify top line
|
// Verify top line
|
||||||
VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 5, rowValue, rightBoundary, rowValue }));
|
VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 5, rowValue, rightBoundary, rowValue }));
|
||||||
}
|
}
|
||||||
else if (rowValue == 5)
|
else if (rowValue == 5)
|
||||||
{
|
{
|
||||||
// Verify last line
|
// Verify last line
|
||||||
VERIFY_ARE_EQUAL(selection, SMALL_RECT({ leftBoundary, rowValue, 5, rowValue }));
|
VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ leftBoundary, rowValue, 5, rowValue }));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Verify other lines (full)
|
// Verify other lines (full)
|
||||||
VERIFY_ARE_EQUAL(selection, SMALL_RECT({ leftBoundary, rowValue, rightBoundary, rowValue }));
|
VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ leftBoundary, rowValue, rightBoundary, rowValue }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -281,17 +281,17 @@ namespace TerminalCoreUnitTests
|
|||||||
if (rowValue == 5)
|
if (rowValue == 5)
|
||||||
{
|
{
|
||||||
// Verify top line
|
// Verify top line
|
||||||
VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 5, 5, rightBoundary, 5 }));
|
VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 5, 5, rightBoundary, 5 }));
|
||||||
}
|
}
|
||||||
else if (rowValue == 9)
|
else if (rowValue == 9)
|
||||||
{
|
{
|
||||||
// Verify bottom line
|
// Verify bottom line
|
||||||
VERIFY_ARE_EQUAL(selection, SMALL_RECT({ leftBoundary, rowValue, 5, rowValue }));
|
VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ leftBoundary, rowValue, 5, rowValue }));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Verify other lines (full)
|
// Verify other lines (full)
|
||||||
VERIFY_ARE_EQUAL(selection, SMALL_RECT({ leftBoundary, rowValue, rightBoundary, rowValue }));
|
VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ leftBoundary, rowValue, rightBoundary, rowValue }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -306,7 +306,7 @@ namespace TerminalCoreUnitTests
|
|||||||
// Used for two things:
|
// Used for two things:
|
||||||
// - click y-pos
|
// - click y-pos
|
||||||
// - keep track of row we're verifying
|
// - keep track of row we're verifying
|
||||||
SHORT rowValue = 10;
|
til::CoordType rowValue = 10;
|
||||||
|
|
||||||
// Simulate ALT + click at (x,y) = (5,10)
|
// Simulate ALT + click at (x,y) = (5,10)
|
||||||
term.SetSelectionAnchor({ 5, rowValue });
|
term.SetSelectionAnchor({ 5, rowValue });
|
||||||
@@ -327,7 +327,7 @@ namespace TerminalCoreUnitTests
|
|||||||
auto selection = viewport.ConvertToOrigin(selectionRect).ToInclusive();
|
auto selection = viewport.ConvertToOrigin(selectionRect).ToInclusive();
|
||||||
|
|
||||||
// Verify all lines
|
// Verify all lines
|
||||||
VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 5, rowValue, 15, rowValue }));
|
VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 5, rowValue, 15, rowValue }));
|
||||||
|
|
||||||
rowValue++;
|
rowValue++;
|
||||||
}
|
}
|
||||||
@@ -337,13 +337,13 @@ namespace TerminalCoreUnitTests
|
|||||||
{
|
{
|
||||||
Terminal term;
|
Terminal term;
|
||||||
DummyRenderer renderer{ &term };
|
DummyRenderer renderer{ &term };
|
||||||
SHORT scrollbackLines = 5;
|
til::CoordType scrollbackLines = 5;
|
||||||
term.Create({ 100, 100 }, scrollbackLines, renderer);
|
term.Create({ 100, 100 }, scrollbackLines, renderer);
|
||||||
|
|
||||||
// Used for two things:
|
// Used for two things:
|
||||||
// - click y-pos
|
// - click y-pos
|
||||||
// - keep track of row we're verifying
|
// - keep track of row we're verifying
|
||||||
SHORT rowValue = 10;
|
til::CoordType rowValue = 10;
|
||||||
|
|
||||||
// Simulate click at (x,y) = (5,10)
|
// Simulate click at (x,y) = (5,10)
|
||||||
term.SetSelectionAnchor({ 5, rowValue });
|
term.SetSelectionAnchor({ 5, rowValue });
|
||||||
@@ -366,17 +366,17 @@ namespace TerminalCoreUnitTests
|
|||||||
if (rowValue == 10)
|
if (rowValue == 10)
|
||||||
{
|
{
|
||||||
// Verify top line
|
// Verify top line
|
||||||
VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 5, 10, rightBoundary, 10 }));
|
VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 5, 10, rightBoundary, 10 }));
|
||||||
}
|
}
|
||||||
else if (rowValue == 20)
|
else if (rowValue == 20)
|
||||||
{
|
{
|
||||||
// Verify bottom line
|
// Verify bottom line
|
||||||
VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 0, 20, 15, 20 }));
|
VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 0, 20, 15, 20 }));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Verify other lines (full)
|
// Verify other lines (full)
|
||||||
VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 0, rowValue, rightBoundary, rowValue }));
|
VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 0, rowValue, rightBoundary, rowValue }));
|
||||||
}
|
}
|
||||||
|
|
||||||
rowValue++;
|
rowValue++;
|
||||||
@@ -398,7 +398,7 @@ namespace TerminalCoreUnitTests
|
|||||||
term.Write(burrito);
|
term.Write(burrito);
|
||||||
|
|
||||||
// Simulate click at (x,y) = (5,10)
|
// Simulate click at (x,y) = (5,10)
|
||||||
auto clickPos = COORD{ 5, 10 };
|
auto clickPos = til::point{ 5, 10 };
|
||||||
term.SetSelectionAnchor(clickPos);
|
term.SetSelectionAnchor(clickPos);
|
||||||
|
|
||||||
// Validate selection area
|
// Validate selection area
|
||||||
@@ -421,7 +421,7 @@ namespace TerminalCoreUnitTests
|
|||||||
term.Write(burrito);
|
term.Write(burrito);
|
||||||
|
|
||||||
// Simulate click at (x,y) = (5,10)
|
// Simulate click at (x,y) = (5,10)
|
||||||
auto clickPos = COORD{ 4, 10 };
|
auto clickPos = til::point{ 4, 10 };
|
||||||
term.SetSelectionAnchor(clickPos);
|
term.SetSelectionAnchor(clickPos);
|
||||||
|
|
||||||
// Validate selection area
|
// Validate selection area
|
||||||
@@ -461,23 +461,23 @@ namespace TerminalCoreUnitTests
|
|||||||
VERIFY_ARE_EQUAL(selectionRects.size(), static_cast<size_t>(5));
|
VERIFY_ARE_EQUAL(selectionRects.size(), static_cast<size_t>(5));
|
||||||
|
|
||||||
auto viewport = term.GetViewport();
|
auto viewport = term.GetViewport();
|
||||||
SHORT rowValue = 8;
|
til::CoordType rowValue = 8;
|
||||||
for (auto selectionRect : selectionRects)
|
for (auto selectionRect : selectionRects)
|
||||||
{
|
{
|
||||||
auto selection = viewport.ConvertToOrigin(selectionRect).ToInclusive();
|
auto selection = viewport.ConvertToOrigin(selectionRect).ToInclusive();
|
||||||
|
|
||||||
if (rowValue == 10)
|
if (rowValue == 10)
|
||||||
{
|
{
|
||||||
VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 4, rowValue, 7, rowValue }));
|
VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 4, rowValue, 7, rowValue }));
|
||||||
}
|
}
|
||||||
else if (rowValue == 11)
|
else if (rowValue == 11)
|
||||||
{
|
{
|
||||||
VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 5, rowValue, 8, rowValue }));
|
VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 5, rowValue, 8, rowValue }));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Verify all lines
|
// Verify all lines
|
||||||
VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 5, rowValue, 7, rowValue }));
|
VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 5, rowValue, 7, rowValue }));
|
||||||
}
|
}
|
||||||
|
|
||||||
rowValue++;
|
rowValue++;
|
||||||
@@ -500,11 +500,11 @@ namespace TerminalCoreUnitTests
|
|||||||
term.Write(text);
|
term.Write(text);
|
||||||
|
|
||||||
// Simulate double click at (x,y) = (5,10)
|
// Simulate double click at (x,y) = (5,10)
|
||||||
auto clickPos = COORD{ 5, 10 };
|
auto clickPos = til::point{ 5, 10 };
|
||||||
term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Word);
|
term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Word);
|
||||||
|
|
||||||
// Validate selection area
|
// Validate selection area
|
||||||
ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, (4 + gsl::narrow<SHORT>(text.size()) - 1), 10 }));
|
ValidateSingleRowSelection(term, til::inclusive_rect{ 4, 10, gsl::narrow<til::CoordType>(4 + text.size() - 1), 10 });
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(DoubleClick_Delimiter)
|
TEST_METHOD(DoubleClick_Delimiter)
|
||||||
@@ -518,14 +518,14 @@ namespace TerminalCoreUnitTests
|
|||||||
term.UpdateSettings(settings);
|
term.UpdateSettings(settings);
|
||||||
|
|
||||||
// Simulate click at (x,y) = (5,10)
|
// Simulate click at (x,y) = (5,10)
|
||||||
auto clickPos = COORD{ 5, 10 };
|
auto clickPos = til::point{ 5, 10 };
|
||||||
term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Word);
|
term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Word);
|
||||||
|
|
||||||
// Simulate renderer calling TriggerSelection and acquiring selection area
|
// Simulate renderer calling TriggerSelection and acquiring selection area
|
||||||
auto selectionRects = term.GetSelectionRects();
|
auto selectionRects = term.GetSelectionRects();
|
||||||
|
|
||||||
// Validate selection area
|
// Validate selection area
|
||||||
ValidateSingleRowSelection(term, SMALL_RECT({ 0, 10, 99, 10 }));
|
ValidateSingleRowSelection(term, til::inclusive_rect({ 0, 10, 99, 10 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(DoubleClick_DelimiterClass)
|
TEST_METHOD(DoubleClick_DelimiterClass)
|
||||||
@@ -545,7 +545,7 @@ namespace TerminalCoreUnitTests
|
|||||||
|
|
||||||
// Simulate click at (x,y) = (15,10)
|
// Simulate click at (x,y) = (15,10)
|
||||||
// this is over the '>' char
|
// this is over the '>' char
|
||||||
auto clickPos = COORD{ 15, 10 };
|
auto clickPos = til::point{ 15, 10 };
|
||||||
term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Word);
|
term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Word);
|
||||||
|
|
||||||
// ---Validate selection area---
|
// ---Validate selection area---
|
||||||
@@ -553,7 +553,7 @@ namespace TerminalCoreUnitTests
|
|||||||
// ">" is in class 1
|
// ">" is in class 1
|
||||||
// the white space to the right of the ">" is in class 0
|
// the white space to the right of the ">" is in class 0
|
||||||
// Double-clicking the ">" should only highlight that cell
|
// Double-clicking the ">" should only highlight that cell
|
||||||
ValidateSingleRowSelection(term, SMALL_RECT({ 15, 10, 15, 10 }));
|
ValidateSingleRowSelection(term, til::inclusive_rect({ 15, 10, 15, 10 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(DoubleClickDrag_Right)
|
TEST_METHOD(DoubleClickDrag_Right)
|
||||||
@@ -582,7 +582,7 @@ namespace TerminalCoreUnitTests
|
|||||||
term.SetSelectionEnd({ 21, 10 });
|
term.SetSelectionEnd({ 21, 10 });
|
||||||
|
|
||||||
// Validate selection area
|
// Validate selection area
|
||||||
ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 32, 10 }));
|
ValidateSingleRowSelection(term, til::inclusive_rect({ 4, 10, 32, 10 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(DoubleClickDrag_Left)
|
TEST_METHOD(DoubleClickDrag_Left)
|
||||||
@@ -611,7 +611,7 @@ namespace TerminalCoreUnitTests
|
|||||||
term.SetSelectionEnd({ 5, 10 });
|
term.SetSelectionEnd({ 5, 10 });
|
||||||
|
|
||||||
// Validate selection area
|
// Validate selection area
|
||||||
ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 32, 10 }));
|
ValidateSingleRowSelection(term, til::inclusive_rect({ 4, 10, 32, 10 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(TripleClick_GeneralCase)
|
TEST_METHOD(TripleClick_GeneralCase)
|
||||||
@@ -621,11 +621,11 @@ namespace TerminalCoreUnitTests
|
|||||||
term.Create({ 100, 100 }, 0, renderer);
|
term.Create({ 100, 100 }, 0, renderer);
|
||||||
|
|
||||||
// Simulate click at (x,y) = (5,10)
|
// Simulate click at (x,y) = (5,10)
|
||||||
auto clickPos = COORD{ 5, 10 };
|
auto clickPos = til::point{ 5, 10 };
|
||||||
term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Line);
|
term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Line);
|
||||||
|
|
||||||
// Validate selection area
|
// Validate selection area
|
||||||
ValidateSingleRowSelection(term, SMALL_RECT({ 0, 10, 99, 10 }));
|
ValidateSingleRowSelection(term, til::inclusive_rect({ 0, 10, 99, 10 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(TripleClickDrag_Horizontal)
|
TEST_METHOD(TripleClickDrag_Horizontal)
|
||||||
@@ -635,14 +635,14 @@ namespace TerminalCoreUnitTests
|
|||||||
term.Create({ 100, 100 }, 0, renderer);
|
term.Create({ 100, 100 }, 0, renderer);
|
||||||
|
|
||||||
// Simulate click at (x,y) = (5,10)
|
// Simulate click at (x,y) = (5,10)
|
||||||
auto clickPos = COORD{ 5, 10 };
|
auto clickPos = til::point{ 5, 10 };
|
||||||
term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Line);
|
term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Line);
|
||||||
|
|
||||||
// Simulate move to (x,y) = (7,10)
|
// Simulate move to (x,y) = (7,10)
|
||||||
term.SetSelectionEnd({ 7, 10 });
|
term.SetSelectionEnd({ 7, 10 });
|
||||||
|
|
||||||
// Validate selection area
|
// Validate selection area
|
||||||
ValidateSingleRowSelection(term, SMALL_RECT({ 0, 10, 99, 10 }));
|
ValidateSingleRowSelection(term, til::inclusive_rect({ 0, 10, 99, 10 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(TripleClickDrag_Vertical)
|
TEST_METHOD(TripleClickDrag_Vertical)
|
||||||
@@ -652,7 +652,7 @@ namespace TerminalCoreUnitTests
|
|||||||
term.Create({ 100, 100 }, 0, renderer);
|
term.Create({ 100, 100 }, 0, renderer);
|
||||||
|
|
||||||
// Simulate click at (x,y) = (5,10)
|
// Simulate click at (x,y) = (5,10)
|
||||||
auto clickPos = COORD{ 5, 10 };
|
auto clickPos = til::point{ 5, 10 };
|
||||||
term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Line);
|
term.MultiClickSelection(clickPos, Terminal::SelectionExpansion::Line);
|
||||||
|
|
||||||
// Simulate move to (x,y) = (5,11)
|
// Simulate move to (x,y) = (5,11)
|
||||||
@@ -666,11 +666,11 @@ namespace TerminalCoreUnitTests
|
|||||||
|
|
||||||
// verify first selection rect
|
// verify first selection rect
|
||||||
auto selection = term.GetViewport().ConvertToOrigin(selectionRects.at(0)).ToInclusive();
|
auto selection = term.GetViewport().ConvertToOrigin(selectionRects.at(0)).ToInclusive();
|
||||||
VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 0, 10, 99, 10 }));
|
VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 0, 10, 99, 10 }));
|
||||||
|
|
||||||
// verify second selection rect
|
// verify second selection rect
|
||||||
selection = term.GetViewport().ConvertToOrigin(selectionRects.at(1)).ToInclusive();
|
selection = term.GetViewport().ConvertToOrigin(selectionRects.at(1)).ToInclusive();
|
||||||
VERIFY_ARE_EQUAL(selection, SMALL_RECT({ 0, 11, 99, 11 }));
|
VERIFY_ARE_EQUAL(selection, til::inclusive_rect({ 0, 11, 99, 11 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(ShiftClick)
|
TEST_METHOD(ShiftClick)
|
||||||
@@ -694,7 +694,7 @@ namespace TerminalCoreUnitTests
|
|||||||
term.MultiClickSelection({ 5, 10 }, Terminal::SelectionExpansion::Word);
|
term.MultiClickSelection({ 5, 10 }, Terminal::SelectionExpansion::Word);
|
||||||
|
|
||||||
// Validate selection area: "doubleClickMe" selected
|
// Validate selection area: "doubleClickMe" selected
|
||||||
ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 16, 10 }));
|
ValidateSingleRowSelection(term, til::inclusive_rect({ 4, 10, 16, 10 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2: Shift+Click to "dragThroughHere"
|
// Step 2: Shift+Click to "dragThroughHere"
|
||||||
@@ -707,7 +707,7 @@ namespace TerminalCoreUnitTests
|
|||||||
term.SetSelectionEnd({ 21, 10 }, Terminal::SelectionExpansion::Char);
|
term.SetSelectionEnd({ 21, 10 }, Terminal::SelectionExpansion::Char);
|
||||||
|
|
||||||
// Validate selection area: "doubleClickMe drag" selected
|
// Validate selection area: "doubleClickMe drag" selected
|
||||||
ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 21, 10 }));
|
ValidateSingleRowSelection(term, til::inclusive_rect({ 4, 10, 21, 10 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 3: Shift+Double-Click at "dragThroughHere"
|
// Step 3: Shift+Double-Click at "dragThroughHere"
|
||||||
@@ -720,7 +720,7 @@ namespace TerminalCoreUnitTests
|
|||||||
term.SetSelectionEnd({ 21, 10 }, Terminal::SelectionExpansion::Word);
|
term.SetSelectionEnd({ 21, 10 }, Terminal::SelectionExpansion::Word);
|
||||||
|
|
||||||
// Validate selection area: "doubleClickMe dragThroughHere" selected
|
// Validate selection area: "doubleClickMe dragThroughHere" selected
|
||||||
ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 32, 10 }));
|
ValidateSingleRowSelection(term, til::inclusive_rect({ 4, 10, 32, 10 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 4: Shift+Triple-Click at "dragThroughHere"
|
// Step 4: Shift+Triple-Click at "dragThroughHere"
|
||||||
@@ -733,7 +733,7 @@ namespace TerminalCoreUnitTests
|
|||||||
term.SetSelectionEnd({ 21, 10 }, Terminal::SelectionExpansion::Line);
|
term.SetSelectionEnd({ 21, 10 }, Terminal::SelectionExpansion::Line);
|
||||||
|
|
||||||
// Validate selection area: "doubleClickMe dragThroughHere..." selected
|
// Validate selection area: "doubleClickMe dragThroughHere..." selected
|
||||||
ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 99, 10 }));
|
ValidateSingleRowSelection(term, til::inclusive_rect({ 4, 10, 99, 10 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 5: Shift+Double-Click at "dragThroughHere"
|
// Step 5: Shift+Double-Click at "dragThroughHere"
|
||||||
@@ -746,7 +746,7 @@ namespace TerminalCoreUnitTests
|
|||||||
term.SetSelectionEnd({ 21, 10 }, Terminal::SelectionExpansion::Word);
|
term.SetSelectionEnd({ 21, 10 }, Terminal::SelectionExpansion::Word);
|
||||||
|
|
||||||
// Validate selection area: "doubleClickMe dragThroughHere" selected
|
// Validate selection area: "doubleClickMe dragThroughHere" selected
|
||||||
ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 32, 10 }));
|
ValidateSingleRowSelection(term, til::inclusive_rect({ 4, 10, 32, 10 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 6: Drag past "dragThroughHere"
|
// Step 6: Drag past "dragThroughHere"
|
||||||
@@ -760,7 +760,7 @@ namespace TerminalCoreUnitTests
|
|||||||
term.SetSelectionEnd({ 35, 10 });
|
term.SetSelectionEnd({ 35, 10 });
|
||||||
|
|
||||||
// Validate selection area: "doubleClickMe dragThroughHere..." selected
|
// Validate selection area: "doubleClickMe dragThroughHere..." selected
|
||||||
ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 99, 10 }));
|
ValidateSingleRowSelection(term, til::inclusive_rect({ 4, 10, 99, 10 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 6: Drag back to "dragThroughHere"
|
// Step 6: Drag back to "dragThroughHere"
|
||||||
@@ -773,7 +773,7 @@ namespace TerminalCoreUnitTests
|
|||||||
term.SetSelectionEnd({ 21, 10 });
|
term.SetSelectionEnd({ 21, 10 });
|
||||||
|
|
||||||
// Validate selection area: "doubleClickMe dragThroughHere" selected
|
// Validate selection area: "doubleClickMe dragThroughHere" selected
|
||||||
ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 32, 10 }));
|
ValidateSingleRowSelection(term, til::inclusive_rect({ 4, 10, 32, 10 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 7: Drag within "dragThroughHere"
|
// Step 7: Drag within "dragThroughHere"
|
||||||
@@ -786,7 +786,7 @@ namespace TerminalCoreUnitTests
|
|||||||
term.SetSelectionEnd({ 25, 10 });
|
term.SetSelectionEnd({ 25, 10 });
|
||||||
|
|
||||||
// Validate selection area: "doubleClickMe dragThroughHere" still selected
|
// Validate selection area: "doubleClickMe dragThroughHere" still selected
|
||||||
ValidateSingleRowSelection(term, SMALL_RECT({ 4, 10, 32, 10 }));
|
ValidateSingleRowSelection(term, til::inclusive_rect({ 4, 10, 32, 10 }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -802,7 +802,7 @@ namespace TerminalCoreUnitTests
|
|||||||
term.SelectNewRegion({ 10, 10 }, { 20, 10 });
|
term.SelectNewRegion({ 10, 10 }, { 20, 10 });
|
||||||
|
|
||||||
// Validate selection area
|
// Validate selection area
|
||||||
ValidateSingleRowSelection(term, SMALL_RECT({ 10, 10, 20, 10 }));
|
ValidateSingleRowSelection(term, til::inclusive_rect({ 10, 10, 20, 10 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2: Drag to (5,10)
|
// Step 2: Drag to (5,10)
|
||||||
@@ -811,7 +811,7 @@ namespace TerminalCoreUnitTests
|
|||||||
|
|
||||||
// Validate selection area
|
// Validate selection area
|
||||||
// NOTE: Pivot should be (10, 10)
|
// NOTE: Pivot should be (10, 10)
|
||||||
ValidateSingleRowSelection(term, SMALL_RECT({ 5, 10, 10, 10 }));
|
ValidateSingleRowSelection(term, til::inclusive_rect({ 5, 10, 10, 10 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 3: Drag back to (20,10)
|
// Step 3: Drag back to (20,10)
|
||||||
@@ -820,7 +820,7 @@ namespace TerminalCoreUnitTests
|
|||||||
|
|
||||||
// Validate selection area
|
// Validate selection area
|
||||||
// NOTE: Pivot should still be (10, 10)
|
// NOTE: Pivot should still be (10, 10)
|
||||||
ValidateSingleRowSelection(term, SMALL_RECT({ 10, 10, 20, 10 }));
|
ValidateSingleRowSelection(term, til::inclusive_rect({ 10, 10, 20, 10 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 4: Shift+Click at (5,10)
|
// Step 4: Shift+Click at (5,10)
|
||||||
@@ -829,7 +829,7 @@ namespace TerminalCoreUnitTests
|
|||||||
|
|
||||||
// Validate selection area
|
// Validate selection area
|
||||||
// NOTE: Pivot should still be (10, 10)
|
// NOTE: Pivot should still be (10, 10)
|
||||||
ValidateSingleRowSelection(term, SMALL_RECT({ 5, 10, 10, 10 }));
|
ValidateSingleRowSelection(term, til::inclusive_rect({ 5, 10, 10, 10 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 5: Shift+Click back at (20,10)
|
// Step 5: Shift+Click back at (20,10)
|
||||||
@@ -838,7 +838,7 @@ namespace TerminalCoreUnitTests
|
|||||||
|
|
||||||
// Validate selection area
|
// Validate selection area
|
||||||
// NOTE: Pivot should still be (10, 10)
|
// NOTE: Pivot should still be (10, 10)
|
||||||
ValidateSingleRowSelection(term, SMALL_RECT({ 10, 10, 20, 10 }));
|
ValidateSingleRowSelection(term, til::inclusive_rect({ 10, 10, 20, 10 }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ class TerminalCoreUnitTests::TerminalBufferTests final
|
|||||||
// !!! DANGER: Many tests in this class expect the Terminal buffer
|
// !!! DANGER: Many tests in this class expect the Terminal buffer
|
||||||
// to be 80x32. If you change these, you'll probably inadvertently break a
|
// to be 80x32. If you change these, you'll probably inadvertently break a
|
||||||
// bunch of tests !!!
|
// bunch of tests !!!
|
||||||
static const SHORT TerminalViewWidth = 80;
|
static const til::CoordType TerminalViewWidth = 80;
|
||||||
static const SHORT TerminalViewHeight = 32;
|
static const til::CoordType TerminalViewHeight = 32;
|
||||||
static const SHORT TerminalHistoryLength = 100;
|
static const til::CoordType TerminalHistoryLength = 100;
|
||||||
|
|
||||||
TEST_CLASS(TerminalBufferTests);
|
TEST_CLASS(TerminalBufferTests);
|
||||||
|
|
||||||
@@ -70,8 +70,8 @@ class TerminalCoreUnitTests::TerminalBufferTests final
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _SetTabStops(std::list<short> columns, bool replace);
|
void _SetTabStops(std::list<til::CoordType> columns, bool replace);
|
||||||
std::list<short> _GetTabStops();
|
std::list<til::CoordType> _GetTabStops();
|
||||||
|
|
||||||
std::unique_ptr<DummyRenderer> emptyRenderer;
|
std::unique_ptr<DummyRenderer> emptyRenderer;
|
||||||
std::unique_ptr<Terminal> term;
|
std::unique_ptr<Terminal> term;
|
||||||
@@ -103,7 +103,7 @@ void TerminalBufferTests::TestWrappingCharByChar()
|
|||||||
const auto initialView = term->GetViewport();
|
const auto initialView = term->GetViewport();
|
||||||
auto& cursor = termTb.GetCursor();
|
auto& cursor = termTb.GetCursor();
|
||||||
|
|
||||||
const auto charsToWrite = gsl::narrow_cast<short>(TestUtils::Test100CharsString.size());
|
const auto charsToWrite = gsl::narrow_cast<til::CoordType>(TestUtils::Test100CharsString.size());
|
||||||
|
|
||||||
VERIFY_ARE_EQUAL(0, initialView.Top());
|
VERIFY_ARE_EQUAL(0, initialView.Top());
|
||||||
VERIFY_ARE_EQUAL(32, initialView.BottomExclusive());
|
VERIFY_ARE_EQUAL(32, initialView.BottomExclusive());
|
||||||
@@ -142,7 +142,7 @@ void TerminalBufferTests::TestWrappingALongString()
|
|||||||
const auto initialView = term->GetViewport();
|
const auto initialView = term->GetViewport();
|
||||||
auto& cursor = termTb.GetCursor();
|
auto& cursor = termTb.GetCursor();
|
||||||
|
|
||||||
const auto charsToWrite = gsl::narrow_cast<short>(TestUtils::Test100CharsString.size());
|
const auto charsToWrite = gsl::narrow_cast<til::CoordType>(TestUtils::Test100CharsString.size());
|
||||||
VERIFY_ARE_EQUAL(100, charsToWrite);
|
VERIFY_ARE_EQUAL(100, charsToWrite);
|
||||||
|
|
||||||
VERIFY_ARE_EQUAL(0, initialView.Top());
|
VERIFY_ARE_EQUAL(0, initialView.Top());
|
||||||
@@ -251,7 +251,7 @@ void TerminalBufferTests::DontSnapToOutputTest()
|
|||||||
VERIFY_ARE_EQUAL(TerminalHistoryLength, term->_scrollOffset);
|
VERIFY_ARE_EQUAL(TerminalHistoryLength, term->_scrollOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TerminalBufferTests::_SetTabStops(std::list<short> columns, bool replace)
|
void TerminalBufferTests::_SetTabStops(std::list<til::CoordType> columns, bool replace)
|
||||||
{
|
{
|
||||||
auto& termTb = *term->_mainBuffer;
|
auto& termTb = *term->_mainBuffer;
|
||||||
auto& termSm = *term->_stateMachine;
|
auto& termSm = *term->_stateMachine;
|
||||||
@@ -272,9 +272,9 @@ void TerminalBufferTests::_SetTabStops(std::list<short> columns, bool replace)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<short> TerminalBufferTests::_GetTabStops()
|
std::list<til::CoordType> TerminalBufferTests::_GetTabStops()
|
||||||
{
|
{
|
||||||
std::list<short> columns;
|
std::list<til::CoordType> columns;
|
||||||
auto& termTb = *term->_mainBuffer;
|
auto& termTb = *term->_mainBuffer;
|
||||||
auto& termSm = *term->_stateMachine;
|
auto& termSm = *term->_stateMachine;
|
||||||
const auto initialView = term->GetViewport();
|
const auto initialView = term->GetViewport();
|
||||||
@@ -305,7 +305,7 @@ void TerminalBufferTests::TestResetClearTabStops()
|
|||||||
const auto resetToInitialState = L"\033c";
|
const auto resetToInitialState = L"\033c";
|
||||||
|
|
||||||
Log::Comment(L"Default tabs every 8 columns.");
|
Log::Comment(L"Default tabs every 8 columns.");
|
||||||
std::list<short> expectedStops{ 8, 16, 24, 32, 40, 48, 56, 64, 72 };
|
std::list<til::CoordType> expectedStops{ 8, 16, 24, 32, 40, 48, 56, 64, 72 };
|
||||||
VERIFY_ARE_EQUAL(expectedStops, _GetTabStops());
|
VERIFY_ARE_EQUAL(expectedStops, _GetTabStops());
|
||||||
|
|
||||||
Log::Comment(L"Clear all tabs.");
|
Log::Comment(L"Clear all tabs.");
|
||||||
@@ -330,7 +330,7 @@ void TerminalBufferTests::TestAddTabStop()
|
|||||||
|
|
||||||
Log::Comment(L"Clear all tabs.");
|
Log::Comment(L"Clear all tabs.");
|
||||||
termSm.ProcessString(clearTabStops);
|
termSm.ProcessString(clearTabStops);
|
||||||
std::list<short> expectedStops{};
|
std::list<til::CoordType> expectedStops{};
|
||||||
VERIFY_ARE_EQUAL(expectedStops, _GetTabStops());
|
VERIFY_ARE_EQUAL(expectedStops, _GetTabStops());
|
||||||
|
|
||||||
Log::Comment(L"Add tab to empty list.");
|
Log::Comment(L"Add tab to empty list.");
|
||||||
@@ -419,7 +419,7 @@ void TerminalBufferTests::TestClearTabStop()
|
|||||||
|
|
||||||
Log::Comment(L"Allocate many (5) list items and clear head.");
|
Log::Comment(L"Allocate many (5) list items and clear head.");
|
||||||
{
|
{
|
||||||
std::list<short> inputData = { 3, 5, 6, 10, 15, 17 };
|
std::list<til::CoordType> inputData = { 3, 5, 6, 10, 15, 17 };
|
||||||
_SetTabStops(inputData, false);
|
_SetTabStops(inputData, false);
|
||||||
cursor.SetXPosition(inputData.front());
|
cursor.SetXPosition(inputData.front());
|
||||||
termSm.ProcessString(clearTabStop);
|
termSm.ProcessString(clearTabStop);
|
||||||
@@ -433,7 +433,7 @@ void TerminalBufferTests::TestClearTabStop()
|
|||||||
|
|
||||||
Log::Comment(L"Allocate many (5) list items and clear middle.");
|
Log::Comment(L"Allocate many (5) list items and clear middle.");
|
||||||
{
|
{
|
||||||
std::list<short> inputData = { 3, 5, 6, 10, 15, 17 };
|
std::list<til::CoordType> inputData = { 3, 5, 6, 10, 15, 17 };
|
||||||
_SetTabStops(inputData, false);
|
_SetTabStops(inputData, false);
|
||||||
cursor.SetXPosition(*std::next(inputData.begin()));
|
cursor.SetXPosition(*std::next(inputData.begin()));
|
||||||
termSm.ProcessString(clearTabStop);
|
termSm.ProcessString(clearTabStop);
|
||||||
@@ -447,7 +447,7 @@ void TerminalBufferTests::TestClearTabStop()
|
|||||||
|
|
||||||
Log::Comment(L"Allocate many (5) list items and clear tail.");
|
Log::Comment(L"Allocate many (5) list items and clear tail.");
|
||||||
{
|
{
|
||||||
std::list<short> inputData = { 3, 5, 6, 10, 15, 17 };
|
std::list<til::CoordType> inputData = { 3, 5, 6, 10, 15, 17 };
|
||||||
_SetTabStops(inputData, false);
|
_SetTabStops(inputData, false);
|
||||||
cursor.SetXPosition(inputData.back());
|
cursor.SetXPosition(inputData.back());
|
||||||
termSm.ProcessString(clearTabStop);
|
termSm.ProcessString(clearTabStop);
|
||||||
@@ -461,7 +461,7 @@ void TerminalBufferTests::TestClearTabStop()
|
|||||||
|
|
||||||
Log::Comment(L"Allocate many (5) list items and clear nonexistent item.");
|
Log::Comment(L"Allocate many (5) list items and clear nonexistent item.");
|
||||||
{
|
{
|
||||||
std::list<short> inputData = { 3, 5, 6, 10, 15, 17 };
|
std::list<til::CoordType> inputData = { 3, 5, 6, 10, 15, 17 };
|
||||||
_SetTabStops(inputData, false);
|
_SetTabStops(inputData, false);
|
||||||
cursor.SetXPosition(0);
|
cursor.SetXPosition(0);
|
||||||
termSm.ProcessString(clearTabStop);
|
termSm.ProcessString(clearTabStop);
|
||||||
@@ -482,7 +482,7 @@ void TerminalBufferTests::TestGetForwardTab()
|
|||||||
|
|
||||||
const auto nextForwardTab = L"\033[I";
|
const auto nextForwardTab = L"\033[I";
|
||||||
|
|
||||||
std::list<short> inputData = { 3, 5, 6, 10, 15, 17 };
|
std::list<til::CoordType> inputData = { 3, 5, 6, 10, 15, 17 };
|
||||||
_SetTabStops(inputData, true);
|
_SetTabStops(inputData, true);
|
||||||
|
|
||||||
const auto coordScreenBufferSize = initialView.Dimensions();
|
const auto coordScreenBufferSize = initialView.Dimensions();
|
||||||
@@ -551,7 +551,7 @@ void TerminalBufferTests::TestGetReverseTab()
|
|||||||
|
|
||||||
const auto nextReverseTab = L"\033[Z";
|
const auto nextReverseTab = L"\033[Z";
|
||||||
|
|
||||||
std::list<short> inputData = { 3, 5, 6, 10, 15, 17 };
|
std::list<til::CoordType> inputData = { 3, 5, 6, 10, 15, 17 };
|
||||||
_SetTabStops(inputData, true);
|
_SetTabStops(inputData, true);
|
||||||
|
|
||||||
Log::Comment(L"Find previous tab from before front.");
|
Log::Comment(L"Find previous tab from before front.");
|
||||||
|
|||||||
@@ -549,21 +549,21 @@ LaunchPosition AppHost::_GetWindowLaunchPosition()
|
|||||||
// - launchMode: A LaunchMode enum reference that indicates the launch mode
|
// - launchMode: A LaunchMode enum reference that indicates the launch mode
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - None
|
// - None
|
||||||
void AppHost::_HandleCreateWindow(const HWND hwnd, RECT proposedRect, LaunchMode& launchMode)
|
void AppHost::_HandleCreateWindow(const HWND hwnd, til::rect proposedRect, LaunchMode& launchMode)
|
||||||
{
|
{
|
||||||
launchMode = _logic.GetLaunchMode();
|
launchMode = _logic.GetLaunchMode();
|
||||||
|
|
||||||
// Acquire the actual initial position
|
// Acquire the actual initial position
|
||||||
auto initialPos = _logic.GetInitialPosition(proposedRect.left, proposedRect.top);
|
auto initialPos = _logic.GetInitialPosition(proposedRect.left, proposedRect.top);
|
||||||
const auto centerOnLaunch = _logic.CenterOnLaunch();
|
const auto centerOnLaunch = _logic.CenterOnLaunch();
|
||||||
proposedRect.left = static_cast<long>(initialPos.X);
|
proposedRect.left = gsl::narrow<til::CoordType>(initialPos.X);
|
||||||
proposedRect.top = static_cast<long>(initialPos.Y);
|
proposedRect.top = gsl::narrow<til::CoordType>(initialPos.Y);
|
||||||
|
|
||||||
long adjustedHeight = 0;
|
long adjustedHeight = 0;
|
||||||
long adjustedWidth = 0;
|
long adjustedWidth = 0;
|
||||||
|
|
||||||
// Find nearest monitor.
|
// Find nearest monitor.
|
||||||
auto hmon = MonitorFromRect(&proposedRect, MONITOR_DEFAULTTONEAREST);
|
auto hmon = MonitorFromRect(proposedRect.as_win32_rect(), MONITOR_DEFAULTTONEAREST);
|
||||||
|
|
||||||
// Get nearest monitor information
|
// Get nearest monitor information
|
||||||
MONITORINFO monitorInfo;
|
MONITORINFO monitorInfo;
|
||||||
@@ -620,13 +620,13 @@ void AppHost::_HandleCreateWindow(const HWND hwnd, RECT proposedRect, LaunchMode
|
|||||||
Utils::ClampToShortMax(adjustedHeight, 1) };
|
Utils::ClampToShortMax(adjustedHeight, 1) };
|
||||||
|
|
||||||
// Find nearest monitor for the position that we've actually settled on
|
// Find nearest monitor for the position that we've actually settled on
|
||||||
auto hMonNearest = MonitorFromRect(&proposedRect, MONITOR_DEFAULTTONEAREST);
|
auto hMonNearest = MonitorFromRect(proposedRect.as_win32_rect(), MONITOR_DEFAULTTONEAREST);
|
||||||
MONITORINFO nearestMonitorInfo;
|
MONITORINFO nearestMonitorInfo;
|
||||||
nearestMonitorInfo.cbSize = sizeof(MONITORINFO);
|
nearestMonitorInfo.cbSize = sizeof(MONITORINFO);
|
||||||
// Get monitor dimensions:
|
// Get monitor dimensions:
|
||||||
GetMonitorInfo(hMonNearest, &nearestMonitorInfo);
|
GetMonitorInfo(hMonNearest, &nearestMonitorInfo);
|
||||||
const til::size desktopDimensions{ gsl::narrow<short>(nearestMonitorInfo.rcWork.right - nearestMonitorInfo.rcWork.left),
|
const til::size desktopDimensions{ nearestMonitorInfo.rcWork.right - nearestMonitorInfo.rcWork.left,
|
||||||
gsl::narrow<short>(nearestMonitorInfo.rcWork.bottom - nearestMonitorInfo.rcWork.top) };
|
nearestMonitorInfo.rcWork.bottom - nearestMonitorInfo.rcWork.top };
|
||||||
|
|
||||||
// GH#10583 - Adjust the position of the rectangle to account for the size
|
// GH#10583 - Adjust the position of the rectangle to account for the size
|
||||||
// of the invisible borders on the left/right. We DON'T want to adjust this
|
// of the invisible borders on the left/right. We DON'T want to adjust this
|
||||||
@@ -642,11 +642,11 @@ void AppHost::_HandleCreateWindow(const HWND hwnd, RECT proposedRect, LaunchMode
|
|||||||
// space reserved for the resize handles. So retrieve that size here.
|
// space reserved for the resize handles. So retrieve that size here.
|
||||||
const auto availableSpace = desktopDimensions + nonClientSize;
|
const auto availableSpace = desktopDimensions + nonClientSize;
|
||||||
|
|
||||||
origin = til::point{
|
origin = {
|
||||||
::base::ClampSub(nearestMonitorInfo.rcWork.left, (nonClientSize.width / 2)),
|
(nearestMonitorInfo.rcWork.left - (nonClientSize.width / 2)),
|
||||||
(nearestMonitorInfo.rcWork.top)
|
(nearestMonitorInfo.rcWork.top)
|
||||||
};
|
};
|
||||||
dimensions = til::size{
|
dimensions = {
|
||||||
availableSpace.width,
|
availableSpace.width,
|
||||||
availableSpace.height / 2
|
availableSpace.height / 2
|
||||||
};
|
};
|
||||||
@@ -655,7 +655,7 @@ void AppHost::_HandleCreateWindow(const HWND hwnd, RECT proposedRect, LaunchMode
|
|||||||
else if (centerOnLaunch)
|
else if (centerOnLaunch)
|
||||||
{
|
{
|
||||||
// Move our proposed location into the center of that specific monitor.
|
// Move our proposed location into the center of that specific monitor.
|
||||||
origin = til::point{
|
origin = {
|
||||||
(nearestMonitorInfo.rcWork.left + ((desktopDimensions.width / 2) - (dimensions.width / 2))),
|
(nearestMonitorInfo.rcWork.left + ((desktopDimensions.width / 2) - (dimensions.width / 2))),
|
||||||
(nearestMonitorInfo.rcWork.top + ((desktopDimensions.height / 2) - (dimensions.height / 2)))
|
(nearestMonitorInfo.rcWork.top + ((desktopDimensions.height / 2) - (dimensions.height / 2)))
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ private:
|
|||||||
void _HandleCommandlineArgs();
|
void _HandleCommandlineArgs();
|
||||||
winrt::Microsoft::Terminal::Settings::Model::LaunchPosition _GetWindowLaunchPosition();
|
winrt::Microsoft::Terminal::Settings::Model::LaunchPosition _GetWindowLaunchPosition();
|
||||||
|
|
||||||
void _HandleCreateWindow(const HWND hwnd, RECT proposedRect, winrt::Microsoft::Terminal::Settings::Model::LaunchMode& launchMode);
|
void _HandleCreateWindow(const HWND hwnd, til::rect proposedRect, winrt::Microsoft::Terminal::Settings::Model::LaunchMode& launchMode);
|
||||||
void _UpdateTitleBarContent(const winrt::Windows::Foundation::IInspectable& sender,
|
void _UpdateTitleBarContent(const winrt::Windows::Foundation::IInspectable& sender,
|
||||||
const winrt::Windows::UI::Xaml::UIElement& arg);
|
const winrt::Windows::UI::Xaml::UIElement& arg);
|
||||||
void _UpdateTheme(const winrt::Windows::Foundation::IInspectable&,
|
void _UpdateTheme(const winrt::Windows::Foundation::IInspectable&,
|
||||||
|
|||||||
@@ -146,13 +146,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//// Gets the physical size of the client area of the HWND in _window
|
//// Gets the physical size of the client area of the HWND in _window
|
||||||
SIZE GetPhysicalSize() const noexcept
|
til::size GetPhysicalSize() const noexcept
|
||||||
{
|
{
|
||||||
RECT rect = {};
|
RECT rect = {};
|
||||||
GetClientRect(_window.get(), &rect);
|
GetClientRect(_window.get(), &rect);
|
||||||
const auto windowsWidth = rect.right - rect.left;
|
const auto windowsWidth = rect.right - rect.left;
|
||||||
const auto windowsHeight = rect.bottom - rect.top;
|
const auto windowsHeight = rect.bottom - rect.top;
|
||||||
return SIZE{ windowsWidth, windowsHeight };
|
return { windowsWidth, windowsHeight };
|
||||||
}
|
}
|
||||||
|
|
||||||
//// Gets the logical (in DIPs) size of a physical size specified by the parameter physicalSize
|
//// Gets the logical (in DIPs) size of a physical size specified by the parameter physicalSize
|
||||||
@@ -164,7 +164,7 @@ public:
|
|||||||
//// See also:
|
//// See also:
|
||||||
//// https://docs.microsoft.com/en-us/windows/desktop/LearnWin32/dpi-and-device-independent-pixels
|
//// https://docs.microsoft.com/en-us/windows/desktop/LearnWin32/dpi-and-device-independent-pixels
|
||||||
//// https://docs.microsoft.com/en-us/windows/desktop/hidpi/high-dpi-desktop-application-development-on-windows#per-monitor-and-per-monitor-v2-dpi-awareness
|
//// https://docs.microsoft.com/en-us/windows/desktop/hidpi/high-dpi-desktop-application-development-on-windows#per-monitor-and-per-monitor-v2-dpi-awareness
|
||||||
winrt::Windows::Foundation::Size GetLogicalSize(const SIZE physicalSize) const noexcept
|
winrt::Windows::Foundation::Size GetLogicalSize(const til::size physicalSize) const noexcept
|
||||||
{
|
{
|
||||||
const auto scale = GetCurrentDpiScale();
|
const auto scale = GetCurrentDpiScale();
|
||||||
// 0.5 is to ensure that we pixel snap correctly at the edges, this is necessary with odd DPIs like 1.25, 1.5, 1, .75
|
// 0.5 is to ensure that we pixel snap correctly at the edges, this is necessary with odd DPIs like 1.25, 1.5, 1, .75
|
||||||
|
|||||||
@@ -108,11 +108,11 @@ void IslandWindow::Close()
|
|||||||
// - pfn: a function to be called during the handling of WM_CREATE. It takes two
|
// - pfn: a function to be called during the handling of WM_CREATE. It takes two
|
||||||
// parameters:
|
// parameters:
|
||||||
// * HWND: the HWND of the window that's being created.
|
// * HWND: the HWND of the window that's being created.
|
||||||
// * RECT: The position on the screen that the system has proposed for our
|
// * til::rect: The position on the screen that the system has proposed for our
|
||||||
// window.
|
// window.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - <none>
|
// - <none>
|
||||||
void IslandWindow::SetCreateCallback(std::function<void(const HWND, const RECT, LaunchMode& launchMode)> pfn) noexcept
|
void IslandWindow::SetCreateCallback(std::function<void(const HWND, const til::rect&, LaunchMode& launchMode)> pfn) noexcept
|
||||||
{
|
{
|
||||||
_pfnCreateCallback = pfn;
|
_pfnCreateCallback = pfn;
|
||||||
}
|
}
|
||||||
@@ -148,7 +148,7 @@ void IslandWindow::_HandleCreateWindow(const WPARAM, const LPARAM lParam) noexce
|
|||||||
{
|
{
|
||||||
// Get proposed window rect from create structure
|
// Get proposed window rect from create structure
|
||||||
auto pcs = reinterpret_cast<CREATESTRUCTW*>(lParam);
|
auto pcs = reinterpret_cast<CREATESTRUCTW*>(lParam);
|
||||||
RECT rc;
|
til::rect rc;
|
||||||
rc.left = pcs->x;
|
rc.left = pcs->x;
|
||||||
rc.top = pcs->y;
|
rc.top = pcs->y;
|
||||||
rc.right = rc.left + pcs->cx;
|
rc.right = rc.left + pcs->cx;
|
||||||
@@ -713,9 +713,9 @@ void IslandWindow::SetContent(winrt::Windows::UI::Xaml::UIElement content)
|
|||||||
// Arguments:
|
// Arguments:
|
||||||
// - dpi: the scaling that we should use to calculate the border sizes.
|
// - dpi: the scaling that we should use to calculate the border sizes.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - a RECT whose components represent the margins of the nonclient area,
|
// - a til::rect whose components represent the margins of the nonclient area,
|
||||||
// relative to the client area.
|
// relative to the client area.
|
||||||
RECT IslandWindow::GetNonClientFrame(const UINT dpi) const noexcept
|
til::rect IslandWindow::GetNonClientFrame(const UINT dpi) const noexcept
|
||||||
{
|
{
|
||||||
const auto windowStyle = static_cast<DWORD>(GetWindowLong(_window.get(), GWL_STYLE));
|
const auto windowStyle = static_cast<DWORD>(GetWindowLong(_window.get(), GWL_STYLE));
|
||||||
RECT islandFrame{};
|
RECT islandFrame{};
|
||||||
@@ -724,7 +724,7 @@ RECT IslandWindow::GetNonClientFrame(const UINT dpi) const noexcept
|
|||||||
// the error and go on. We'll use whatever the control proposed as the
|
// the error and go on. We'll use whatever the control proposed as the
|
||||||
// size of our window, which will be at least close.
|
// size of our window, which will be at least close.
|
||||||
LOG_IF_WIN32_BOOL_FALSE(AdjustWindowRectExForDpi(&islandFrame, windowStyle, false, 0, dpi));
|
LOG_IF_WIN32_BOOL_FALSE(AdjustWindowRectExForDpi(&islandFrame, windowStyle, false, 0, dpi));
|
||||||
return islandFrame;
|
return til::rect{ islandFrame };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
@@ -733,7 +733,7 @@ RECT IslandWindow::GetNonClientFrame(const UINT dpi) const noexcept
|
|||||||
// - dpi: dpi of a monitor on which the window is placed
|
// - dpi: dpi of a monitor on which the window is placed
|
||||||
// Return Value
|
// Return Value
|
||||||
// - The size difference
|
// - The size difference
|
||||||
SIZE IslandWindow::GetTotalNonClientExclusiveSize(const UINT dpi) const noexcept
|
til::size IslandWindow::GetTotalNonClientExclusiveSize(const UINT dpi) const noexcept
|
||||||
{
|
{
|
||||||
const auto islandFrame{ GetNonClientFrame(dpi) };
|
const auto islandFrame{ GetNonClientFrame(dpi) };
|
||||||
return {
|
return {
|
||||||
@@ -1015,7 +1015,7 @@ void IslandWindow::_SetIsBorderless(const bool borderlessEnabled)
|
|||||||
// - Called when entering fullscreen, with the window's current monitor rect and work area.
|
// - Called when entering fullscreen, with the window's current monitor rect and work area.
|
||||||
// - The current window position, dpi, work area, and maximized state are stored, and the
|
// - The current window position, dpi, work area, and maximized state are stored, and the
|
||||||
// window is positioned to the monitor rect.
|
// window is positioned to the monitor rect.
|
||||||
void IslandWindow::_SetFullscreenPosition(const RECT rcMonitor, const RECT rcWork)
|
void IslandWindow::_SetFullscreenPosition(const RECT& rcMonitor, const RECT& rcWork)
|
||||||
{
|
{
|
||||||
const auto hWnd = GetHandle();
|
const auto hWnd = GetHandle();
|
||||||
|
|
||||||
@@ -1039,7 +1039,7 @@ void IslandWindow::_SetFullscreenPosition(const RECT rcMonitor, const RECT rcWor
|
|||||||
// window's current monitor (if the current work area or window DPI have changed).
|
// window's current monitor (if the current work area or window DPI have changed).
|
||||||
// - A fullscreen window's monitor can be changed by win+shift+left/right hotkeys or monitor
|
// - A fullscreen window's monitor can be changed by win+shift+left/right hotkeys or monitor
|
||||||
// topology changes (for example unplugging a monitor or disconnecting a remote session).
|
// topology changes (for example unplugging a monitor or disconnecting a remote session).
|
||||||
void IslandWindow::_RestoreFullscreenPosition(const RECT rcWork)
|
void IslandWindow::_RestoreFullscreenPosition(const RECT& rcWork)
|
||||||
{
|
{
|
||||||
const auto hWnd = GetHandle();
|
const auto hWnd = GetHandle();
|
||||||
|
|
||||||
@@ -1698,7 +1698,7 @@ til::rect IslandWindow::_getQuakeModeSize(HMONITOR hmon)
|
|||||||
availableSpace.height / 2
|
availableSpace.height / 2
|
||||||
};
|
};
|
||||||
|
|
||||||
return til::rect{ origin, dimensions };
|
return { origin, dimensions };
|
||||||
}
|
}
|
||||||
|
|
||||||
void IslandWindow::HideWindow()
|
void IslandWindow::HideWindow()
|
||||||
|
|||||||
@@ -32,12 +32,12 @@ public:
|
|||||||
virtual void OnAppInitialized();
|
virtual void OnAppInitialized();
|
||||||
virtual void SetContent(winrt::Windows::UI::Xaml::UIElement content);
|
virtual void SetContent(winrt::Windows::UI::Xaml::UIElement content);
|
||||||
virtual void OnApplicationThemeChanged(const winrt::Windows::UI::Xaml::ElementTheme& requestedTheme);
|
virtual void OnApplicationThemeChanged(const winrt::Windows::UI::Xaml::ElementTheme& requestedTheme);
|
||||||
virtual RECT GetNonClientFrame(const UINT dpi) const noexcept;
|
virtual til::rect GetNonClientFrame(const UINT dpi) const noexcept;
|
||||||
virtual SIZE GetTotalNonClientExclusiveSize(const UINT dpi) const noexcept;
|
virtual til::size GetTotalNonClientExclusiveSize(const UINT dpi) const noexcept;
|
||||||
|
|
||||||
virtual void Initialize();
|
virtual void Initialize();
|
||||||
|
|
||||||
void SetCreateCallback(std::function<void(const HWND, const RECT, winrt::Microsoft::Terminal::Settings::Model::LaunchMode& launchMode)> pfn) noexcept;
|
void SetCreateCallback(std::function<void(const HWND, const til::rect&, winrt::Microsoft::Terminal::Settings::Model::LaunchMode& launchMode)> pfn) noexcept;
|
||||||
void SetSnapDimensionCallback(std::function<float(bool widthOrHeight, float dimension)> pfn) noexcept;
|
void SetSnapDimensionCallback(std::function<float(bool widthOrHeight, float dimension)> pfn) noexcept;
|
||||||
|
|
||||||
void FocusModeChanged(const bool focusMode);
|
void FocusModeChanged(const bool focusMode);
|
||||||
@@ -94,7 +94,7 @@ protected:
|
|||||||
winrt::Windows::UI::Xaml::Controls::Grid _rootGrid;
|
winrt::Windows::UI::Xaml::Controls::Grid _rootGrid;
|
||||||
wil::com_ptr<ITaskbarList3> _taskbar;
|
wil::com_ptr<ITaskbarList3> _taskbar;
|
||||||
|
|
||||||
std::function<void(const HWND, const RECT, winrt::Microsoft::Terminal::Settings::Model::LaunchMode& launchMode)> _pfnCreateCallback;
|
std::function<void(const HWND, const til::rect&, winrt::Microsoft::Terminal::Settings::Model::LaunchMode& launchMode)> _pfnCreateCallback;
|
||||||
std::function<float(bool, float)> _pfnSnapDimensionCallback;
|
std::function<float(bool, float)> _pfnSnapDimensionCallback;
|
||||||
|
|
||||||
void _HandleCreateWindow(const WPARAM wParam, const LPARAM lParam) noexcept;
|
void _HandleCreateWindow(const WPARAM wParam, const LPARAM lParam) noexcept;
|
||||||
@@ -111,8 +111,8 @@ protected:
|
|||||||
|
|
||||||
virtual void _SetIsBorderless(const bool borderlessEnabled);
|
virtual void _SetIsBorderless(const bool borderlessEnabled);
|
||||||
virtual void _SetIsFullscreen(const bool fullscreenEnabled);
|
virtual void _SetIsFullscreen(const bool fullscreenEnabled);
|
||||||
void _RestoreFullscreenPosition(const RECT rcWork);
|
void _RestoreFullscreenPosition(const RECT& rcWork);
|
||||||
void _SetFullscreenPosition(const RECT rcMonitor, const RECT rcWork);
|
void _SetFullscreenPosition(const RECT& rcMonitor, const RECT& rcWork);
|
||||||
|
|
||||||
LONG _getDesiredWindowStyle() const;
|
LONG _getDesiredWindowStyle() const;
|
||||||
|
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ LRESULT NonClientIslandWindow::_InputSinkMessageHandler(UINT const message,
|
|||||||
{
|
{
|
||||||
// Try to determine what part of the window is being hovered here. This
|
// Try to determine what part of the window is being hovered here. This
|
||||||
// is absolutely critical to making sure Snap Layouts (GH#9443) works!
|
// is absolutely critical to making sure Snap Layouts (GH#9443) works!
|
||||||
return _dragBarNcHitTest(til::point{ GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam) });
|
return _dragBarNcHitTest({ GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam) });
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -425,7 +425,7 @@ int NonClientIslandWindow::_GetTopBorderHeight() const noexcept
|
|||||||
return topBorderVisibleHeight;
|
return topBorderVisibleHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
RECT NonClientIslandWindow::_GetDragAreaRect() const noexcept
|
til::rect NonClientIslandWindow::_GetDragAreaRect() const noexcept
|
||||||
{
|
{
|
||||||
if (_dragBar && _dragBar.Visibility() == Visibility::Visible)
|
if (_dragBar && _dragBar.Visibility() == Visibility::Visible)
|
||||||
{
|
{
|
||||||
@@ -445,16 +445,15 @@ RECT NonClientIslandWindow::_GetDragAreaRect() const noexcept
|
|||||||
static_cast<float>(_dragBar.ActualHeight())
|
static_cast<float>(_dragBar.ActualHeight())
|
||||||
};
|
};
|
||||||
const auto clientDragBarRect = transform.TransformBounds(logicalDragBarRect);
|
const auto clientDragBarRect = transform.TransformBounds(logicalDragBarRect);
|
||||||
RECT dragBarRect = {
|
return {
|
||||||
static_cast<LONG>(clientDragBarRect.X * scale),
|
gsl::narrow_cast<til::CoordType>(clientDragBarRect.X * scale),
|
||||||
static_cast<LONG>(clientDragBarRect.Y * scale),
|
gsl::narrow_cast<til::CoordType>(clientDragBarRect.Y * scale),
|
||||||
static_cast<LONG>((clientDragBarRect.Width + clientDragBarRect.X) * scale),
|
gsl::narrow_cast<til::CoordType>((clientDragBarRect.Width + clientDragBarRect.X) * scale),
|
||||||
static_cast<LONG>((clientDragBarRect.Height + clientDragBarRect.Y) * scale),
|
gsl::narrow_cast<til::CoordType>((clientDragBarRect.Height + clientDragBarRect.Y) * scale),
|
||||||
};
|
};
|
||||||
return dragBarRect;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return RECT{};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
@@ -539,9 +538,9 @@ void NonClientIslandWindow::_UpdateIslandPosition(const UINT windowWidth, const
|
|||||||
// buttons, which will make them clickable. It's perhaps not the right fix,
|
// buttons, which will make them clickable. It's perhaps not the right fix,
|
||||||
// but it works.
|
// but it works.
|
||||||
// _GetTopBorderHeight() returns 0 when we're maximized.
|
// _GetTopBorderHeight() returns 0 when we're maximized.
|
||||||
const auto topBorderHeight = ::base::saturated_cast<short>((originalTopHeight == 0) ? -1 : originalTopHeight);
|
const auto topBorderHeight = (originalTopHeight == 0) ? -1 : originalTopHeight;
|
||||||
|
|
||||||
const COORD newIslandPos = { 0, topBorderHeight };
|
const til::point newIslandPos = { 0, topBorderHeight };
|
||||||
|
|
||||||
winrt::check_bool(SetWindowPos(_interopWindowHandle,
|
winrt::check_bool(SetWindowPos(_interopWindowHandle,
|
||||||
HWND_BOTTOM,
|
HWND_BOTTOM,
|
||||||
@@ -807,17 +806,17 @@ int NonClientIslandWindow::_GetResizeHandleHeight() const noexcept
|
|||||||
// Arguments:
|
// Arguments:
|
||||||
// - dpi: the scaling that we should use to calculate the border sizes.
|
// - dpi: the scaling that we should use to calculate the border sizes.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - a RECT whose components represent the margins of the nonclient area,
|
// - a til::rect whose components represent the margins of the nonclient area,
|
||||||
// relative to the client area.
|
// relative to the client area.
|
||||||
RECT NonClientIslandWindow::GetNonClientFrame(UINT dpi) const noexcept
|
til::rect NonClientIslandWindow::GetNonClientFrame(UINT dpi) const noexcept
|
||||||
{
|
{
|
||||||
const auto windowStyle = static_cast<DWORD>(GetWindowLong(_window.get(), GWL_STYLE));
|
const auto windowStyle = static_cast<DWORD>(GetWindowLong(_window.get(), GWL_STYLE));
|
||||||
RECT islandFrame{};
|
til::rect islandFrame;
|
||||||
|
|
||||||
// If we failed to get the correct window size for whatever reason, log
|
// If we failed to get the correct window size for whatever reason, log
|
||||||
// the error and go on. We'll use whatever the control proposed as the
|
// the error and go on. We'll use whatever the control proposed as the
|
||||||
// size of our window, which will be at least close.
|
// size of our window, which will be at least close.
|
||||||
LOG_IF_WIN32_BOOL_FALSE(AdjustWindowRectExForDpi(&islandFrame, windowStyle, false, 0, dpi));
|
LOG_IF_WIN32_BOOL_FALSE(AdjustWindowRectExForDpi(islandFrame.as_win32_rect(), windowStyle, false, 0, dpi));
|
||||||
|
|
||||||
islandFrame.top = -topBorderVisibleHeight;
|
islandFrame.top = -topBorderVisibleHeight;
|
||||||
return islandFrame;
|
return islandFrame;
|
||||||
@@ -829,7 +828,7 @@ RECT NonClientIslandWindow::GetNonClientFrame(UINT dpi) const noexcept
|
|||||||
// - dpi: dpi of a monitor on which the window is placed
|
// - dpi: dpi of a monitor on which the window is placed
|
||||||
// Return Value
|
// Return Value
|
||||||
// - The size difference
|
// - The size difference
|
||||||
SIZE NonClientIslandWindow::GetTotalNonClientExclusiveSize(UINT dpi) const noexcept
|
til::size NonClientIslandWindow::GetTotalNonClientExclusiveSize(UINT dpi) const noexcept
|
||||||
{
|
{
|
||||||
const auto islandFrame{ GetNonClientFrame(dpi) };
|
const auto islandFrame{ GetNonClientFrame(dpi) };
|
||||||
|
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] virtual LRESULT MessageHandler(UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept override;
|
[[nodiscard]] virtual LRESULT MessageHandler(UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept override;
|
||||||
|
|
||||||
virtual RECT GetNonClientFrame(UINT dpi) const noexcept override;
|
virtual til::rect GetNonClientFrame(UINT dpi) const noexcept override;
|
||||||
virtual SIZE GetTotalNonClientExclusiveSize(UINT dpi) const noexcept override;
|
virtual til::size GetTotalNonClientExclusiveSize(UINT dpi) const noexcept override;
|
||||||
|
|
||||||
void Initialize() override;
|
void Initialize() override;
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ public:
|
|||||||
void OnApplicationThemeChanged(const winrt::Windows::UI::Xaml::ElementTheme& requestedTheme) override;
|
void OnApplicationThemeChanged(const winrt::Windows::UI::Xaml::ElementTheme& requestedTheme) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::optional<COORD> _oldIslandPos;
|
std::optional<til::point> _oldIslandPos;
|
||||||
|
|
||||||
winrt::TerminalApp::TitlebarControl _titlebar{ nullptr };
|
winrt::TerminalApp::TitlebarControl _titlebar{ nullptr };
|
||||||
winrt::Windows::UI::Xaml::UIElement _clientContent{ nullptr };
|
winrt::Windows::UI::Xaml::UIElement _clientContent{ nullptr };
|
||||||
@@ -70,7 +70,7 @@ private:
|
|||||||
void _ResizeDragBarWindow() noexcept;
|
void _ResizeDragBarWindow() noexcept;
|
||||||
|
|
||||||
int _GetResizeHandleHeight() const noexcept;
|
int _GetResizeHandleHeight() const noexcept;
|
||||||
RECT _GetDragAreaRect() const noexcept;
|
til::rect _GetDragAreaRect() const noexcept;
|
||||||
int _GetTopBorderHeight() const noexcept;
|
int _GetTopBorderHeight() const noexcept;
|
||||||
LRESULT _dragBarNcHitTest(const til::point pointer);
|
LRESULT _dragBarNcHitTest(const til::point pointer);
|
||||||
|
|
||||||
|
|||||||
@@ -186,31 +186,31 @@ namespace Microsoft.Terminal.Wpf
|
|||||||
public static extern void TerminalSendOutput(IntPtr terminal, string lpdata);
|
public static extern void TerminalSendOutput(IntPtr terminal, string lpdata);
|
||||||
|
|
||||||
[DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
|
[DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
|
||||||
public static extern uint TerminalTriggerResize(IntPtr terminal, short width, short height, out COORD dimensions);
|
public static extern uint TerminalTriggerResize(IntPtr terminal, int width, int height, out TilSize dimensions);
|
||||||
|
|
||||||
[DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
|
[DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
|
||||||
public static extern uint TerminalTriggerResizeWithDimension(IntPtr terminal, [MarshalAs(UnmanagedType.Struct)] COORD dimensions, out SIZE dimensionsInPixels);
|
public static extern uint TerminalTriggerResizeWithDimension(IntPtr terminal, TilSize dimensions, out TilSize dimensionsInPixels);
|
||||||
|
|
||||||
[DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
|
[DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
|
||||||
public static extern uint TerminalCalculateResize(IntPtr terminal, short width, short height, out COORD dimensions);
|
public static extern uint TerminalCalculateResize(IntPtr terminal, int width, int height, out TilSize dimensions);
|
||||||
|
|
||||||
[DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
|
[DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
|
||||||
public static extern void TerminalDpiChanged(IntPtr terminal, int newDpi);
|
public static extern void TerminalDpiChanged(IntPtr terminal, int newDpi);
|
||||||
|
|
||||||
[DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
|
[DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
|
||||||
public static extern void TerminalRegisterScrollCallback(IntPtr terminal, [MarshalAs(UnmanagedType.FunctionPtr)]ScrollCallback callback);
|
public static extern void TerminalRegisterScrollCallback(IntPtr terminal, [MarshalAs(UnmanagedType.FunctionPtr)] ScrollCallback callback);
|
||||||
|
|
||||||
[DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
|
[DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
|
||||||
public static extern void TerminalRegisterWriteCallback(IntPtr terminal, [MarshalAs(UnmanagedType.FunctionPtr)]WriteCallback callback);
|
public static extern void TerminalRegisterWriteCallback(IntPtr terminal, [MarshalAs(UnmanagedType.FunctionPtr)] WriteCallback callback);
|
||||||
|
|
||||||
[DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
|
[DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
|
||||||
public static extern void TerminalUserScroll(IntPtr terminal, int viewTop);
|
public static extern void TerminalUserScroll(IntPtr terminal, int viewTop);
|
||||||
|
|
||||||
[DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
|
[DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
|
||||||
public static extern uint TerminalStartSelection(IntPtr terminal, COORD cursorPosition, bool altPressed);
|
public static extern uint TerminalStartSelection(IntPtr terminal, TilPoint cursorPosition, bool altPressed);
|
||||||
|
|
||||||
[DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
|
[DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
|
||||||
public static extern uint TerminalMoveSelection(IntPtr terminal, COORD cursorPosition);
|
public static extern uint TerminalMoveSelection(IntPtr terminal, TilPoint cursorPosition);
|
||||||
|
|
||||||
[DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
|
[DllImport("PublicTerminalCore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
|
||||||
public static extern void TerminalClearSelection(IntPtr terminal);
|
public static extern void TerminalClearSelection(IntPtr terminal);
|
||||||
@@ -272,31 +272,31 @@ namespace Microsoft.Terminal.Wpf
|
|||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct COORD
|
public struct TilPoint
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The x-coordinate of the point.
|
/// The x-coordinate of the point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public short X;
|
public int X;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The y-coordinate of the point.
|
/// The y-coordinate of the point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public short Y;
|
public int Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct SIZE
|
public struct TilSize
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The x size.
|
/// The x size.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int cx;
|
public int X;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The y size.
|
/// The y size.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int cy;
|
public int Y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#pragma warning restore SA1600 // Elements should be documented
|
#pragma warning restore SA1600 // Elements should be documented
|
||||||
|
|||||||
@@ -173,9 +173,9 @@ namespace Microsoft.Terminal.Wpf
|
|||||||
|
|
||||||
NativeMethods.TerminalTriggerResize(
|
NativeMethods.TerminalTriggerResize(
|
||||||
this.terminal,
|
this.terminal,
|
||||||
Convert.ToInt16(renderSize.Width),
|
(int)renderSize.Width,
|
||||||
Convert.ToInt16(renderSize.Height),
|
(int)renderSize.Height,
|
||||||
out NativeMethods.COORD dimensions);
|
out NativeMethods.TilSize dimensions);
|
||||||
|
|
||||||
this.Rows = dimensions.Y;
|
this.Rows = dimensions.Y;
|
||||||
this.Columns = dimensions.X;
|
this.Columns = dimensions.X;
|
||||||
@@ -200,11 +200,11 @@ namespace Microsoft.Terminal.Wpf
|
|||||||
throw new ArgumentException("Terminal column count cannot be 0.", nameof(columns));
|
throw new ArgumentException("Terminal column count cannot be 0.", nameof(columns));
|
||||||
}
|
}
|
||||||
|
|
||||||
NativeMethods.SIZE dimensionsInPixels;
|
NativeMethods.TilSize dimensionsInPixels;
|
||||||
NativeMethods.COORD dimensions = new NativeMethods.COORD
|
NativeMethods.TilSize dimensions = new NativeMethods.TilSize
|
||||||
{
|
{
|
||||||
X = (short)columns,
|
X = (int)columns,
|
||||||
Y = (short)rows,
|
Y = (int)rows,
|
||||||
};
|
};
|
||||||
|
|
||||||
NativeMethods.TerminalTriggerResizeWithDimension(this.terminal, dimensions, out dimensionsInPixels);
|
NativeMethods.TerminalTriggerResizeWithDimension(this.terminal, dimensions, out dimensionsInPixels);
|
||||||
@@ -214,8 +214,8 @@ namespace Microsoft.Terminal.Wpf
|
|||||||
|
|
||||||
this.TerminalRendererSize = new Size()
|
this.TerminalRendererSize = new Size()
|
||||||
{
|
{
|
||||||
Width = dimensionsInPixels.cx,
|
Width = dimensionsInPixels.X,
|
||||||
Height = dimensionsInPixels.cy,
|
Height = dimensionsInPixels.Y,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Connection?.Resize((uint)dimensions.Y, (uint)dimensions.X);
|
this.Connection?.Resize((uint)dimensions.Y, (uint)dimensions.X);
|
||||||
@@ -226,11 +226,11 @@ namespace Microsoft.Terminal.Wpf
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="size">DPI scaled size.</param>
|
/// <param name="size">DPI scaled size.</param>
|
||||||
/// <returns>Amount of rows and columns that would fit the given size.</returns>
|
/// <returns>Amount of rows and columns that would fit the given size.</returns>
|
||||||
internal (uint columns, uint rows) CalculateRowsAndColumns(Size size)
|
internal (int columns, int rows) CalculateRowsAndColumns(Size size)
|
||||||
{
|
{
|
||||||
NativeMethods.TerminalCalculateResize(this.terminal, (short)size.Width, (short)size.Height, out NativeMethods.COORD dimensions);
|
NativeMethods.TerminalCalculateResize(this.terminal, (int)size.Width, (int)size.Height, out NativeMethods.TilSize dimensions);
|
||||||
|
|
||||||
return ((uint)dimensions.X, (uint)dimensions.Y);
|
return (dimensions.X, dimensions.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -242,7 +242,7 @@ namespace Microsoft.Terminal.Wpf
|
|||||||
|
|
||||||
if (this.Columns < columns || this.Rows < rows)
|
if (this.Columns < columns || this.Rows < rows)
|
||||||
{
|
{
|
||||||
this.connection?.Resize(rows, columns);
|
this.connection?.Resize((uint)rows, (uint)columns);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,11 +368,11 @@ namespace Microsoft.Terminal.Wpf
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
NativeMethods.COORD dimensions;
|
NativeMethods.TilSize dimensions;
|
||||||
|
|
||||||
if (this.AutoResize)
|
if (this.AutoResize)
|
||||||
{
|
{
|
||||||
NativeMethods.TerminalTriggerResize(this.terminal, (short)windowpos.cx, (short)windowpos.cy, out dimensions);
|
NativeMethods.TerminalTriggerResize(this.terminal, windowpos.cx, windowpos.cy, out dimensions);
|
||||||
|
|
||||||
this.Columns = dimensions.X;
|
this.Columns = dimensions.X;
|
||||||
this.Rows = dimensions.Y;
|
this.Rows = dimensions.Y;
|
||||||
@@ -386,7 +386,7 @@ namespace Microsoft.Terminal.Wpf
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Calculate the new columns and rows that fit the total control size and alert the control to redraw the margins.
|
// Calculate the new columns and rows that fit the total control size and alert the control to redraw the margins.
|
||||||
NativeMethods.TerminalCalculateResize(this.terminal, (short)this.TerminalControlSize.Width, (short)this.TerminalControlSize.Height, out dimensions);
|
NativeMethods.TerminalCalculateResize(this.terminal, (int)this.TerminalControlSize.Width, (int)this.TerminalControlSize.Height, out dimensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Connection?.Resize((uint)dimensions.Y, (uint)dimensions.X);
|
this.Connection?.Resize((uint)dimensions.Y, (uint)dimensions.X);
|
||||||
@@ -405,9 +405,9 @@ namespace Microsoft.Terminal.Wpf
|
|||||||
private void LeftClickHandler(int lParam)
|
private void LeftClickHandler(int lParam)
|
||||||
{
|
{
|
||||||
var altPressed = NativeMethods.GetKeyState((int)NativeMethods.VirtualKey.VK_MENU) < 0;
|
var altPressed = NativeMethods.GetKeyState((int)NativeMethods.VirtualKey.VK_MENU) < 0;
|
||||||
var x = (short)(((int)lParam << 16) >> 16);
|
var x = lParam & 0xffff;
|
||||||
var y = (short)((int)lParam >> 16);
|
var y = lParam >> 16;
|
||||||
NativeMethods.COORD cursorPosition = new NativeMethods.COORD()
|
var cursorPosition = new NativeMethods.TilPoint()
|
||||||
{
|
{
|
||||||
X = x,
|
X = x,
|
||||||
Y = y,
|
Y = y,
|
||||||
@@ -418,11 +418,11 @@ namespace Microsoft.Terminal.Wpf
|
|||||||
|
|
||||||
private void MouseMoveHandler(int wParam, int lParam)
|
private void MouseMoveHandler(int wParam, int lParam)
|
||||||
{
|
{
|
||||||
if (((int)wParam & 0x0001) == 1)
|
if ((wParam & 0x0001) == 1)
|
||||||
{
|
{
|
||||||
var x = (short)(((int)lParam << 16) >> 16);
|
var x = lParam & 0xffff;
|
||||||
var y = (short)((int)lParam >> 16);
|
var y = lParam >> 16;
|
||||||
NativeMethods.COORD cursorPosition = new NativeMethods.COORD()
|
var cursorPosition = new NativeMethods.TilPoint()
|
||||||
{
|
{
|
||||||
X = x,
|
X = x,
|
||||||
Y = y,
|
Y = y,
|
||||||
|
|||||||
@@ -118,19 +118,19 @@ public:
|
|||||||
[[nodiscard]] HRESULT FillConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT FillConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
|
||||||
const WORD attribute,
|
const WORD attribute,
|
||||||
const size_t lengthToWrite,
|
const size_t lengthToWrite,
|
||||||
const COORD startingCoordinate,
|
const til::point startingCoordinate,
|
||||||
size_t& cellsModified) noexcept override;
|
size_t& cellsModified) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT FillConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT FillConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
|
||||||
const char character,
|
const char character,
|
||||||
const size_t lengthToWrite,
|
const size_t lengthToWrite,
|
||||||
const COORD startingCoordinate,
|
const til::point startingCoordinate,
|
||||||
size_t& cellsModified) noexcept override;
|
size_t& cellsModified) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT FillConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT FillConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
|
||||||
const wchar_t character,
|
const wchar_t character,
|
||||||
const size_t lengthToWrite,
|
const size_t lengthToWrite,
|
||||||
const COORD startingCoordinate,
|
const til::point startingCoordinate,
|
||||||
size_t& cellsModified,
|
size_t& cellsModified,
|
||||||
const bool enablePowershellShim = false) noexcept override;
|
const bool enablePowershellShim = false) noexcept override;
|
||||||
|
|
||||||
@@ -162,25 +162,25 @@ public:
|
|||||||
const CONSOLE_SCREEN_BUFFER_INFOEX& data) noexcept override;
|
const CONSOLE_SCREEN_BUFFER_INFOEX& data) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT SetConsoleScreenBufferSizeImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT SetConsoleScreenBufferSizeImpl(SCREEN_INFORMATION& context,
|
||||||
const COORD size) noexcept override;
|
const til::size size) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT SetConsoleCursorPositionImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT SetConsoleCursorPositionImpl(SCREEN_INFORMATION& context,
|
||||||
const COORD position) noexcept override;
|
const til::point position) noexcept override;
|
||||||
|
|
||||||
void GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& context,
|
void GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& context,
|
||||||
COORD& size) noexcept override;
|
til::size& size) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT ScrollConsoleScreenBufferAImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT ScrollConsoleScreenBufferAImpl(SCREEN_INFORMATION& context,
|
||||||
const SMALL_RECT& source,
|
const til::inclusive_rect& source,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
std::optional<SMALL_RECT> clip,
|
std::optional<til::inclusive_rect> clip,
|
||||||
const char fillCharacter,
|
const char fillCharacter,
|
||||||
const WORD fillAttribute) noexcept override;
|
const WORD fillAttribute) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT ScrollConsoleScreenBufferWImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT ScrollConsoleScreenBufferWImpl(SCREEN_INFORMATION& context,
|
||||||
const SMALL_RECT& source,
|
const til::inclusive_rect& source,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
std::optional<SMALL_RECT> clip,
|
std::optional<til::inclusive_rect> clip,
|
||||||
const wchar_t fillCharacter,
|
const wchar_t fillCharacter,
|
||||||
const WORD fillAttribute,
|
const WORD fillAttribute,
|
||||||
const bool enableCmdShim = false) noexcept override;
|
const bool enableCmdShim = false) noexcept override;
|
||||||
@@ -190,20 +190,20 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] HRESULT SetConsoleWindowInfoImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT SetConsoleWindowInfoImpl(SCREEN_INFORMATION& context,
|
||||||
const bool isAbsolute,
|
const bool isAbsolute,
|
||||||
const SMALL_RECT& windowRect) noexcept override;
|
const til::inclusive_rect& windowRect) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT ReadConsoleOutputAttributeImpl(const SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT ReadConsoleOutputAttributeImpl(const SCREEN_INFORMATION& context,
|
||||||
const COORD origin,
|
const til::point origin,
|
||||||
gsl::span<WORD> buffer,
|
gsl::span<WORD> buffer,
|
||||||
size_t& written) noexcept override;
|
size_t& written) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT ReadConsoleOutputCharacterAImpl(const SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT ReadConsoleOutputCharacterAImpl(const SCREEN_INFORMATION& context,
|
||||||
const COORD origin,
|
const til::point origin,
|
||||||
gsl::span<char> buffer,
|
gsl::span<char> buffer,
|
||||||
size_t& written) noexcept override;
|
size_t& written) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT ReadConsoleOutputCharacterWImpl(const SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT ReadConsoleOutputCharacterWImpl(const SCREEN_INFORMATION& context,
|
||||||
const COORD origin,
|
const til::point origin,
|
||||||
gsl::span<wchar_t> buffer,
|
gsl::span<wchar_t> buffer,
|
||||||
size_t& written) noexcept override;
|
size_t& written) noexcept override;
|
||||||
|
|
||||||
@@ -229,17 +229,17 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] HRESULT WriteConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT WriteConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
|
||||||
const gsl::span<const WORD> attrs,
|
const gsl::span<const WORD> attrs,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
size_t& used) noexcept override;
|
size_t& used) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT WriteConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT WriteConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
|
||||||
const std::string_view text,
|
const std::string_view text,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
size_t& used) noexcept override;
|
size_t& used) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT WriteConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT WriteConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
|
||||||
const std::wstring_view text,
|
const std::wstring_view text,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
size_t& used) noexcept override;
|
size_t& used) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT ReadConsoleOutputAImpl(const SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT ReadConsoleOutputAImpl(const SCREEN_INFORMATION& context,
|
||||||
@@ -279,7 +279,7 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] HRESULT GetConsoleFontSizeImpl(const SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT GetConsoleFontSizeImpl(const SCREEN_INFORMATION& context,
|
||||||
const DWORD index,
|
const DWORD index,
|
||||||
COORD& size) noexcept override;
|
til::size& size) noexcept override;
|
||||||
|
|
||||||
//// driver will pare down for non-Ex method
|
//// driver will pare down for non-Ex method
|
||||||
[[nodiscard]] HRESULT GetCurrentConsoleFontExImpl(const SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT GetCurrentConsoleFontExImpl(const SCREEN_INFORMATION& context,
|
||||||
@@ -288,7 +288,7 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] HRESULT SetConsoleDisplayModeImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT SetConsoleDisplayModeImpl(SCREEN_INFORMATION& context,
|
||||||
const ULONG flags,
|
const ULONG flags,
|
||||||
COORD& newSize) noexcept override;
|
til::size& newSize) noexcept override;
|
||||||
|
|
||||||
void GetConsoleDisplayModeImpl(ULONG& flags) noexcept override;
|
void GetConsoleDisplayModeImpl(ULONG& flags) noexcept override;
|
||||||
|
|
||||||
|
|||||||
@@ -22,10 +22,10 @@ static constexpr size_t COMMAND_NUMBER_SIZE = 8; // size of command number buffe
|
|||||||
// - history - the history to look through to measure command sizes
|
// - history - the history to look through to measure command sizes
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - the proposed size of the popup with the history list taken into account
|
// - the proposed size of the popup with the history list taken into account
|
||||||
static COORD calculatePopupSize(const CommandHistory& history)
|
static til::size calculatePopupSize(const CommandHistory& history)
|
||||||
{
|
{
|
||||||
// this is the historical size of the popup, so it is now used as a minimum
|
// this is the historical size of the popup, so it is now used as a minimum
|
||||||
const COORD minSize = { 40, 10 };
|
const til::size minSize = { 40, 10 };
|
||||||
|
|
||||||
// padding is for the command number listing before a command is printed to the window.
|
// padding is for the command number listing before a command is printed to the window.
|
||||||
// ex: |10: echo blah
|
// ex: |10: echo blah
|
||||||
@@ -45,9 +45,9 @@ static COORD calculatePopupSize(const CommandHistory& history)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// calculate height, it can range up to 20 rows
|
// calculate height, it can range up to 20 rows
|
||||||
auto height = std::clamp(gsl::narrow<short>(history.GetNumberOfCommands()), minSize.Y, 20i16);
|
auto height = std::clamp(gsl::narrow<til::CoordType>(history.GetNumberOfCommands()), minSize.Y, 20);
|
||||||
|
|
||||||
return { gsl::narrow<short>(width), height };
|
return { gsl::narrow_cast<til::CoordType>(width), height };
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandListPopup::CommandListPopup(SCREEN_INFORMATION& screenInfo, const CommandHistory& history) :
|
CommandListPopup::CommandListPopup(SCREEN_INFORMATION& screenInfo, const CommandHistory& history) :
|
||||||
@@ -139,7 +139,7 @@ void CommandListPopup::_setBottomIndex()
|
|||||||
{
|
{
|
||||||
if (_currentCommand < (SHORT)(_history.GetNumberOfCommands() - Height()))
|
if (_currentCommand < (SHORT)(_history.GetNumberOfCommands() - Height()))
|
||||||
{
|
{
|
||||||
_bottomIndex = std::max(_currentCommand, gsl::narrow<SHORT>(Height() - 1i16));
|
_bottomIndex = std::max(_currentCommand, gsl::narrow<SHORT>(Height() - 1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -204,7 +204,7 @@ void CommandListPopup::_setBottomIndex()
|
|||||||
{
|
{
|
||||||
auto& history = cookedReadData.History();
|
auto& history = cookedReadData.History();
|
||||||
|
|
||||||
if (history.GetNumberOfCommands() <= 1 || _currentCommand == gsl::narrow<short>(history.GetNumberOfCommands()) - 1i16)
|
if (history.GetNumberOfCommands() <= 1 || _currentCommand == gsl::narrow<short>(history.GetNumberOfCommands()) - 1)
|
||||||
{
|
{
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -330,22 +330,22 @@ void CommandListPopup::_DrawContent()
|
|||||||
void CommandListPopup::_drawList()
|
void CommandListPopup::_drawList()
|
||||||
{
|
{
|
||||||
// draw empty popup
|
// draw empty popup
|
||||||
COORD WriteCoord;
|
til::point WriteCoord;
|
||||||
WriteCoord.X = _region.Left + 1i16;
|
WriteCoord.X = _region.Left + 1;
|
||||||
WriteCoord.Y = _region.Top + 1i16;
|
WriteCoord.Y = _region.Top + 1;
|
||||||
size_t lStringLength = Width();
|
size_t lStringLength = Width();
|
||||||
for (SHORT i = 0; i < Height(); ++i)
|
for (til::CoordType i = 0; i < Height(); ++i)
|
||||||
{
|
{
|
||||||
const OutputCellIterator spaces(UNICODE_SPACE, _attributes, lStringLength);
|
const OutputCellIterator spaces(UNICODE_SPACE, _attributes, lStringLength);
|
||||||
const auto result = _screenInfo.Write(spaces, WriteCoord);
|
const auto result = _screenInfo.Write(spaces, WriteCoord);
|
||||||
lStringLength = result.GetCellDistance(spaces);
|
lStringLength = result.GetCellDistance(spaces);
|
||||||
WriteCoord.Y += 1i16;
|
WriteCoord.Y += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto api = Microsoft::Console::Interactivity::ServiceLocator::LocateGlobals().api;
|
auto api = Microsoft::Console::Interactivity::ServiceLocator::LocateGlobals().api;
|
||||||
|
|
||||||
WriteCoord.Y = _region.Top + 1i16;
|
WriteCoord.Y = _region.Top + 1;
|
||||||
auto i = std::max(gsl::narrow<SHORT>(_bottomIndex - Height() + 1), 0i16);
|
auto i = gsl::narrow<SHORT>(std::max(_bottomIndex - Height() + 1, 0));
|
||||||
for (; i <= _bottomIndex; i++)
|
for (; i <= _bottomIndex; i++)
|
||||||
{
|
{
|
||||||
CHAR CommandNumber[COMMAND_NUMBER_SIZE];
|
CHAR CommandNumber[COMMAND_NUMBER_SIZE];
|
||||||
@@ -377,7 +377,7 @@ void CommandListPopup::_drawList()
|
|||||||
CommandNumberLength = static_cast<ULONG>(Width());
|
CommandNumberLength = static_cast<ULONG>(Width());
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteCoord.X = _region.Left + 1i16;
|
WriteCoord.X = _region.Left + 1;
|
||||||
|
|
||||||
LOG_IF_FAILED(api->WriteConsoleOutputCharacterAImpl(_screenInfo,
|
LOG_IF_FAILED(api->WriteConsoleOutputCharacterAImpl(_screenInfo,
|
||||||
{ CommandNumberPtr, CommandNumberLength },
|
{ CommandNumberPtr, CommandNumberLength },
|
||||||
@@ -415,7 +415,7 @@ void CommandListPopup::_drawList()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteCoord.X = gsl::narrow<SHORT>(WriteCoord.X + CommandNumberLength);
|
WriteCoord.X = gsl::narrow<til::CoordType>(WriteCoord.X + CommandNumberLength);
|
||||||
size_t used;
|
size_t used;
|
||||||
LOG_IF_FAILED(api->WriteConsoleOutputCharacterWImpl(_screenInfo,
|
LOG_IF_FAILED(api->WriteConsoleOutputCharacterWImpl(_screenInfo,
|
||||||
{ command.data(), lStringLength },
|
{ command.data(), lStringLength },
|
||||||
@@ -425,7 +425,7 @@ void CommandListPopup::_drawList()
|
|||||||
// write attributes to screen
|
// write attributes to screen
|
||||||
if (i == _currentCommand)
|
if (i == _currentCommand)
|
||||||
{
|
{
|
||||||
WriteCoord.X = _region.Left + 1i16;
|
WriteCoord.X = _region.Left + 1;
|
||||||
// inverted attributes
|
// inverted attributes
|
||||||
lStringLength = Width();
|
lStringLength = Width();
|
||||||
auto inverted = _attributes;
|
auto inverted = _attributes;
|
||||||
@@ -468,7 +468,7 @@ void CommandListPopup::_update(const SHORT originalDelta, const bool wrap)
|
|||||||
{
|
{
|
||||||
if (NewCmdNum >= gsl::narrow<SHORT>(_history.GetNumberOfCommands()))
|
if (NewCmdNum >= gsl::narrow<SHORT>(_history.GetNumberOfCommands()))
|
||||||
{
|
{
|
||||||
NewCmdNum = gsl::narrow<SHORT>(_history.GetNumberOfCommands()) - 1i16;
|
NewCmdNum = gsl::narrow<SHORT>(_history.GetNumberOfCommands()) - 1;
|
||||||
}
|
}
|
||||||
else if (NewCmdNum < 0)
|
else if (NewCmdNum < 0)
|
||||||
{
|
{
|
||||||
@@ -482,9 +482,9 @@ void CommandListPopup::_update(const SHORT originalDelta, const bool wrap)
|
|||||||
if (NewCmdNum <= _bottomIndex - Size)
|
if (NewCmdNum <= _bottomIndex - Size)
|
||||||
{
|
{
|
||||||
_bottomIndex += delta;
|
_bottomIndex += delta;
|
||||||
if (_bottomIndex < Size - 1i16)
|
if (_bottomIndex < Size - 1)
|
||||||
{
|
{
|
||||||
_bottomIndex = Size - 1i16;
|
_bottomIndex = gsl::narrow<SHORT>(Size - 1);
|
||||||
}
|
}
|
||||||
Scroll = true;
|
Scroll = true;
|
||||||
}
|
}
|
||||||
@@ -493,7 +493,7 @@ void CommandListPopup::_update(const SHORT originalDelta, const bool wrap)
|
|||||||
_bottomIndex += delta;
|
_bottomIndex += delta;
|
||||||
if (_bottomIndex >= gsl::narrow<SHORT>(_history.GetNumberOfCommands()))
|
if (_bottomIndex >= gsl::narrow<SHORT>(_history.GetNumberOfCommands()))
|
||||||
{
|
{
|
||||||
_bottomIndex = gsl::narrow<SHORT>(_history.GetNumberOfCommands()) - 1i16;
|
_bottomIndex = gsl::narrow<SHORT>(_history.GetNumberOfCommands()) - 1;
|
||||||
}
|
}
|
||||||
Scroll = true;
|
Scroll = true;
|
||||||
}
|
}
|
||||||
@@ -518,27 +518,27 @@ void CommandListPopup::_update(const SHORT originalDelta, const bool wrap)
|
|||||||
// - NewCurrentCommand - The new command to be highlighted.
|
// - NewCurrentCommand - The new command to be highlighted.
|
||||||
void CommandListPopup::_updateHighlight(const SHORT OldCurrentCommand, const SHORT NewCurrentCommand)
|
void CommandListPopup::_updateHighlight(const SHORT OldCurrentCommand, const SHORT NewCurrentCommand)
|
||||||
{
|
{
|
||||||
SHORT TopIndex;
|
til::CoordType TopIndex;
|
||||||
if (_bottomIndex < Height())
|
if (_bottomIndex < Height())
|
||||||
{
|
{
|
||||||
TopIndex = 0;
|
TopIndex = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TopIndex = _bottomIndex - Height() + 1i16;
|
TopIndex = _bottomIndex - Height() + 1;
|
||||||
}
|
}
|
||||||
COORD WriteCoord;
|
til::point WriteCoord;
|
||||||
WriteCoord.X = _region.Left + 1i16;
|
WriteCoord.X = _region.Left + 1;
|
||||||
size_t lStringLength = Width();
|
size_t lStringLength = Width();
|
||||||
|
|
||||||
WriteCoord.Y = _region.Top + 1i16 + OldCurrentCommand - TopIndex;
|
WriteCoord.Y = _region.Top + 1 + OldCurrentCommand - TopIndex;
|
||||||
|
|
||||||
const OutputCellIterator it(_attributes, lStringLength);
|
const OutputCellIterator it(_attributes, lStringLength);
|
||||||
const auto done = _screenInfo.Write(it, WriteCoord);
|
const auto done = _screenInfo.Write(it, WriteCoord);
|
||||||
lStringLength = done.GetCellDistance(it);
|
lStringLength = done.GetCellDistance(it);
|
||||||
|
|
||||||
// highlight new command
|
// highlight new command
|
||||||
WriteCoord.Y = _region.Top + 1i16 + NewCurrentCommand - TopIndex;
|
WriteCoord.Y = _region.Top + 1 + NewCurrentCommand - TopIndex;
|
||||||
|
|
||||||
// inverted attributes
|
// inverted attributes
|
||||||
auto inverted = _attributes;
|
auto inverted = _attributes;
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ void CursorBlinker::TimerRoutine(SCREEN_INFORMATION& ScreenInfo) const noexcept
|
|||||||
const auto fontSize = ScreenInfo.GetScreenFontSize();
|
const auto fontSize = ScreenInfo.GetScreenFontSize();
|
||||||
cursor.SetHasMoved(false);
|
cursor.SetHasMoved(false);
|
||||||
|
|
||||||
RECT rc;
|
til::rect rc;
|
||||||
rc.left = (position.X - viewport.Left()) * fontSize.X;
|
rc.left = (position.X - viewport.Left()) * fontSize.X;
|
||||||
rc.top = (position.Y - viewport.Top()) * fontSize.Y;
|
rc.top = (position.Y - viewport.Top()) * fontSize.Y;
|
||||||
rc.right = rc.left + fontSize.X;
|
rc.right = rc.left + fontSize.X;
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ void VtApiRoutines::_SynchronizeCursor(std::unique_ptr<IWaitRoutine>& waiter) no
|
|||||||
[[nodiscard]] HRESULT VtApiRoutines::FillConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT VtApiRoutines::FillConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
|
||||||
const WORD attribute,
|
const WORD attribute,
|
||||||
const size_t lengthToWrite,
|
const size_t lengthToWrite,
|
||||||
const COORD startingCoordinate,
|
const til::point startingCoordinate,
|
||||||
size_t& cellsModified) noexcept
|
size_t& cellsModified) noexcept
|
||||||
{
|
{
|
||||||
(void)m_pVtEngine->_CursorPosition(startingCoordinate);
|
(void)m_pVtEngine->_CursorPosition(startingCoordinate);
|
||||||
@@ -252,7 +252,7 @@ void VtApiRoutines::_SynchronizeCursor(std::unique_ptr<IWaitRoutine>& waiter) no
|
|||||||
[[nodiscard]] HRESULT VtApiRoutines::FillConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT VtApiRoutines::FillConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
|
||||||
const char character,
|
const char character,
|
||||||
const size_t lengthToWrite,
|
const size_t lengthToWrite,
|
||||||
const COORD startingCoordinate,
|
const til::point startingCoordinate,
|
||||||
size_t& cellsModified) noexcept
|
size_t& cellsModified) noexcept
|
||||||
{
|
{
|
||||||
// I mean... if you get your jollies by using UTF8 for single byte codepoints...
|
// I mean... if you get your jollies by using UTF8 for single byte codepoints...
|
||||||
@@ -275,7 +275,7 @@ void VtApiRoutines::_SynchronizeCursor(std::unique_ptr<IWaitRoutine>& waiter) no
|
|||||||
[[nodiscard]] HRESULT VtApiRoutines::FillConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT VtApiRoutines::FillConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
|
||||||
const wchar_t character,
|
const wchar_t character,
|
||||||
const size_t lengthToWrite,
|
const size_t lengthToWrite,
|
||||||
const COORD startingCoordinate,
|
const til::point startingCoordinate,
|
||||||
size_t& cellsModified,
|
size_t& cellsModified,
|
||||||
const bool enablePowershellShim) noexcept
|
const bool enablePowershellShim) noexcept
|
||||||
{
|
{
|
||||||
@@ -350,7 +350,7 @@ void VtApiRoutines::GetConsoleScreenBufferInfoExImpl(const SCREEN_INFORMATION& c
|
|||||||
const CONSOLE_SCREEN_BUFFER_INFOEX& data) noexcept
|
const CONSOLE_SCREEN_BUFFER_INFOEX& data) noexcept
|
||||||
{
|
{
|
||||||
(void)m_pVtEngine->_ResizeWindow(data.srWindow.Right - data.srWindow.Left, data.srWindow.Bottom - data.srWindow.Top);
|
(void)m_pVtEngine->_ResizeWindow(data.srWindow.Right - data.srWindow.Left, data.srWindow.Bottom - data.srWindow.Top);
|
||||||
(void)m_pVtEngine->_CursorPosition(data.dwCursorPosition);
|
(void)m_pVtEngine->_CursorPosition(til::wrap_coord(data.dwCursorPosition));
|
||||||
(void)m_pVtEngine->_SetGraphicsRendition16Color(static_cast<BYTE>(data.wAttributes), true);
|
(void)m_pVtEngine->_SetGraphicsRendition16Color(static_cast<BYTE>(data.wAttributes), true);
|
||||||
(void)m_pVtEngine->_SetGraphicsRendition16Color(static_cast<BYTE>(data.wAttributes >> 4), false);
|
(void)m_pVtEngine->_SetGraphicsRendition16Color(static_cast<BYTE>(data.wAttributes >> 4), false);
|
||||||
//color table?
|
//color table?
|
||||||
@@ -361,14 +361,14 @@ void VtApiRoutines::GetConsoleScreenBufferInfoExImpl(const SCREEN_INFORMATION& c
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] HRESULT VtApiRoutines::SetConsoleScreenBufferSizeImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT VtApiRoutines::SetConsoleScreenBufferSizeImpl(SCREEN_INFORMATION& context,
|
||||||
const COORD size) noexcept
|
const til::size size) noexcept
|
||||||
{
|
{
|
||||||
// Don't transmit. The terminal figures out its own buffer size.
|
// Don't transmit. The terminal figures out its own buffer size.
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] HRESULT VtApiRoutines::SetConsoleCursorPositionImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT VtApiRoutines::SetConsoleCursorPositionImpl(SCREEN_INFORMATION& context,
|
||||||
const COORD position) noexcept
|
const til::point position) noexcept
|
||||||
{
|
{
|
||||||
if (m_listeningForDSR)
|
if (m_listeningForDSR)
|
||||||
{
|
{
|
||||||
@@ -384,16 +384,16 @@ void VtApiRoutines::GetConsoleScreenBufferInfoExImpl(const SCREEN_INFORMATION& c
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VtApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& context,
|
void VtApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& context,
|
||||||
COORD& size) noexcept
|
til::size& size) noexcept
|
||||||
{
|
{
|
||||||
m_pUsualRoutines->GetLargestConsoleWindowSizeImpl(context, size); // This is likely super weird but not weirder than existing ConPTY answers.
|
m_pUsualRoutines->GetLargestConsoleWindowSizeImpl(context, size); // This is likely super weird but not weirder than existing ConPTY answers.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] HRESULT VtApiRoutines::ScrollConsoleScreenBufferAImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT VtApiRoutines::ScrollConsoleScreenBufferAImpl(SCREEN_INFORMATION& context,
|
||||||
const SMALL_RECT& source,
|
const til::inclusive_rect& source,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
std::optional<SMALL_RECT> clip,
|
std::optional<til::inclusive_rect> clip,
|
||||||
const char fillCharacter,
|
const char fillCharacter,
|
||||||
const WORD fillAttribute) noexcept
|
const WORD fillAttribute) noexcept
|
||||||
{
|
{
|
||||||
@@ -402,9 +402,9 @@ void VtApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& co
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] HRESULT VtApiRoutines::ScrollConsoleScreenBufferWImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT VtApiRoutines::ScrollConsoleScreenBufferWImpl(SCREEN_INFORMATION& context,
|
||||||
const SMALL_RECT& source,
|
const til::inclusive_rect& source,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
std::optional<SMALL_RECT> clip,
|
std::optional<til::inclusive_rect> clip,
|
||||||
const wchar_t fillCharacter,
|
const wchar_t fillCharacter,
|
||||||
const WORD fillAttribute,
|
const WORD fillAttribute,
|
||||||
const bool enableCmdShim) noexcept
|
const bool enableCmdShim) noexcept
|
||||||
@@ -424,15 +424,15 @@ void VtApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& co
|
|||||||
|
|
||||||
[[nodiscard]] HRESULT VtApiRoutines::SetConsoleWindowInfoImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT VtApiRoutines::SetConsoleWindowInfoImpl(SCREEN_INFORMATION& context,
|
||||||
const bool isAbsolute,
|
const bool isAbsolute,
|
||||||
const SMALL_RECT& windowRect) noexcept
|
const til::inclusive_rect& windowRect) noexcept
|
||||||
{
|
{
|
||||||
(void)m_pVtEngine->_ResizeWindow(windowRect.Right - windowRect.Left, windowRect.Bottom - windowRect.Top);
|
(void)m_pVtEngine->_ResizeWindow(windowRect.Right - windowRect.Left + 1, windowRect.Bottom - windowRect.Top + 1);
|
||||||
(void)m_pVtEngine->_Flush();
|
(void)m_pVtEngine->_Flush();
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] HRESULT VtApiRoutines::ReadConsoleOutputAttributeImpl(const SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT VtApiRoutines::ReadConsoleOutputAttributeImpl(const SCREEN_INFORMATION& context,
|
||||||
const COORD origin,
|
const til::point origin,
|
||||||
gsl::span<WORD> buffer,
|
gsl::span<WORD> buffer,
|
||||||
size_t& written) noexcept
|
size_t& written) noexcept
|
||||||
{
|
{
|
||||||
@@ -442,7 +442,7 @@ void VtApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& co
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] HRESULT VtApiRoutines::ReadConsoleOutputCharacterAImpl(const SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT VtApiRoutines::ReadConsoleOutputCharacterAImpl(const SCREEN_INFORMATION& context,
|
||||||
const COORD origin,
|
const til::point origin,
|
||||||
gsl::span<char> buffer,
|
gsl::span<char> buffer,
|
||||||
size_t& written) noexcept
|
size_t& written) noexcept
|
||||||
{
|
{
|
||||||
@@ -452,7 +452,7 @@ void VtApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& co
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] HRESULT VtApiRoutines::ReadConsoleOutputCharacterWImpl(const SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT VtApiRoutines::ReadConsoleOutputCharacterWImpl(const SCREEN_INFORMATION& context,
|
||||||
const COORD origin,
|
const til::point origin,
|
||||||
gsl::span<wchar_t> buffer,
|
gsl::span<wchar_t> buffer,
|
||||||
size_t& written) noexcept
|
size_t& written) noexcept
|
||||||
{
|
{
|
||||||
@@ -498,7 +498,7 @@ extern HRESULT _ConvertCellsToWInplace(const UINT codepage,
|
|||||||
const Microsoft::Console::Types::Viewport& requestRectangle,
|
const Microsoft::Console::Types::Viewport& requestRectangle,
|
||||||
Microsoft::Console::Types::Viewport& writtenRectangle) noexcept
|
Microsoft::Console::Types::Viewport& writtenRectangle) noexcept
|
||||||
{
|
{
|
||||||
COORD cursor{ requestRectangle.Left(), requestRectangle.Top() };
|
auto cursor = requestRectangle.Origin();
|
||||||
|
|
||||||
const size_t width = requestRectangle.Width();
|
const size_t width = requestRectangle.Width();
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
@@ -529,7 +529,7 @@ extern HRESULT _ConvertCellsToWInplace(const UINT codepage,
|
|||||||
|
|
||||||
[[nodiscard]] HRESULT VtApiRoutines::WriteConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT VtApiRoutines::WriteConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
|
||||||
const gsl::span<const WORD> attrs,
|
const gsl::span<const WORD> attrs,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
size_t& used) noexcept
|
size_t& used) noexcept
|
||||||
{
|
{
|
||||||
(void)m_pVtEngine->_CursorPosition(target);
|
(void)m_pVtEngine->_CursorPosition(target);
|
||||||
@@ -549,7 +549,7 @@ extern HRESULT _ConvertCellsToWInplace(const UINT codepage,
|
|||||||
|
|
||||||
[[nodiscard]] HRESULT VtApiRoutines::WriteConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT VtApiRoutines::WriteConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
|
||||||
const std::string_view text,
|
const std::string_view text,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
size_t& used) noexcept
|
size_t& used) noexcept
|
||||||
{
|
{
|
||||||
if (m_outputCodepage == CP_UTF8)
|
if (m_outputCodepage == CP_UTF8)
|
||||||
@@ -567,7 +567,7 @@ extern HRESULT _ConvertCellsToWInplace(const UINT codepage,
|
|||||||
|
|
||||||
[[nodiscard]] HRESULT VtApiRoutines::WriteConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT VtApiRoutines::WriteConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
|
||||||
const std::wstring_view text,
|
const std::wstring_view text,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
size_t& used) noexcept
|
size_t& used) noexcept
|
||||||
{
|
{
|
||||||
(void)m_pVtEngine->_CursorPosition(target);
|
(void)m_pVtEngine->_CursorPosition(target);
|
||||||
@@ -676,7 +676,7 @@ void VtApiRoutines::GetNumberOfConsoleMouseButtonsImpl(ULONG& buttons) noexcept
|
|||||||
|
|
||||||
[[nodiscard]] HRESULT VtApiRoutines::GetConsoleFontSizeImpl(const SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT VtApiRoutines::GetConsoleFontSizeImpl(const SCREEN_INFORMATION& context,
|
||||||
const DWORD index,
|
const DWORD index,
|
||||||
COORD& size) noexcept
|
til::size& size) noexcept
|
||||||
{
|
{
|
||||||
size.X = 8;
|
size.X = 8;
|
||||||
size.Y = 12;
|
size.Y = 12;
|
||||||
@@ -693,7 +693,7 @@ void VtApiRoutines::GetNumberOfConsoleMouseButtonsImpl(ULONG& buttons) noexcept
|
|||||||
|
|
||||||
[[nodiscard]] HRESULT VtApiRoutines::SetConsoleDisplayModeImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT VtApiRoutines::SetConsoleDisplayModeImpl(SCREEN_INFORMATION& context,
|
||||||
const ULONG flags,
|
const ULONG flags,
|
||||||
COORD& newSize) noexcept
|
til::size& newSize) noexcept
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,19 +121,19 @@ public:
|
|||||||
[[nodiscard]] HRESULT FillConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT FillConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
|
||||||
const WORD attribute,
|
const WORD attribute,
|
||||||
const size_t lengthToWrite,
|
const size_t lengthToWrite,
|
||||||
const COORD startingCoordinate,
|
const til::point startingCoordinate,
|
||||||
size_t& cellsModified) noexcept override;
|
size_t& cellsModified) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT FillConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT FillConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
|
||||||
const char character,
|
const char character,
|
||||||
const size_t lengthToWrite,
|
const size_t lengthToWrite,
|
||||||
const COORD startingCoordinate,
|
const til::point startingCoordinate,
|
||||||
size_t& cellsModified) noexcept override;
|
size_t& cellsModified) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT FillConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT FillConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
|
||||||
const wchar_t character,
|
const wchar_t character,
|
||||||
const size_t lengthToWrite,
|
const size_t lengthToWrite,
|
||||||
const COORD startingCoordinate,
|
const til::point startingCoordinate,
|
||||||
size_t& cellsModified,
|
size_t& cellsModified,
|
||||||
const bool enablePowershellShim = false) noexcept override;
|
const bool enablePowershellShim = false) noexcept override;
|
||||||
|
|
||||||
@@ -165,25 +165,25 @@ public:
|
|||||||
const CONSOLE_SCREEN_BUFFER_INFOEX& data) noexcept override;
|
const CONSOLE_SCREEN_BUFFER_INFOEX& data) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT SetConsoleScreenBufferSizeImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT SetConsoleScreenBufferSizeImpl(SCREEN_INFORMATION& context,
|
||||||
const COORD size) noexcept override;
|
const til::size size) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT SetConsoleCursorPositionImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT SetConsoleCursorPositionImpl(SCREEN_INFORMATION& context,
|
||||||
const COORD position) noexcept override;
|
const til::point position) noexcept override;
|
||||||
|
|
||||||
void GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& context,
|
void GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& context,
|
||||||
COORD& size) noexcept override;
|
til::size& size) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT ScrollConsoleScreenBufferAImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT ScrollConsoleScreenBufferAImpl(SCREEN_INFORMATION& context,
|
||||||
const SMALL_RECT& source,
|
const til::inclusive_rect& source,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
std::optional<SMALL_RECT> clip,
|
std::optional<til::inclusive_rect> clip,
|
||||||
const char fillCharacter,
|
const char fillCharacter,
|
||||||
const WORD fillAttribute) noexcept override;
|
const WORD fillAttribute) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT ScrollConsoleScreenBufferWImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT ScrollConsoleScreenBufferWImpl(SCREEN_INFORMATION& context,
|
||||||
const SMALL_RECT& source,
|
const til::inclusive_rect& source,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
std::optional<SMALL_RECT> clip,
|
std::optional<til::inclusive_rect> clip,
|
||||||
const wchar_t fillCharacter,
|
const wchar_t fillCharacter,
|
||||||
const WORD fillAttribute,
|
const WORD fillAttribute,
|
||||||
const bool enableCmdShim = false) noexcept override;
|
const bool enableCmdShim = false) noexcept override;
|
||||||
@@ -193,20 +193,20 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] HRESULT SetConsoleWindowInfoImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT SetConsoleWindowInfoImpl(SCREEN_INFORMATION& context,
|
||||||
const bool isAbsolute,
|
const bool isAbsolute,
|
||||||
const SMALL_RECT& windowRect) noexcept override;
|
const til::inclusive_rect& windowRect) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT ReadConsoleOutputAttributeImpl(const SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT ReadConsoleOutputAttributeImpl(const SCREEN_INFORMATION& context,
|
||||||
const COORD origin,
|
const til::point origin,
|
||||||
gsl::span<WORD> buffer,
|
gsl::span<WORD> buffer,
|
||||||
size_t& written) noexcept override;
|
size_t& written) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT ReadConsoleOutputCharacterAImpl(const SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT ReadConsoleOutputCharacterAImpl(const SCREEN_INFORMATION& context,
|
||||||
const COORD origin,
|
const til::point origin,
|
||||||
gsl::span<char> buffer,
|
gsl::span<char> buffer,
|
||||||
size_t& written) noexcept override;
|
size_t& written) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT ReadConsoleOutputCharacterWImpl(const SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT ReadConsoleOutputCharacterWImpl(const SCREEN_INFORMATION& context,
|
||||||
const COORD origin,
|
const til::point origin,
|
||||||
gsl::span<wchar_t> buffer,
|
gsl::span<wchar_t> buffer,
|
||||||
size_t& written) noexcept override;
|
size_t& written) noexcept override;
|
||||||
|
|
||||||
@@ -232,17 +232,17 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] HRESULT WriteConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT WriteConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
|
||||||
const gsl::span<const WORD> attrs,
|
const gsl::span<const WORD> attrs,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
size_t& used) noexcept override;
|
size_t& used) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT WriteConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT WriteConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
|
||||||
const std::string_view text,
|
const std::string_view text,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
size_t& used) noexcept override;
|
size_t& used) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT WriteConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT WriteConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
|
||||||
const std::wstring_view text,
|
const std::wstring_view text,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
size_t& used) noexcept override;
|
size_t& used) noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT ReadConsoleOutputAImpl(const SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT ReadConsoleOutputAImpl(const SCREEN_INFORMATION& context,
|
||||||
@@ -282,7 +282,7 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] HRESULT GetConsoleFontSizeImpl(const SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT GetConsoleFontSizeImpl(const SCREEN_INFORMATION& context,
|
||||||
const DWORD index,
|
const DWORD index,
|
||||||
COORD& size) noexcept override;
|
til::size& size) noexcept override;
|
||||||
|
|
||||||
//// driver will pare down for non-Ex method
|
//// driver will pare down for non-Ex method
|
||||||
[[nodiscard]] HRESULT GetCurrentConsoleFontExImpl(const SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT GetCurrentConsoleFontExImpl(const SCREEN_INFORMATION& context,
|
||||||
@@ -291,7 +291,7 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] HRESULT SetConsoleDisplayModeImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT SetConsoleDisplayModeImpl(SCREEN_INFORMATION& context,
|
||||||
const ULONG flags,
|
const ULONG flags,
|
||||||
COORD& newSize) noexcept override;
|
til::size& newSize) noexcept override;
|
||||||
|
|
||||||
void GetConsoleDisplayModeImpl(ULONG& flags) noexcept override;
|
void GetConsoleDisplayModeImpl(ULONG& flags) noexcept override;
|
||||||
|
|
||||||
|
|||||||
@@ -390,7 +390,7 @@ void VtIo::CreatePseudoWindow()
|
|||||||
// Return Value:
|
// Return Value:
|
||||||
// - S_OK if we successfully inherited the cursor or did nothing, else an
|
// - S_OK if we successfully inherited the cursor or did nothing, else an
|
||||||
// appropriate HRESULT
|
// appropriate HRESULT
|
||||||
[[nodiscard]] HRESULT VtIo::SetCursorPosition(const COORD coordCursor)
|
[[nodiscard]] HRESULT VtIo::SetCursorPosition(const til::point coordCursor)
|
||||||
{
|
{
|
||||||
auto hr = S_OK;
|
auto hr = S_OK;
|
||||||
if (_lookingForCursorPosition)
|
if (_lookingForCursorPosition)
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ namespace Microsoft::Console::VirtualTerminal
|
|||||||
[[nodiscard]] static HRESULT ParseIoMode(const std::wstring& VtMode, _Out_ VtIoMode& ioMode);
|
[[nodiscard]] static HRESULT ParseIoMode(const std::wstring& VtMode, _Out_ VtIoMode& ioMode);
|
||||||
|
|
||||||
[[nodiscard]] HRESULT SuppressResizeRepaint();
|
[[nodiscard]] HRESULT SuppressResizeRepaint();
|
||||||
[[nodiscard]] HRESULT SetCursorPosition(const COORD coordCursor);
|
[[nodiscard]] HRESULT SetCursorPosition(const til::point coordCursor);
|
||||||
|
|
||||||
[[nodiscard]] HRESULT SwitchScreenBuffer(const bool useAltBuffer);
|
[[nodiscard]] HRESULT SwitchScreenBuffer(const bool useAltBuffer);
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region)
|
|||||||
// - S_OK, E_INVALIDARG or similar HRESULT error.
|
// - S_OK, E_INVALIDARG or similar HRESULT error.
|
||||||
[[nodiscard]] HRESULT ApiRoutines::WriteConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT ApiRoutines::WriteConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
|
||||||
const gsl::span<const WORD> attrs,
|
const gsl::span<const WORD> attrs,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
size_t& used) noexcept
|
size_t& used) noexcept
|
||||||
{
|
{
|
||||||
// Set used to 0 from the beginning in case we exit early.
|
// Set used to 0 from the beginning in case we exit early.
|
||||||
@@ -110,7 +110,7 @@ void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region)
|
|||||||
// - S_OK, E_INVALIDARG or similar HRESULT error.
|
// - S_OK, E_INVALIDARG or similar HRESULT error.
|
||||||
[[nodiscard]] HRESULT ApiRoutines::WriteConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT ApiRoutines::WriteConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
|
||||||
const std::wstring_view chars,
|
const std::wstring_view chars,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
size_t& used) noexcept
|
size_t& used) noexcept
|
||||||
{
|
{
|
||||||
// Set used to 0 from the beginning in case we exit early.
|
// Set used to 0 from the beginning in case we exit early.
|
||||||
@@ -153,7 +153,7 @@ void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region)
|
|||||||
// - S_OK, E_INVALIDARG or similar HRESULT error.
|
// - S_OK, E_INVALIDARG or similar HRESULT error.
|
||||||
[[nodiscard]] HRESULT ApiRoutines::WriteConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT ApiRoutines::WriteConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
|
||||||
const std::string_view chars,
|
const std::string_view chars,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
size_t& used) noexcept
|
size_t& used) noexcept
|
||||||
{
|
{
|
||||||
// Set used to 0 from the beginning in case we exit early.
|
// Set used to 0 from the beginning in case we exit early.
|
||||||
@@ -195,7 +195,7 @@ void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region)
|
|||||||
[[nodiscard]] HRESULT ApiRoutines::FillConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT ApiRoutines::FillConsoleOutputAttributeImpl(IConsoleOutputObject& OutContext,
|
||||||
const WORD attribute,
|
const WORD attribute,
|
||||||
const size_t lengthToWrite,
|
const size_t lengthToWrite,
|
||||||
const COORD startingCoordinate,
|
const til::point startingCoordinate,
|
||||||
size_t& cellsModified) noexcept
|
size_t& cellsModified) noexcept
|
||||||
{
|
{
|
||||||
// Set modified cells to 0 from the beginning.
|
// Set modified cells to 0 from the beginning.
|
||||||
@@ -221,14 +221,15 @@ void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region)
|
|||||||
TextAttribute useThisAttr(attribute);
|
TextAttribute useThisAttr(attribute);
|
||||||
const OutputCellIterator it(useThisAttr, lengthToWrite);
|
const OutputCellIterator it(useThisAttr, lengthToWrite);
|
||||||
const auto done = screenBuffer.Write(it, startingCoordinate);
|
const auto done = screenBuffer.Write(it, startingCoordinate);
|
||||||
|
const auto cellsModifiedCoord = done.GetCellDistance(it);
|
||||||
|
|
||||||
cellsModified = done.GetCellDistance(it);
|
cellsModified = cellsModifiedCoord;
|
||||||
|
|
||||||
if (screenBuffer.HasAccessibilityEventing())
|
if (screenBuffer.HasAccessibilityEventing())
|
||||||
{
|
{
|
||||||
// Notify accessibility
|
// Notify accessibility
|
||||||
auto endingCoordinate = startingCoordinate;
|
auto endingCoordinate = startingCoordinate;
|
||||||
bufferSize.MoveInBounds(cellsModified, endingCoordinate);
|
bufferSize.MoveInBounds(cellsModifiedCoord, endingCoordinate);
|
||||||
screenBuffer.NotifyAccessibilityEventing(startingCoordinate.X, startingCoordinate.Y, endingCoordinate.X, endingCoordinate.Y);
|
screenBuffer.NotifyAccessibilityEventing(startingCoordinate.X, startingCoordinate.Y, endingCoordinate.X, endingCoordinate.Y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -253,7 +254,7 @@ void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region)
|
|||||||
[[nodiscard]] HRESULT ApiRoutines::FillConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT ApiRoutines::FillConsoleOutputCharacterWImpl(IConsoleOutputObject& OutContext,
|
||||||
const wchar_t character,
|
const wchar_t character,
|
||||||
const size_t lengthToWrite,
|
const size_t lengthToWrite,
|
||||||
const COORD startingCoordinate,
|
const til::point startingCoordinate,
|
||||||
size_t& cellsModified,
|
size_t& cellsModified,
|
||||||
const bool enablePowershellShim) noexcept
|
const bool enablePowershellShim) noexcept
|
||||||
{
|
{
|
||||||
@@ -284,13 +285,15 @@ void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region)
|
|||||||
// when writing to the buffer, specifically unset wrap if we get to the last column.
|
// when writing to the buffer, specifically unset wrap if we get to the last column.
|
||||||
// a fill operation should UNSET wrap in that scenario. See GH #1126 for more details.
|
// a fill operation should UNSET wrap in that scenario. See GH #1126 for more details.
|
||||||
const auto done = screenInfo.Write(it, startingCoordinate, false);
|
const auto done = screenInfo.Write(it, startingCoordinate, false);
|
||||||
cellsModified = done.GetInputDistance(it);
|
const auto cellsModifiedCoord = done.GetInputDistance(it);
|
||||||
|
|
||||||
|
cellsModified = cellsModifiedCoord;
|
||||||
|
|
||||||
// Notify accessibility
|
// Notify accessibility
|
||||||
if (screenInfo.HasAccessibilityEventing())
|
if (screenInfo.HasAccessibilityEventing())
|
||||||
{
|
{
|
||||||
auto endingCoordinate = startingCoordinate;
|
auto endingCoordinate = startingCoordinate;
|
||||||
bufferSize.MoveInBounds(cellsModified, endingCoordinate);
|
bufferSize.MoveInBounds(cellsModifiedCoord, endingCoordinate);
|
||||||
screenInfo.NotifyAccessibilityEventing(startingCoordinate.X, startingCoordinate.Y, endingCoordinate.X, endingCoordinate.Y);
|
screenInfo.NotifyAccessibilityEventing(startingCoordinate.X, startingCoordinate.Y, endingCoordinate.X, endingCoordinate.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,10 +307,10 @@ void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region)
|
|||||||
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||||
if (enablePowershellShim && gci.IsInVtIoMode())
|
if (enablePowershellShim && gci.IsInVtIoMode())
|
||||||
{
|
{
|
||||||
const til::size currentBufferDimensions{ screenInfo.GetBufferSize().Dimensions() };
|
const auto currentBufferDimensions{ screenInfo.GetBufferSize().Dimensions() };
|
||||||
|
|
||||||
const auto wroteWholeBuffer = lengthToWrite == (currentBufferDimensions.area<size_t>());
|
const auto wroteWholeBuffer = lengthToWrite == (currentBufferDimensions.area<size_t>());
|
||||||
const auto startedAtOrigin = startingCoordinate == COORD{ 0, 0 };
|
const auto startedAtOrigin = startingCoordinate == til::point{ 0, 0 };
|
||||||
const auto wroteSpaces = character == UNICODE_SPACE;
|
const auto wroteSpaces = character == UNICODE_SPACE;
|
||||||
|
|
||||||
if (wroteWholeBuffer && startedAtOrigin && wroteSpaces)
|
if (wroteWholeBuffer && startedAtOrigin && wroteSpaces)
|
||||||
@@ -334,7 +337,7 @@ void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region)
|
|||||||
[[nodiscard]] HRESULT ApiRoutines::FillConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
|
[[nodiscard]] HRESULT ApiRoutines::FillConsoleOutputCharacterAImpl(IConsoleOutputObject& OutContext,
|
||||||
const char character,
|
const char character,
|
||||||
const size_t lengthToWrite,
|
const size_t lengthToWrite,
|
||||||
const COORD startingCoordinate,
|
const til::point startingCoordinate,
|
||||||
size_t& cellsModified) noexcept
|
size_t& cellsModified) noexcept
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -40,9 +40,9 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
|
|||||||
// - fKeepCursorVisible - TRUE if changing window origin desirable when hit right edge
|
// - fKeepCursorVisible - TRUE if changing window origin desirable when hit right edge
|
||||||
// Return Value:
|
// Return Value:
|
||||||
[[nodiscard]] NTSTATUS AdjustCursorPosition(SCREEN_INFORMATION& screenInfo,
|
[[nodiscard]] NTSTATUS AdjustCursorPosition(SCREEN_INFORMATION& screenInfo,
|
||||||
_In_ COORD coordCursor,
|
_In_ til::point coordCursor,
|
||||||
const BOOL fKeepCursorVisible,
|
const BOOL fKeepCursorVisible,
|
||||||
_Inout_opt_ PSHORT psScrollY)
|
_Inout_opt_ til::CoordType* psScrollY)
|
||||||
{
|
{
|
||||||
const auto inVtMode = WI_IsFlagSet(screenInfo.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING);
|
const auto inVtMode = WI_IsFlagSet(screenInfo.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING);
|
||||||
const auto bufferSize = screenInfo.GetBufferSize().Dimensions();
|
const auto bufferSize = screenInfo.GetBufferSize().Dimensions();
|
||||||
@@ -50,8 +50,8 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
|
|||||||
{
|
{
|
||||||
if (coordCursor.Y > 0)
|
if (coordCursor.Y > 0)
|
||||||
{
|
{
|
||||||
coordCursor.X = (SHORT)(bufferSize.X + coordCursor.X);
|
coordCursor.X = bufferSize.X + coordCursor.X;
|
||||||
coordCursor.Y = (SHORT)(coordCursor.Y - 1);
|
coordCursor.Y = coordCursor.Y - 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -91,7 +91,7 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
|
|||||||
auto srMargins = screenInfo.GetAbsoluteScrollMargins().ToInclusive();
|
auto srMargins = screenInfo.GetAbsoluteScrollMargins().ToInclusive();
|
||||||
const auto fMarginsSet = srMargins.Bottom > srMargins.Top;
|
const auto fMarginsSet = srMargins.Bottom > srMargins.Top;
|
||||||
auto currentCursor = screenInfo.GetTextBuffer().GetCursor().GetPosition();
|
auto currentCursor = screenInfo.GetTextBuffer().GetCursor().GetPosition();
|
||||||
const int iCurrentCursorY = currentCursor.Y;
|
const auto iCurrentCursorY = currentCursor.Y;
|
||||||
|
|
||||||
const auto fCursorInMargins = iCurrentCursorY <= srMargins.Bottom && iCurrentCursorY >= srMargins.Top;
|
const auto fCursorInMargins = iCurrentCursorY <= srMargins.Bottom && iCurrentCursorY >= srMargins.Top;
|
||||||
const auto cursorAboveViewport = coordCursor.Y < 0 && inVtMode;
|
const auto cursorAboveViewport = coordCursor.Y < 0 && inVtMode;
|
||||||
@@ -119,22 +119,22 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
|
|||||||
// To do this, we're going to scroll everything starting at the bottom
|
// To do this, we're going to scroll everything starting at the bottom
|
||||||
// margin down, then move the viewport down.
|
// margin down, then move the viewport down.
|
||||||
|
|
||||||
const SHORT delta = coordCursor.Y - srMargins.Bottom;
|
const auto delta = coordCursor.Y - srMargins.Bottom;
|
||||||
SMALL_RECT scrollRect{ 0 };
|
til::inclusive_rect scrollRect;
|
||||||
scrollRect.Left = 0;
|
scrollRect.Left = 0;
|
||||||
scrollRect.Top = srMargins.Bottom + 1; // One below margins
|
scrollRect.Top = srMargins.Bottom + 1; // One below margins
|
||||||
scrollRect.Bottom = bufferSize.Y - 1; // -1, otherwise this would be an exclusive rect.
|
scrollRect.Bottom = bufferSize.Y - 1; // -1, otherwise this would be an exclusive rect.
|
||||||
scrollRect.Right = bufferSize.X - 1; // -1, otherwise this would be an exclusive rect.
|
scrollRect.Right = bufferSize.X - 1; // -1, otherwise this would be an exclusive rect.
|
||||||
|
|
||||||
// This is the Y position we're moving the contents below the bottom margin to.
|
// This is the Y position we're moving the contents below the bottom margin to.
|
||||||
SHORT moveToYPosition = scrollRect.Top + delta;
|
auto moveToYPosition = scrollRect.Top + delta;
|
||||||
|
|
||||||
// This is where the viewport will need to be to give the effect of
|
// This is where the viewport will need to be to give the effect of
|
||||||
// scrolling the contents in the margins.
|
// scrolling the contents in the margins.
|
||||||
SHORT newViewTop = viewport.Top() + delta;
|
auto newViewTop = viewport.Top() + delta;
|
||||||
|
|
||||||
// This is how many new lines need to be added to the buffer to support this operation.
|
// This is how many new lines need to be added to the buffer to support this operation.
|
||||||
const SHORT newRows = (viewport.BottomExclusive() + delta) - bufferSize.Y;
|
const auto newRows = (viewport.BottomExclusive() + delta) - bufferSize.Y;
|
||||||
|
|
||||||
// If we're near the bottom of the buffer, we might need to insert some
|
// If we're near the bottom of the buffer, we might need to insert some
|
||||||
// new rows at the bottom.
|
// new rows at the bottom.
|
||||||
@@ -148,8 +148,8 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
|
|||||||
scrollRect.Top--;
|
scrollRect.Top--;
|
||||||
}
|
}
|
||||||
|
|
||||||
const COORD newPostMarginsOrigin = { 0, moveToYPosition };
|
const til::point newPostMarginsOrigin{ 0, moveToYPosition };
|
||||||
const COORD newViewOrigin = { 0, newViewTop };
|
const til::point newViewOrigin{ 0, newViewTop };
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -195,7 +195,7 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
|
|||||||
// And now we need to report that only the bottom line didn't "move" as we put the EEEE
|
// And now we need to report that only the bottom line didn't "move" as we put the EEEE
|
||||||
// back where it started, but everything else moved.
|
// back where it started, but everything else moved.
|
||||||
// In this case, delta was 1. So the amount that moved is the entire viewport height minus the delta.
|
// In this case, delta was 1. So the amount that moved is the entire viewport height minus the delta.
|
||||||
Viewport invalid = Viewport::FromDimensions(viewport.Origin(), { viewport.Width(), viewport.Height() - delta });
|
auto invalid = Viewport::FromDimensions(viewport.Origin(), { viewport.Width(), viewport.Height() - delta });
|
||||||
screenInfo.GetTextBuffer().TriggerRedraw(invalid);
|
screenInfo.GetTextBuffer().TriggerRedraw(invalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,15 +214,15 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
|
|||||||
// the margins content, and we can skip this.
|
// the margins content, and we can skip this.
|
||||||
if (fScrollUp || (fScrollDown && !scrollDownAtTop))
|
if (fScrollUp || (fScrollDown && !scrollDownAtTop))
|
||||||
{
|
{
|
||||||
SHORT diff = coordCursor.Y - (fScrollUp ? srMargins.Top : srMargins.Bottom);
|
auto diff = coordCursor.Y - (fScrollUp ? srMargins.Top : srMargins.Bottom);
|
||||||
|
|
||||||
SMALL_RECT scrollRect = { 0 };
|
til::inclusive_rect scrollRect;
|
||||||
scrollRect.Top = srMargins.Top;
|
scrollRect.Top = srMargins.Top;
|
||||||
scrollRect.Bottom = srMargins.Bottom;
|
scrollRect.Bottom = srMargins.Bottom;
|
||||||
scrollRect.Left = 0; // NOTE: Left/Right Scroll margins don't do anything currently.
|
scrollRect.Left = 0; // NOTE: Left/Right Scroll margins don't do anything currently.
|
||||||
scrollRect.Right = bufferSize.X - 1; // -1, otherwise this would be an exclusive rect.
|
scrollRect.Right = bufferSize.X - 1; // -1, otherwise this would be an exclusive rect.
|
||||||
|
|
||||||
COORD dest;
|
til::point dest;
|
||||||
dest.X = scrollRect.Left;
|
dest.X = scrollRect.Left;
|
||||||
dest.Y = scrollRect.Top - diff;
|
dest.Y = scrollRect.Top - diff;
|
||||||
|
|
||||||
@@ -257,9 +257,9 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
|
|||||||
|
|
||||||
if (nullptr != psScrollY)
|
if (nullptr != psScrollY)
|
||||||
{
|
{
|
||||||
*psScrollY += (SHORT)(bufferSize.Y - coordCursor.Y - 1);
|
*psScrollY += bufferSize.Y - coordCursor.Y - 1;
|
||||||
}
|
}
|
||||||
coordCursor.Y += (SHORT)(bufferSize.Y - coordCursor.Y - 1);
|
coordCursor.Y += bufferSize.Y - coordCursor.Y - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto cursorMovedPastViewport = coordCursor.Y > screenInfo.GetViewport().BottomInclusive();
|
const auto cursorMovedPastViewport = coordCursor.Y > screenInfo.GetViewport().BottomInclusive();
|
||||||
@@ -269,7 +269,7 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
|
|||||||
// if at right or bottom edge of window, scroll right or down one char.
|
// if at right or bottom edge of window, scroll right or down one char.
|
||||||
if (cursorMovedPastViewport)
|
if (cursorMovedPastViewport)
|
||||||
{
|
{
|
||||||
COORD WindowOrigin;
|
til::point WindowOrigin;
|
||||||
WindowOrigin.X = 0;
|
WindowOrigin.X = 0;
|
||||||
WindowOrigin.Y = coordCursor.Y - screenInfo.GetViewport().BottomInclusive();
|
WindowOrigin.Y = coordCursor.Y - screenInfo.GetViewport().BottomInclusive();
|
||||||
Status = screenInfo.SetViewportOrigin(false, WindowOrigin, true);
|
Status = screenInfo.SetViewportOrigin(false, WindowOrigin, true);
|
||||||
@@ -327,16 +327,16 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
|
|||||||
_In_reads_bytes_(*pcb) const wchar_t* pwchRealUnicode,
|
_In_reads_bytes_(*pcb) const wchar_t* pwchRealUnicode,
|
||||||
_Inout_ size_t* const pcb,
|
_Inout_ size_t* const pcb,
|
||||||
_Out_opt_ size_t* const pcSpaces,
|
_Out_opt_ size_t* const pcSpaces,
|
||||||
const SHORT sOriginalXPosition,
|
const til::CoordType sOriginalXPosition,
|
||||||
const DWORD dwFlags,
|
const DWORD dwFlags,
|
||||||
_Inout_opt_ PSHORT const psScrollY)
|
_Inout_opt_ til::CoordType* const psScrollY)
|
||||||
{
|
{
|
||||||
const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||||
auto& textBuffer = screenInfo.GetTextBuffer();
|
auto& textBuffer = screenInfo.GetTextBuffer();
|
||||||
auto& cursor = textBuffer.GetCursor();
|
auto& cursor = textBuffer.GetCursor();
|
||||||
auto CursorPosition = cursor.GetPosition();
|
auto CursorPosition = cursor.GetPosition();
|
||||||
auto Status = STATUS_SUCCESS;
|
auto Status = STATUS_SUCCESS;
|
||||||
SHORT XPosition;
|
til::CoordType XPosition;
|
||||||
size_t TempNumSpaces = 0;
|
size_t TempNumSpaces = 0;
|
||||||
const auto fUnprocessed = WI_IsFlagClear(screenInfo.OutputMode, ENABLE_PROCESSED_OUTPUT);
|
const auto fUnprocessed = WI_IsFlagClear(screenInfo.OutputMode, ENABLE_PROCESSED_OUTPUT);
|
||||||
const auto fWrapAtEOL = WI_IsFlagSet(screenInfo.OutputMode, ENABLE_WRAP_AT_EOL_OUTPUT);
|
const auto fWrapAtEOL = WI_IsFlagSet(screenInfo.OutputMode, ENABLE_WRAP_AT_EOL_OUTPUT);
|
||||||
@@ -357,7 +357,7 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
|
|||||||
coordScreenBufferSize.X = textBuffer.GetLineWidth(CursorPosition.Y);
|
coordScreenBufferSize.X = textBuffer.GetLineWidth(CursorPosition.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr unsigned int LOCAL_BUFFER_SIZE = 1024;
|
static constexpr til::CoordType LOCAL_BUFFER_SIZE = 1024;
|
||||||
WCHAR LocalBuffer[LOCAL_BUFFER_SIZE];
|
WCHAR LocalBuffer[LOCAL_BUFFER_SIZE];
|
||||||
|
|
||||||
while (*pcb < BufferSize)
|
while (*pcb < BufferSize)
|
||||||
@@ -386,7 +386,7 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
|
|||||||
|
|
||||||
// As an optimization, collect characters in buffer and print out all at once.
|
// As an optimization, collect characters in buffer and print out all at once.
|
||||||
XPosition = cursor.GetPosition().X;
|
XPosition = cursor.GetPosition().X;
|
||||||
size_t i = 0;
|
til::CoordType i = 0;
|
||||||
auto LocalBufPtr = LocalBuffer;
|
auto LocalBufPtr = LocalBuffer;
|
||||||
while (*pcb < BufferSize && i < LOCAL_BUFFER_SIZE && XPosition < coordScreenBufferSize.X)
|
while (*pcb < BufferSize && i < LOCAL_BUFFER_SIZE && XPosition < coordScreenBufferSize.X)
|
||||||
{
|
{
|
||||||
@@ -452,14 +452,14 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
|
|||||||
break;
|
break;
|
||||||
case UNICODE_TAB:
|
case UNICODE_TAB:
|
||||||
{
|
{
|
||||||
const ULONG TabSize = NUMBER_OF_SPACES_IN_TAB(XPosition);
|
const auto TabSize = NUMBER_OF_SPACES_IN_TAB(XPosition);
|
||||||
XPosition = (SHORT)(XPosition + TabSize);
|
XPosition = XPosition + TabSize;
|
||||||
if (XPosition >= coordScreenBufferSize.X)
|
if (XPosition >= coordScreenBufferSize.X)
|
||||||
{
|
{
|
||||||
goto EndWhile;
|
goto EndWhile;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ULONG j = 0; j < TabSize && i < LOCAL_BUFFER_SIZE; j++, i++)
|
for (til::CoordType j = 0; j < TabSize && i < LOCAL_BUFFER_SIZE; j++, i++)
|
||||||
{
|
{
|
||||||
*LocalBufPtr = UNICODE_SPACE;
|
*LocalBufPtr = UNICODE_SPACE;
|
||||||
LocalBufPtr++;
|
LocalBufPtr++;
|
||||||
@@ -547,9 +547,9 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
|
|||||||
|
|
||||||
// Make sure we don't write past the end of the buffer.
|
// Make sure we don't write past the end of the buffer.
|
||||||
// WCL-NOTE: This check uses a code unit count instead of a column count. That is incorrect.
|
// WCL-NOTE: This check uses a code unit count instead of a column count. That is incorrect.
|
||||||
if (i > gsl::narrow_cast<size_t>(coordScreenBufferSize.X) - CursorPosition.X)
|
if (i > coordScreenBufferSize.X - CursorPosition.X)
|
||||||
{
|
{
|
||||||
i = gsl::narrow_cast<size_t>(coordScreenBufferSize.X) - CursorPosition.X;
|
i = coordScreenBufferSize.X - CursorPosition.X;
|
||||||
}
|
}
|
||||||
|
|
||||||
// line was wrapped if we're writing up to the end of the current row
|
// line was wrapped if we're writing up to the end of the current row
|
||||||
@@ -559,7 +559,7 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
|
|||||||
// Notify accessibility
|
// Notify accessibility
|
||||||
if (screenInfo.HasAccessibilityEventing())
|
if (screenInfo.HasAccessibilityEventing())
|
||||||
{
|
{
|
||||||
screenInfo.NotifyAccessibilityEventing(CursorPosition.X, CursorPosition.Y, CursorPosition.X + gsl::narrow<SHORT>(i - 1), CursorPosition.Y);
|
screenInfo.NotifyAccessibilityEventing(CursorPosition.X, CursorPosition.Y, CursorPosition.X + i - 1, CursorPosition.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The number of "spaces" or "cells" we have consumed needs to be reported and stored for later
|
// The number of "spaces" or "cells" we have consumed needs to be reported and stored for later
|
||||||
@@ -633,7 +633,7 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
|
|||||||
wchar_t* Tmp2 = nullptr;
|
wchar_t* Tmp2 = nullptr;
|
||||||
WCHAR LastChar;
|
WCHAR LastChar;
|
||||||
|
|
||||||
const size_t bufferSize = pwchBuffer - pwchBufferBackupLimit;
|
const auto bufferSize = pwchBuffer - pwchBufferBackupLimit;
|
||||||
std::unique_ptr<wchar_t[]> buffer;
|
std::unique_ptr<wchar_t[]> buffer;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -677,9 +677,9 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
|
|||||||
|
|
||||||
if (LastChar == UNICODE_TAB)
|
if (LastChar == UNICODE_TAB)
|
||||||
{
|
{
|
||||||
CursorPosition.X -= (SHORT)(RetrieveNumberOfSpaces(sOriginalXPosition,
|
CursorPosition.X -= RetrieveNumberOfSpaces(sOriginalXPosition,
|
||||||
pwchBufferBackupLimit,
|
pwchBufferBackupLimit,
|
||||||
(ULONG)(pwchBuffer - pwchBufferBackupLimit - 1)));
|
pwchBuffer - pwchBufferBackupLimit - 1);
|
||||||
if (CursorPosition.X < 0)
|
if (CursorPosition.X < 0)
|
||||||
{
|
{
|
||||||
CursorPosition.X = (coordScreenBufferSize.X - 1) / TAB_SIZE;
|
CursorPosition.X = (coordScreenBufferSize.X - 1) / TAB_SIZE;
|
||||||
@@ -756,7 +756,7 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
|
|||||||
dwFlags & WC_PRINTABLE_CONTROL_CHARS))
|
dwFlags & WC_PRINTABLE_CONTROL_CHARS))
|
||||||
{
|
{
|
||||||
CursorPosition.X = coordScreenBufferSize.X - 1;
|
CursorPosition.X = coordScreenBufferSize.X - 1;
|
||||||
CursorPosition.Y = (SHORT)(cursor.GetPosition().Y - 1);
|
CursorPosition.Y = cursor.GetPosition().Y - 1;
|
||||||
|
|
||||||
// since you just backspaced yourself back up into the previous row, unset the wrap flag
|
// since you just backspaced yourself back up into the previous row, unset the wrap flag
|
||||||
// on the prev row if it was set
|
// on the prev row if it was set
|
||||||
@@ -778,8 +778,8 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
|
|||||||
}
|
}
|
||||||
case UNICODE_TAB:
|
case UNICODE_TAB:
|
||||||
{
|
{
|
||||||
const auto TabSize = gsl::narrow_cast<size_t>(NUMBER_OF_SPACES_IN_TAB(cursor.GetPosition().X));
|
const auto TabSize = NUMBER_OF_SPACES_IN_TAB(cursor.GetPosition().X);
|
||||||
CursorPosition.X = (SHORT)(cursor.GetPosition().X + TabSize);
|
CursorPosition.X = cursor.GetPosition().X + TabSize;
|
||||||
|
|
||||||
// move cursor forward to next tab stop. fill space with blanks.
|
// move cursor forward to next tab stop. fill space with blanks.
|
||||||
// we get here when the tab extends beyond the right edge of the
|
// we get here when the tab extends beyond the right edge of the
|
||||||
@@ -839,7 +839,7 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
|
|||||||
CursorPosition.X = 0;
|
CursorPosition.X = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CursorPosition.Y = (SHORT)(cursor.GetPosition().Y + 1);
|
CursorPosition.Y = cursor.GetPosition().Y + 1;
|
||||||
|
|
||||||
{
|
{
|
||||||
// since we explicitly just moved down a row, clear the wrap status on the row we just came from
|
// since we explicitly just moved down a row, clear the wrap status on the row we just came from
|
||||||
@@ -883,7 +883,7 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
|
|||||||
}
|
}
|
||||||
|
|
||||||
CursorPosition.X = 0;
|
CursorPosition.X = 0;
|
||||||
CursorPosition.Y = (SHORT)(TargetPoint.Y + 1);
|
CursorPosition.Y = TargetPoint.Y + 1;
|
||||||
|
|
||||||
// since you just moved yourself down onto the next row with 1 character, that sounds like a
|
// since you just moved yourself down onto the next row with 1 character, that sounds like a
|
||||||
// forced wrap so set the flag
|
// forced wrap so set the flag
|
||||||
@@ -942,9 +942,9 @@ using Microsoft::Console::VirtualTerminal::StateMachine;
|
|||||||
_In_reads_bytes_(*pcb) const wchar_t* pwchRealUnicode,
|
_In_reads_bytes_(*pcb) const wchar_t* pwchRealUnicode,
|
||||||
_Inout_ size_t* const pcb,
|
_Inout_ size_t* const pcb,
|
||||||
_Out_opt_ size_t* const pcSpaces,
|
_Out_opt_ size_t* const pcSpaces,
|
||||||
const SHORT sOriginalXPosition,
|
const til::CoordType sOriginalXPosition,
|
||||||
const DWORD dwFlags,
|
const DWORD dwFlags,
|
||||||
_Inout_opt_ PSHORT const psScrollY)
|
_Inout_opt_ til::CoordType* const psScrollY)
|
||||||
{
|
{
|
||||||
if (!WI_IsFlagSet(screenInfo.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING) ||
|
if (!WI_IsFlagSet(screenInfo.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING) ||
|
||||||
!WI_IsFlagSet(screenInfo.OutputMode, ENABLE_PROCESSED_OUTPUT))
|
!WI_IsFlagSet(screenInfo.OutputMode, ENABLE_PROCESSED_OUTPUT))
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ Arguments:
|
|||||||
Return Value:
|
Return Value:
|
||||||
--*/
|
--*/
|
||||||
[[nodiscard]] NTSTATUS AdjustCursorPosition(SCREEN_INFORMATION& screenInfo,
|
[[nodiscard]] NTSTATUS AdjustCursorPosition(SCREEN_INFORMATION& screenInfo,
|
||||||
_In_ COORD coordCursor,
|
_In_ til::point coordCursor,
|
||||||
const BOOL fKeepCursorVisible,
|
const BOOL fKeepCursorVisible,
|
||||||
_Inout_opt_ PSHORT psScrollY);
|
_Inout_opt_ til::CoordType* psScrollY);
|
||||||
|
|
||||||
/*++
|
/*++
|
||||||
Routine Description:
|
Routine Description:
|
||||||
@@ -73,9 +73,9 @@ Note:
|
|||||||
_In_reads_bytes_(*pcb) const wchar_t* pwchRealUnicode,
|
_In_reads_bytes_(*pcb) const wchar_t* pwchRealUnicode,
|
||||||
_Inout_ size_t* const pcb,
|
_Inout_ size_t* const pcb,
|
||||||
_Out_opt_ size_t* const pcSpaces,
|
_Out_opt_ size_t* const pcSpaces,
|
||||||
const SHORT sOriginalXPosition,
|
const til::CoordType sOriginalXPosition,
|
||||||
const DWORD dwFlags,
|
const DWORD dwFlags,
|
||||||
_Inout_opt_ PSHORT const psScrollY);
|
_Inout_opt_ til::CoordType* const psScrollY);
|
||||||
|
|
||||||
// The new entry point for WriteChars to act as an intercept in case we place a Virtual Terminal processor in the way.
|
// The new entry point for WriteChars to act as an intercept in case we place a Virtual Terminal processor in the way.
|
||||||
[[nodiscard]] NTSTATUS WriteChars(SCREEN_INFORMATION& screenInfo,
|
[[nodiscard]] NTSTATUS WriteChars(SCREEN_INFORMATION& screenInfo,
|
||||||
@@ -84,9 +84,9 @@ Note:
|
|||||||
_In_reads_bytes_(*pcb) const wchar_t* pwchRealUnicode,
|
_In_reads_bytes_(*pcb) const wchar_t* pwchRealUnicode,
|
||||||
_Inout_ size_t* const pcb,
|
_Inout_ size_t* const pcb,
|
||||||
_Out_opt_ size_t* const pcSpaces,
|
_Out_opt_ size_t* const pcSpaces,
|
||||||
const SHORT sOriginalXPosition,
|
const til::CoordType sOriginalXPosition,
|
||||||
const DWORD dwFlags,
|
const DWORD dwFlags,
|
||||||
_Inout_opt_ PSHORT const psScrollY);
|
_Inout_opt_ til::CoordType* const psScrollY);
|
||||||
|
|
||||||
// NOTE: console lock must be held when calling this routine
|
// NOTE: console lock must be held when calling this routine
|
||||||
// String has been translated to unicode at this point.
|
// String has been translated to unicode at this point.
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ void RedrawCommandLine(COOKED_READ_DATA& cookedReadData)
|
|||||||
// Draw the command line
|
// Draw the command line
|
||||||
cookedReadData.OriginalCursorPosition() = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
|
cookedReadData.OriginalCursorPosition() = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
|
||||||
|
|
||||||
SHORT ScrollY = 0;
|
til::CoordType ScrollY = 0;
|
||||||
#pragma prefast(suppress : 28931, "Status is not unused. It's used in debug assertions.")
|
#pragma prefast(suppress : 28931, "Status is not unused. It's used in debug assertions.")
|
||||||
auto Status = WriteCharsLegacy(cookedReadData.ScreenInfo(),
|
auto Status = WriteCharsLegacy(cookedReadData.ScreenInfo(),
|
||||||
cookedReadData.BufferStartPtr(),
|
cookedReadData.BufferStartPtr(),
|
||||||
@@ -264,9 +264,9 @@ void RedrawCommandLine(COOKED_READ_DATA& cookedReadData)
|
|||||||
|
|
||||||
// Move the cursor back to the right position
|
// Move the cursor back to the right position
|
||||||
auto CursorPosition = cookedReadData.OriginalCursorPosition();
|
auto CursorPosition = cookedReadData.OriginalCursorPosition();
|
||||||
CursorPosition.X += (SHORT)RetrieveTotalNumberOfSpaces(cookedReadData.OriginalCursorPosition().X,
|
CursorPosition.X += RetrieveTotalNumberOfSpaces(cookedReadData.OriginalCursorPosition().X,
|
||||||
cookedReadData.BufferStartPtr(),
|
cookedReadData.BufferStartPtr(),
|
||||||
cookedReadData.InsertionPoint());
|
cookedReadData.InsertionPoint());
|
||||||
if (CheckBisectStringW(cookedReadData.BufferStartPtr(),
|
if (CheckBisectStringW(cookedReadData.BufferStartPtr(),
|
||||||
cookedReadData.InsertionPoint(),
|
cookedReadData.InsertionPoint(),
|
||||||
cookedReadData.ScreenInfo().GetBufferSize().Width() - cookedReadData.OriginalCursorPosition().X))
|
cookedReadData.ScreenInfo().GetBufferSize().Width() - cookedReadData.OriginalCursorPosition().X))
|
||||||
@@ -289,7 +289,7 @@ void SetCurrentCommandLine(COOKED_READ_DATA& cookedReadData, _In_ SHORT Index) /
|
|||||||
FAIL_FAST_IF(!(cookedReadData.BufferStartPtr() == cookedReadData.BufferCurrentPtr()));
|
FAIL_FAST_IF(!(cookedReadData.BufferStartPtr() == cookedReadData.BufferCurrentPtr()));
|
||||||
if (cookedReadData.IsEchoInput())
|
if (cookedReadData.IsEchoInput())
|
||||||
{
|
{
|
||||||
SHORT ScrollY = 0;
|
til::CoordType ScrollY = 0;
|
||||||
FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
|
FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
|
||||||
cookedReadData.BufferStartPtr(),
|
cookedReadData.BufferStartPtr(),
|
||||||
cookedReadData.BufferCurrentPtr(),
|
cookedReadData.BufferCurrentPtr(),
|
||||||
@@ -453,7 +453,7 @@ void CommandLine::_processHistoryCycling(COOKED_READ_DATA& cookedReadData,
|
|||||||
FAIL_FAST_IF(!(cookedReadData.BufferStartPtr() == cookedReadData.BufferCurrentPtr()));
|
FAIL_FAST_IF(!(cookedReadData.BufferStartPtr() == cookedReadData.BufferCurrentPtr()));
|
||||||
if (cookedReadData.IsEchoInput())
|
if (cookedReadData.IsEchoInput())
|
||||||
{
|
{
|
||||||
short ScrollY = 0;
|
til::CoordType ScrollY = 0;
|
||||||
FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
|
FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
|
||||||
cookedReadData.BufferStartPtr(),
|
cookedReadData.BufferStartPtr(),
|
||||||
cookedReadData.BufferCurrentPtr(),
|
cookedReadData.BufferCurrentPtr(),
|
||||||
@@ -488,7 +488,7 @@ void CommandLine::_setPromptToOldestCommand(COOKED_READ_DATA& cookedReadData)
|
|||||||
FAIL_FAST_IF(!(cookedReadData.BufferStartPtr() == cookedReadData.BufferCurrentPtr()));
|
FAIL_FAST_IF(!(cookedReadData.BufferStartPtr() == cookedReadData.BufferCurrentPtr()));
|
||||||
if (cookedReadData.IsEchoInput())
|
if (cookedReadData.IsEchoInput())
|
||||||
{
|
{
|
||||||
short ScrollY = 0;
|
til::CoordType ScrollY = 0;
|
||||||
FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
|
FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
|
||||||
cookedReadData.BufferStartPtr(),
|
cookedReadData.BufferStartPtr(),
|
||||||
cookedReadData.BufferCurrentPtr(),
|
cookedReadData.BufferCurrentPtr(),
|
||||||
@@ -524,7 +524,7 @@ void CommandLine::_setPromptToNewestCommand(COOKED_READ_DATA& cookedReadData)
|
|||||||
FAIL_FAST_IF(!(cookedReadData.BufferStartPtr() == cookedReadData.BufferCurrentPtr()));
|
FAIL_FAST_IF(!(cookedReadData.BufferStartPtr() == cookedReadData.BufferCurrentPtr()));
|
||||||
if (cookedReadData.IsEchoInput())
|
if (cookedReadData.IsEchoInput())
|
||||||
{
|
{
|
||||||
short ScrollY = 0;
|
til::CoordType ScrollY = 0;
|
||||||
FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
|
FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
|
||||||
cookedReadData.BufferStartPtr(),
|
cookedReadData.BufferStartPtr(),
|
||||||
cookedReadData.BufferCurrentPtr(),
|
cookedReadData.BufferCurrentPtr(),
|
||||||
@@ -570,7 +570,7 @@ void CommandLine::DeletePromptAfterCursor(COOKED_READ_DATA& cookedReadData) noex
|
|||||||
// - cookedReadData - The cooked read data to operate on
|
// - cookedReadData - The cooked read data to operate on
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The new cursor position
|
// - The new cursor position
|
||||||
COORD CommandLine::_deletePromptBeforeCursor(COOKED_READ_DATA& cookedReadData) noexcept
|
til::point CommandLine::_deletePromptBeforeCursor(COOKED_READ_DATA& cookedReadData) noexcept
|
||||||
{
|
{
|
||||||
DeleteCommandLine(cookedReadData, false);
|
DeleteCommandLine(cookedReadData, false);
|
||||||
cookedReadData.BytesRead() -= cookedReadData.InsertionPoint() * sizeof(WCHAR);
|
cookedReadData.BytesRead() -= cookedReadData.InsertionPoint() * sizeof(WCHAR);
|
||||||
@@ -598,12 +598,12 @@ COORD CommandLine::_deletePromptBeforeCursor(COOKED_READ_DATA& cookedReadData) n
|
|||||||
// - cookedReadData - The cooked read data to operate on
|
// - cookedReadData - The cooked read data to operate on
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The new cursor position
|
// - The new cursor position
|
||||||
COORD CommandLine::_moveCursorToEndOfPrompt(COOKED_READ_DATA& cookedReadData) noexcept
|
til::point CommandLine::_moveCursorToEndOfPrompt(COOKED_READ_DATA& cookedReadData) noexcept
|
||||||
{
|
{
|
||||||
cookedReadData.InsertionPoint() = cookedReadData.BytesRead() / sizeof(WCHAR);
|
cookedReadData.InsertionPoint() = cookedReadData.BytesRead() / sizeof(WCHAR);
|
||||||
cookedReadData.SetBufferCurrentPtr(cookedReadData.BufferStartPtr() + cookedReadData.InsertionPoint());
|
cookedReadData.SetBufferCurrentPtr(cookedReadData.BufferStartPtr() + cookedReadData.InsertionPoint());
|
||||||
COORD cursorPosition{ 0, 0 };
|
til::point cursorPosition;
|
||||||
cursorPosition.X = (SHORT)(cookedReadData.OriginalCursorPosition().X + cookedReadData.VisibleCharCount());
|
cursorPosition.X = gsl::narrow<til::CoordType>(cookedReadData.OriginalCursorPosition().X + cookedReadData.VisibleCharCount());
|
||||||
cursorPosition.Y = cookedReadData.OriginalCursorPosition().Y;
|
cursorPosition.Y = cookedReadData.OriginalCursorPosition().Y;
|
||||||
|
|
||||||
const auto sScreenBufferSizeX = cookedReadData.ScreenInfo().GetBufferSize().Width();
|
const auto sScreenBufferSizeX = cookedReadData.ScreenInfo().GetBufferSize().Width();
|
||||||
@@ -625,7 +625,7 @@ COORD CommandLine::_moveCursorToEndOfPrompt(COOKED_READ_DATA& cookedReadData) no
|
|||||||
// - cookedReadData - The cooked read data to operate on
|
// - cookedReadData - The cooked read data to operate on
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The new cursor position
|
// - The new cursor position
|
||||||
COORD CommandLine::_moveCursorToStartOfPrompt(COOKED_READ_DATA& cookedReadData) noexcept
|
til::point CommandLine::_moveCursorToStartOfPrompt(COOKED_READ_DATA& cookedReadData) noexcept
|
||||||
{
|
{
|
||||||
cookedReadData.InsertionPoint() = 0;
|
cookedReadData.InsertionPoint() = 0;
|
||||||
cookedReadData.SetBufferCurrentPtr(cookedReadData.BufferStartPtr());
|
cookedReadData.SetBufferCurrentPtr(cookedReadData.BufferStartPtr());
|
||||||
@@ -638,7 +638,7 @@ COORD CommandLine::_moveCursorToStartOfPrompt(COOKED_READ_DATA& cookedReadData)
|
|||||||
// - cookedReadData - The cooked read data to operate on
|
// - cookedReadData - The cooked read data to operate on
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - New cursor position
|
// - New cursor position
|
||||||
COORD CommandLine::_moveCursorLeftByWord(COOKED_READ_DATA& cookedReadData) noexcept
|
til::point CommandLine::_moveCursorLeftByWord(COOKED_READ_DATA& cookedReadData) noexcept
|
||||||
{
|
{
|
||||||
PWCHAR LastWord;
|
PWCHAR LastWord;
|
||||||
auto cursorPosition = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
|
auto cursorPosition = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
|
||||||
@@ -699,12 +699,12 @@ COORD CommandLine::_moveCursorLeftByWord(COOKED_READ_DATA& cookedReadData) noexc
|
|||||||
}
|
}
|
||||||
cookedReadData.SetBufferCurrentPtr(LastWord);
|
cookedReadData.SetBufferCurrentPtr(LastWord);
|
||||||
}
|
}
|
||||||
cookedReadData.InsertionPoint() = (ULONG)(cookedReadData.BufferCurrentPtr() - cookedReadData.BufferStartPtr());
|
cookedReadData.InsertionPoint() = (cookedReadData.BufferCurrentPtr() - cookedReadData.BufferStartPtr());
|
||||||
cursorPosition = cookedReadData.OriginalCursorPosition();
|
cursorPosition = cookedReadData.OriginalCursorPosition();
|
||||||
cursorPosition.X = (SHORT)(cursorPosition.X +
|
cursorPosition.X = cursorPosition.X +
|
||||||
RetrieveTotalNumberOfSpaces(cookedReadData.OriginalCursorPosition().X,
|
RetrieveTotalNumberOfSpaces(cookedReadData.OriginalCursorPosition().X,
|
||||||
cookedReadData.BufferStartPtr(),
|
cookedReadData.BufferStartPtr(),
|
||||||
cookedReadData.InsertionPoint()));
|
cookedReadData.InsertionPoint());
|
||||||
const auto sScreenBufferSizeX = cookedReadData.ScreenInfo().GetBufferSize().Width();
|
const auto sScreenBufferSizeX = cookedReadData.ScreenInfo().GetBufferSize().Width();
|
||||||
if (CheckBisectStringW(cookedReadData.BufferStartPtr(),
|
if (CheckBisectStringW(cookedReadData.BufferStartPtr(),
|
||||||
cookedReadData.InsertionPoint() + 1,
|
cookedReadData.InsertionPoint() + 1,
|
||||||
@@ -722,7 +722,7 @@ COORD CommandLine::_moveCursorLeftByWord(COOKED_READ_DATA& cookedReadData) noexc
|
|||||||
// - cookedReadData - The cooked read data to operate on
|
// - cookedReadData - The cooked read data to operate on
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - New cursor position
|
// - New cursor position
|
||||||
COORD CommandLine::_moveCursorLeft(COOKED_READ_DATA& cookedReadData)
|
til::point CommandLine::_moveCursorLeft(COOKED_READ_DATA& cookedReadData)
|
||||||
{
|
{
|
||||||
auto cursorPosition = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
|
auto cursorPosition = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
|
||||||
if (cookedReadData.BufferCurrentPtr() != cookedReadData.BufferStartPtr())
|
if (cookedReadData.BufferCurrentPtr() != cookedReadData.BufferStartPtr())
|
||||||
@@ -731,10 +731,10 @@ COORD CommandLine::_moveCursorLeft(COOKED_READ_DATA& cookedReadData)
|
|||||||
cookedReadData.InsertionPoint()--;
|
cookedReadData.InsertionPoint()--;
|
||||||
cursorPosition.X = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition().X;
|
cursorPosition.X = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition().X;
|
||||||
cursorPosition.Y = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition().Y;
|
cursorPosition.Y = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition().Y;
|
||||||
cursorPosition.X = (SHORT)(cursorPosition.X -
|
cursorPosition.X = cursorPosition.X -
|
||||||
RetrieveNumberOfSpaces(cookedReadData.OriginalCursorPosition().X,
|
RetrieveNumberOfSpaces(cookedReadData.OriginalCursorPosition().X,
|
||||||
cookedReadData.BufferStartPtr(),
|
cookedReadData.BufferStartPtr(),
|
||||||
cookedReadData.InsertionPoint()));
|
cookedReadData.InsertionPoint());
|
||||||
const auto sScreenBufferSizeX = cookedReadData.ScreenInfo().GetBufferSize().Width();
|
const auto sScreenBufferSizeX = cookedReadData.ScreenInfo().GetBufferSize().Width();
|
||||||
if (CheckBisectProcessW(cookedReadData.ScreenInfo(),
|
if (CheckBisectProcessW(cookedReadData.ScreenInfo(),
|
||||||
cookedReadData.BufferStartPtr(),
|
cookedReadData.BufferStartPtr(),
|
||||||
@@ -758,7 +758,7 @@ COORD CommandLine::_moveCursorLeft(COOKED_READ_DATA& cookedReadData)
|
|||||||
// - cookedReadData - The cooked read data to operate on
|
// - cookedReadData - The cooked read data to operate on
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The new cursor position
|
// - The new cursor position
|
||||||
COORD CommandLine::_moveCursorRightByWord(COOKED_READ_DATA& cookedReadData) noexcept
|
til::point CommandLine::_moveCursorRightByWord(COOKED_READ_DATA& cookedReadData) noexcept
|
||||||
{
|
{
|
||||||
auto cursorPosition = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
|
auto cursorPosition = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
|
||||||
if (cookedReadData.InsertionPoint() < (cookedReadData.BytesRead() / sizeof(WCHAR)))
|
if (cookedReadData.InsertionPoint() < (cookedReadData.BytesRead() / sizeof(WCHAR)))
|
||||||
@@ -810,10 +810,10 @@ COORD CommandLine::_moveCursorRightByWord(COOKED_READ_DATA& cookedReadData) noex
|
|||||||
cookedReadData.SetBufferCurrentPtr(NextWord);
|
cookedReadData.SetBufferCurrentPtr(NextWord);
|
||||||
cookedReadData.InsertionPoint() = (ULONG)(cookedReadData.BufferCurrentPtr() - cookedReadData.BufferStartPtr());
|
cookedReadData.InsertionPoint() = (ULONG)(cookedReadData.BufferCurrentPtr() - cookedReadData.BufferStartPtr());
|
||||||
cursorPosition = cookedReadData.OriginalCursorPosition();
|
cursorPosition = cookedReadData.OriginalCursorPosition();
|
||||||
cursorPosition.X = (SHORT)(cursorPosition.X +
|
cursorPosition.X = cursorPosition.X +
|
||||||
RetrieveTotalNumberOfSpaces(cookedReadData.OriginalCursorPosition().X,
|
RetrieveTotalNumberOfSpaces(cookedReadData.OriginalCursorPosition().X,
|
||||||
cookedReadData.BufferStartPtr(),
|
cookedReadData.BufferStartPtr(),
|
||||||
cookedReadData.InsertionPoint()));
|
cookedReadData.InsertionPoint());
|
||||||
const auto sScreenBufferSizeX = cookedReadData.ScreenInfo().GetBufferSize().Width();
|
const auto sScreenBufferSizeX = cookedReadData.ScreenInfo().GetBufferSize().Width();
|
||||||
if (CheckBisectStringW(cookedReadData.BufferStartPtr(),
|
if (CheckBisectStringW(cookedReadData.BufferStartPtr(),
|
||||||
cookedReadData.InsertionPoint() + 1,
|
cookedReadData.InsertionPoint() + 1,
|
||||||
@@ -831,7 +831,7 @@ COORD CommandLine::_moveCursorRightByWord(COOKED_READ_DATA& cookedReadData) noex
|
|||||||
// - cookedReadData - The cooked read data to operate on
|
// - cookedReadData - The cooked read data to operate on
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The new cursor position
|
// - The new cursor position
|
||||||
COORD CommandLine::_moveCursorRight(COOKED_READ_DATA& cookedReadData) noexcept
|
til::point CommandLine::_moveCursorRight(COOKED_READ_DATA& cookedReadData) noexcept
|
||||||
{
|
{
|
||||||
auto cursorPosition = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
|
auto cursorPosition = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
|
||||||
const auto sScreenBufferSizeX = cookedReadData.ScreenInfo().GetBufferSize().Width();
|
const auto sScreenBufferSizeX = cookedReadData.ScreenInfo().GetBufferSize().Width();
|
||||||
@@ -839,10 +839,10 @@ COORD CommandLine::_moveCursorRight(COOKED_READ_DATA& cookedReadData) noexcept
|
|||||||
if (cookedReadData.InsertionPoint() < (cookedReadData.BytesRead() / sizeof(WCHAR)))
|
if (cookedReadData.InsertionPoint() < (cookedReadData.BytesRead() / sizeof(WCHAR)))
|
||||||
{
|
{
|
||||||
cursorPosition = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
|
cursorPosition = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
|
||||||
cursorPosition.X = (SHORT)(cursorPosition.X +
|
cursorPosition.X = cursorPosition.X +
|
||||||
RetrieveNumberOfSpaces(cookedReadData.OriginalCursorPosition().X,
|
RetrieveNumberOfSpaces(cookedReadData.OriginalCursorPosition().X,
|
||||||
cookedReadData.BufferStartPtr(),
|
cookedReadData.BufferStartPtr(),
|
||||||
cookedReadData.InsertionPoint()));
|
cookedReadData.InsertionPoint());
|
||||||
if (CheckBisectProcessW(cookedReadData.ScreenInfo(),
|
if (CheckBisectProcessW(cookedReadData.ScreenInfo(),
|
||||||
cookedReadData.BufferStartPtr(),
|
cookedReadData.BufferStartPtr(),
|
||||||
cookedReadData.InsertionPoint() + 2,
|
cookedReadData.InsertionPoint() + 2,
|
||||||
@@ -869,7 +869,7 @@ COORD CommandLine::_moveCursorRight(COOKED_READ_DATA& cookedReadData) noexcept
|
|||||||
cookedReadData.InsertionPoint()++;
|
cookedReadData.InsertionPoint()++;
|
||||||
if (cookedReadData.IsEchoInput())
|
if (cookedReadData.IsEchoInput())
|
||||||
{
|
{
|
||||||
short ScrollY = 0;
|
til::CoordType ScrollY = 0;
|
||||||
auto CharsToWrite = sizeof(WCHAR);
|
auto CharsToWrite = sizeof(WCHAR);
|
||||||
FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
|
FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
|
||||||
cookedReadData.BufferStartPtr(),
|
cookedReadData.BufferStartPtr(),
|
||||||
@@ -912,7 +912,7 @@ void CommandLine::_insertCtrlZ(COOKED_READ_DATA& cookedReadData) noexcept
|
|||||||
cookedReadData.InsertionPoint()++;
|
cookedReadData.InsertionPoint()++;
|
||||||
if (cookedReadData.IsEchoInput())
|
if (cookedReadData.IsEchoInput())
|
||||||
{
|
{
|
||||||
short ScrollY = 0;
|
til::CoordType ScrollY = 0;
|
||||||
auto CharsToWrite = sizeof(WCHAR);
|
auto CharsToWrite = sizeof(WCHAR);
|
||||||
FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
|
FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
|
||||||
cookedReadData.BufferStartPtr(),
|
cookedReadData.BufferStartPtr(),
|
||||||
@@ -963,7 +963,7 @@ void CommandLine::_fillPromptWithPreviousCommandFragment(COOKED_READ_DATA& cooke
|
|||||||
cookedReadData.BytesRead() = std::max(LastCommand.size() * sizeof(wchar_t), cookedReadData.BytesRead());
|
cookedReadData.BytesRead() = std::max(LastCommand.size() * sizeof(wchar_t), cookedReadData.BytesRead());
|
||||||
if (cookedReadData.IsEchoInput())
|
if (cookedReadData.IsEchoInput())
|
||||||
{
|
{
|
||||||
short ScrollY = 0;
|
til::CoordType ScrollY = 0;
|
||||||
FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
|
FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
|
||||||
cookedReadData.BufferStartPtr(),
|
cookedReadData.BufferStartPtr(),
|
||||||
cookedReadData.BufferCurrentPtr(),
|
cookedReadData.BufferCurrentPtr(),
|
||||||
@@ -987,7 +987,7 @@ void CommandLine::_fillPromptWithPreviousCommandFragment(COOKED_READ_DATA& cooke
|
|||||||
// - cookedReadData - The cooked read data to operate on
|
// - cookedReadData - The cooked read data to operate on
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The new cursor position
|
// - The new cursor position
|
||||||
COORD CommandLine::_cycleMatchingCommandHistoryToPrompt(COOKED_READ_DATA& cookedReadData)
|
til::point CommandLine::_cycleMatchingCommandHistoryToPrompt(COOKED_READ_DATA& cookedReadData)
|
||||||
{
|
{
|
||||||
auto cursorPosition = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
|
auto cursorPosition = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
|
||||||
if (cookedReadData.HasHistory())
|
if (cookedReadData.HasHistory())
|
||||||
@@ -998,10 +998,8 @@ COORD CommandLine::_cycleMatchingCommandHistoryToPrompt(COOKED_READ_DATA& cooked
|
|||||||
index,
|
index,
|
||||||
CommandHistory::MatchOptions::None))
|
CommandHistory::MatchOptions::None))
|
||||||
{
|
{
|
||||||
SHORT CurrentPos;
|
|
||||||
|
|
||||||
// save cursor position
|
// save cursor position
|
||||||
CurrentPos = (SHORT)cookedReadData.InsertionPoint();
|
const auto CurrentPos = cookedReadData.InsertionPoint();
|
||||||
|
|
||||||
DeleteCommandLine(cookedReadData, true);
|
DeleteCommandLine(cookedReadData, true);
|
||||||
THROW_IF_FAILED(cookedReadData.History().RetrieveNth((SHORT)index,
|
THROW_IF_FAILED(cookedReadData.History().RetrieveNth((SHORT)index,
|
||||||
@@ -1010,7 +1008,7 @@ COORD CommandLine::_cycleMatchingCommandHistoryToPrompt(COOKED_READ_DATA& cooked
|
|||||||
FAIL_FAST_IF(!(cookedReadData.BufferStartPtr() == cookedReadData.BufferCurrentPtr()));
|
FAIL_FAST_IF(!(cookedReadData.BufferStartPtr() == cookedReadData.BufferCurrentPtr()));
|
||||||
if (cookedReadData.IsEchoInput())
|
if (cookedReadData.IsEchoInput())
|
||||||
{
|
{
|
||||||
short ScrollY = 0;
|
til::CoordType ScrollY = 0;
|
||||||
FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
|
FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(cookedReadData.ScreenInfo(),
|
||||||
cookedReadData.BufferStartPtr(),
|
cookedReadData.BufferStartPtr(),
|
||||||
cookedReadData.BufferCurrentPtr(),
|
cookedReadData.BufferCurrentPtr(),
|
||||||
@@ -1039,7 +1037,7 @@ COORD CommandLine::_cycleMatchingCommandHistoryToPrompt(COOKED_READ_DATA& cooked
|
|||||||
// - cookedReadData - The cooked read data to operate on
|
// - cookedReadData - The cooked read data to operate on
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - The new cursor position
|
// - The new cursor position
|
||||||
COORD CommandLine::DeleteFromRightOfCursor(COOKED_READ_DATA& cookedReadData) noexcept
|
til::point CommandLine::DeleteFromRightOfCursor(COOKED_READ_DATA& cookedReadData) noexcept
|
||||||
{
|
{
|
||||||
// save cursor position
|
// save cursor position
|
||||||
auto cursorPosition = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
|
auto cursorPosition = cookedReadData.ScreenInfo().GetTextBuffer().GetCursor().GetPosition();
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ public:
|
|||||||
void EndAllPopups();
|
void EndAllPopups();
|
||||||
|
|
||||||
void DeletePromptAfterCursor(COOKED_READ_DATA& cookedReadData) noexcept;
|
void DeletePromptAfterCursor(COOKED_READ_DATA& cookedReadData) noexcept;
|
||||||
COORD DeleteFromRightOfCursor(COOKED_READ_DATA& cookedReadData) noexcept;
|
til::point DeleteFromRightOfCursor(COOKED_READ_DATA& cookedReadData) noexcept;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CommandLine();
|
CommandLine();
|
||||||
@@ -104,17 +104,17 @@ protected:
|
|||||||
void _processHistoryCycling(COOKED_READ_DATA& cookedReadData, const CommandHistory::SearchDirection searchDirection);
|
void _processHistoryCycling(COOKED_READ_DATA& cookedReadData, const CommandHistory::SearchDirection searchDirection);
|
||||||
void _setPromptToOldestCommand(COOKED_READ_DATA& cookedReadData);
|
void _setPromptToOldestCommand(COOKED_READ_DATA& cookedReadData);
|
||||||
void _setPromptToNewestCommand(COOKED_READ_DATA& cookedReadData);
|
void _setPromptToNewestCommand(COOKED_READ_DATA& cookedReadData);
|
||||||
COORD _deletePromptBeforeCursor(COOKED_READ_DATA& cookedReadData) noexcept;
|
til::point _deletePromptBeforeCursor(COOKED_READ_DATA& cookedReadData) noexcept;
|
||||||
COORD _moveCursorToEndOfPrompt(COOKED_READ_DATA& cookedReadData) noexcept;
|
til::point _moveCursorToEndOfPrompt(COOKED_READ_DATA& cookedReadData) noexcept;
|
||||||
COORD _moveCursorToStartOfPrompt(COOKED_READ_DATA& cookedReadData) noexcept;
|
til::point _moveCursorToStartOfPrompt(COOKED_READ_DATA& cookedReadData) noexcept;
|
||||||
COORD _moveCursorLeftByWord(COOKED_READ_DATA& cookedReadData) noexcept;
|
til::point _moveCursorLeftByWord(COOKED_READ_DATA& cookedReadData) noexcept;
|
||||||
COORD _moveCursorLeft(COOKED_READ_DATA& cookedReadData);
|
til::point _moveCursorLeft(COOKED_READ_DATA& cookedReadData);
|
||||||
COORD _moveCursorRightByWord(COOKED_READ_DATA& cookedReadData) noexcept;
|
til::point _moveCursorRightByWord(COOKED_READ_DATA& cookedReadData) noexcept;
|
||||||
COORD _moveCursorRight(COOKED_READ_DATA& cookedReadData) noexcept;
|
til::point _moveCursorRight(COOKED_READ_DATA& cookedReadData) noexcept;
|
||||||
void _insertCtrlZ(COOKED_READ_DATA& cookedReadData) noexcept;
|
void _insertCtrlZ(COOKED_READ_DATA& cookedReadData) noexcept;
|
||||||
void _deleteCommandHistory(COOKED_READ_DATA& cookedReadData) noexcept;
|
void _deleteCommandHistory(COOKED_READ_DATA& cookedReadData) noexcept;
|
||||||
void _fillPromptWithPreviousCommandFragment(COOKED_READ_DATA& cookedReadData) noexcept;
|
void _fillPromptWithPreviousCommandFragment(COOKED_READ_DATA& cookedReadData) noexcept;
|
||||||
COORD _cycleMatchingCommandHistoryToPrompt(COOKED_READ_DATA& cookedReadData);
|
til::point _cycleMatchingCommandHistoryToPrompt(COOKED_READ_DATA& cookedReadData);
|
||||||
|
|
||||||
#ifdef UNIT_TESTING
|
#ifdef UNIT_TESTING
|
||||||
friend class CommandLineTests;
|
friend class CommandLineTests;
|
||||||
|
|||||||
@@ -15,15 +15,13 @@
|
|||||||
using namespace Microsoft::Console::Types;
|
using namespace Microsoft::Console::Types;
|
||||||
using Microsoft::Console::Interactivity::ServiceLocator;
|
using Microsoft::Console::Interactivity::ServiceLocator;
|
||||||
|
|
||||||
ConversionAreaBufferInfo::ConversionAreaBufferInfo(const COORD coordBufferSize) :
|
ConversionAreaBufferInfo::ConversionAreaBufferInfo(const til::size coordBufferSize) :
|
||||||
coordCaBuffer(coordBufferSize),
|
coordCaBuffer(coordBufferSize)
|
||||||
rcViewCaWindow({ 0 }),
|
|
||||||
coordConView({ 0 })
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ConversionAreaInfo::ConversionAreaInfo(const COORD bufferSize,
|
ConversionAreaInfo::ConversionAreaInfo(const til::size bufferSize,
|
||||||
const COORD windowSize,
|
const til::size windowSize,
|
||||||
const TextAttribute& fill,
|
const TextAttribute& fill,
|
||||||
const TextAttribute& popupFill,
|
const TextAttribute& popupFill,
|
||||||
const FontInfo fontInfo) :
|
const FontInfo fontInfo) :
|
||||||
@@ -110,7 +108,7 @@ void ConversionAreaInfo::SetAttributes(const TextAttribute& attr)
|
|||||||
// - text - Text to insert into the conversion area buffer
|
// - text - Text to insert into the conversion area buffer
|
||||||
// - column - Column to start at (X position)
|
// - column - Column to start at (X position)
|
||||||
void ConversionAreaInfo::WriteText(const std::vector<OutputCell>& text,
|
void ConversionAreaInfo::WriteText(const std::vector<OutputCell>& text,
|
||||||
const SHORT column)
|
const til::CoordType column)
|
||||||
{
|
{
|
||||||
gsl::span<const OutputCell> view(text.data(), text.size());
|
gsl::span<const OutputCell> view(text.data(), text.size());
|
||||||
_screenBuffer->Write(view, { column, 0 });
|
_screenBuffer->Write(view, { column, 0 });
|
||||||
@@ -131,7 +129,7 @@ void ConversionAreaInfo::ClearArea() noexcept
|
|||||||
Paint();
|
Paint();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] HRESULT ConversionAreaInfo::Resize(const COORD newSize) noexcept
|
[[nodiscard]] HRESULT ConversionAreaInfo::Resize(const til::size newSize) noexcept
|
||||||
{
|
{
|
||||||
// attempt to resize underlying buffers
|
// attempt to resize underlying buffers
|
||||||
RETURN_IF_NTSTATUS_FAILED(_screenBuffer->ResizeScreenBuffer(newSize, FALSE));
|
RETURN_IF_NTSTATUS_FAILED(_screenBuffer->ResizeScreenBuffer(newSize, FALSE));
|
||||||
@@ -140,7 +138,7 @@ void ConversionAreaInfo::ClearArea() noexcept
|
|||||||
_caInfo.coordCaBuffer = newSize;
|
_caInfo.coordCaBuffer = newSize;
|
||||||
|
|
||||||
// restrict viewport to buffer size.
|
// restrict viewport to buffer size.
|
||||||
const COORD restriction = { newSize.X - 1i16, newSize.Y - 1i16 };
|
const til::point restriction = { newSize.X - 1, newSize.Y - 1 };
|
||||||
_caInfo.rcViewCaWindow.Left = std::min(_caInfo.rcViewCaWindow.Left, restriction.X);
|
_caInfo.rcViewCaWindow.Left = std::min(_caInfo.rcViewCaWindow.Left, restriction.X);
|
||||||
_caInfo.rcViewCaWindow.Right = std::min(_caInfo.rcViewCaWindow.Right, restriction.X);
|
_caInfo.rcViewCaWindow.Right = std::min(_caInfo.rcViewCaWindow.Right, restriction.X);
|
||||||
_caInfo.rcViewCaWindow.Top = std::min(_caInfo.rcViewCaWindow.Top, restriction.Y);
|
_caInfo.rcViewCaWindow.Top = std::min(_caInfo.rcViewCaWindow.Top, restriction.Y);
|
||||||
@@ -149,7 +147,7 @@ void ConversionAreaInfo::ClearArea() noexcept
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConversionAreaInfo::SetWindowInfo(const SMALL_RECT view) noexcept
|
void ConversionAreaInfo::SetWindowInfo(const til::inclusive_rect& view) noexcept
|
||||||
{
|
{
|
||||||
if (view.Left != _caInfo.rcViewCaWindow.Left ||
|
if (view.Left != _caInfo.rcViewCaWindow.Left ||
|
||||||
view.Top != _caInfo.rcViewCaWindow.Top ||
|
view.Top != _caInfo.rcViewCaWindow.Top ||
|
||||||
@@ -172,7 +170,7 @@ void ConversionAreaInfo::SetWindowInfo(const SMALL_RECT view) noexcept
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConversionAreaInfo::SetViewPos(const COORD pos) noexcept
|
void ConversionAreaInfo::SetViewPos(const til::point pos) noexcept
|
||||||
{
|
{
|
||||||
if (IsHidden())
|
if (IsHidden())
|
||||||
{
|
{
|
||||||
@@ -206,7 +204,7 @@ void ConversionAreaInfo::Paint() const noexcept
|
|||||||
auto& ScreenInfo = gci.GetActiveOutputBuffer();
|
auto& ScreenInfo = gci.GetActiveOutputBuffer();
|
||||||
const auto viewport = ScreenInfo.GetViewport();
|
const auto viewport = ScreenInfo.GetViewport();
|
||||||
|
|
||||||
SMALL_RECT WriteRegion;
|
til::inclusive_rect WriteRegion;
|
||||||
WriteRegion.Left = viewport.Left() + _caInfo.coordConView.X + _caInfo.rcViewCaWindow.Left;
|
WriteRegion.Left = viewport.Left() + _caInfo.coordConView.X + _caInfo.rcViewCaWindow.Left;
|
||||||
WriteRegion.Right = WriteRegion.Left + (_caInfo.rcViewCaWindow.Right - _caInfo.rcViewCaWindow.Left);
|
WriteRegion.Right = WriteRegion.Left + (_caInfo.rcViewCaWindow.Right - _caInfo.rcViewCaWindow.Left);
|
||||||
WriteRegion.Top = viewport.Top() + _caInfo.coordConView.Y + _caInfo.rcViewCaWindow.Top;
|
WriteRegion.Top = viewport.Top() + _caInfo.coordConView.Y + _caInfo.rcViewCaWindow.Top;
|
||||||
|
|||||||
@@ -30,18 +30,18 @@ class TextBuffer;
|
|||||||
class ConversionAreaBufferInfo final
|
class ConversionAreaBufferInfo final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
COORD coordCaBuffer;
|
til::size coordCaBuffer;
|
||||||
SMALL_RECT rcViewCaWindow;
|
til::inclusive_rect rcViewCaWindow;
|
||||||
COORD coordConView;
|
til::point coordConView;
|
||||||
|
|
||||||
explicit ConversionAreaBufferInfo(const COORD coordBufferSize);
|
explicit ConversionAreaBufferInfo(const til::size coordBufferSize);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConversionAreaInfo final
|
class ConversionAreaInfo final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ConversionAreaInfo(const COORD bufferSize,
|
ConversionAreaInfo(const til::size bufferSize,
|
||||||
const COORD windowSize,
|
const til::size windowSize,
|
||||||
const TextAttribute& fill,
|
const TextAttribute& fill,
|
||||||
const TextAttribute& popupFill,
|
const TextAttribute& popupFill,
|
||||||
const FontInfo fontInfo);
|
const FontInfo fontInfo);
|
||||||
@@ -55,13 +55,13 @@ public:
|
|||||||
void SetHidden(const bool fIsHidden) noexcept;
|
void SetHidden(const bool fIsHidden) noexcept;
|
||||||
void ClearArea() noexcept;
|
void ClearArea() noexcept;
|
||||||
|
|
||||||
[[nodiscard]] HRESULT Resize(const COORD newSize) noexcept;
|
[[nodiscard]] HRESULT Resize(const til::size newSize) noexcept;
|
||||||
|
|
||||||
void SetViewPos(const COORD pos) noexcept;
|
void SetViewPos(const til::point pos) noexcept;
|
||||||
void SetWindowInfo(const SMALL_RECT view) noexcept;
|
void SetWindowInfo(const til::inclusive_rect& view) noexcept;
|
||||||
void Paint() const noexcept;
|
void Paint() const noexcept;
|
||||||
|
|
||||||
void WriteText(const std::vector<OutputCell>& text, const SHORT column);
|
void WriteText(const std::vector<OutputCell>& text, const til::CoordType column);
|
||||||
void SetAttributes(const TextAttribute& attr);
|
void SetAttributes(const TextAttribute& attr);
|
||||||
|
|
||||||
const TextBuffer& GetTextBuffer() const noexcept;
|
const TextBuffer& GetTextBuffer() const noexcept;
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ void ConsoleImeInfo::ClearAllAreas()
|
|||||||
// - newSize - New size for conversion areas
|
// - newSize - New size for conversion areas
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - S_OK or appropriate failure HRESULT.
|
// - S_OK or appropriate failure HRESULT.
|
||||||
[[nodiscard]] HRESULT ConsoleImeInfo::ResizeAllAreas(const COORD newSize)
|
[[nodiscard]] HRESULT ConsoleImeInfo::ResizeAllAreas(const til::size newSize)
|
||||||
{
|
{
|
||||||
for (auto& area : ConvAreaCompStr)
|
for (auto& area : ConvAreaCompStr)
|
||||||
{
|
{
|
||||||
@@ -310,7 +310,7 @@ std::vector<OutputCell> ConsoleImeInfo::s_ConvertToCells(const std::wstring_view
|
|||||||
// If the viewport is deemed too small, we'll skip past it and advance begin past the entire full-width character.
|
// If the viewport is deemed too small, we'll skip past it and advance begin past the entire full-width character.
|
||||||
std::vector<OutputCell>::const_iterator ConsoleImeInfo::_WriteConversionArea(const std::vector<OutputCell>::const_iterator begin,
|
std::vector<OutputCell>::const_iterator ConsoleImeInfo::_WriteConversionArea(const std::vector<OutputCell>::const_iterator begin,
|
||||||
const std::vector<OutputCell>::const_iterator end,
|
const std::vector<OutputCell>::const_iterator end,
|
||||||
COORD& pos,
|
til::point& pos,
|
||||||
const Microsoft::Console::Types::Viewport view,
|
const Microsoft::Console::Types::Viewport view,
|
||||||
SCREEN_INFORMATION& screenInfo)
|
SCREEN_INFORMATION& screenInfo)
|
||||||
{
|
{
|
||||||
@@ -372,7 +372,7 @@ std::vector<OutputCell>::const_iterator ConsoleImeInfo::_WriteConversionArea(con
|
|||||||
|
|
||||||
// Set the viewport and positioning parameters for the conversion area to describe to the renderer
|
// Set the viewport and positioning parameters for the conversion area to describe to the renderer
|
||||||
// the appropriate location to overlay this conversion area on top of the main screen buffer inside the viewport.
|
// the appropriate location to overlay this conversion area on top of the main screen buffer inside the viewport.
|
||||||
const SMALL_RECT region{ insertionPos.X, 0, gsl::narrow<SHORT>(insertionPos.X + lineVec.size() - 1), 0 };
|
const til::inclusive_rect region{ insertionPos.X, 0, gsl::narrow<til::CoordType>(insertionPos.X + lineVec.size() - 1), 0 };
|
||||||
area.SetWindowInfo(region);
|
area.SetWindowInfo(region);
|
||||||
area.SetViewPos({ 0 - view.Left(), insertionPos.Y - view.Top() });
|
area.SetViewPos({ 0 - view.Left(), insertionPos.Y - view.Top() });
|
||||||
|
|
||||||
@@ -383,7 +383,7 @@ std::vector<OutputCell>::const_iterator ConsoleImeInfo::_WriteConversionArea(con
|
|||||||
// Notify accessibility that we have updated the text in this display region within the viewport.
|
// Notify accessibility that we have updated the text in this display region within the viewport.
|
||||||
if (screenInfo.HasAccessibilityEventing())
|
if (screenInfo.HasAccessibilityEventing())
|
||||||
{
|
{
|
||||||
screenInfo.NotifyAccessibilityEventing(insertionPos.X, insertionPos.Y, gsl::narrow<SHORT>(insertionPos.X + lineVec.size() - 1), insertionPos.Y);
|
screenInfo.NotifyAccessibilityEventing(region.left, insertionPos.Y, region.right, insertionPos.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hand back the iterator representing the end of what we used to be fed into the beginning of the next call.
|
// Hand back the iterator representing the end of what we used to be fed into the beginning of the next call.
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public:
|
|||||||
void RefreshAreaAttributes();
|
void RefreshAreaAttributes();
|
||||||
void ClearAllAreas();
|
void ClearAllAreas();
|
||||||
|
|
||||||
[[nodiscard]] HRESULT ResizeAllAreas(const COORD newSize);
|
[[nodiscard]] HRESULT ResizeAllAreas(const til::size newSize);
|
||||||
|
|
||||||
void WriteCompMessage(const std::wstring_view text,
|
void WriteCompMessage(const std::wstring_view text,
|
||||||
const gsl::span<const BYTE> attributes,
|
const gsl::span<const BYTE> attributes,
|
||||||
@@ -79,7 +79,7 @@ private:
|
|||||||
|
|
||||||
std::vector<OutputCell>::const_iterator _WriteConversionArea(const std::vector<OutputCell>::const_iterator begin,
|
std::vector<OutputCell>::const_iterator _WriteConversionArea(const std::vector<OutputCell>::const_iterator begin,
|
||||||
const std::vector<OutputCell>::const_iterator end,
|
const std::vector<OutputCell>::const_iterator end,
|
||||||
COORD& pos,
|
til::point& pos,
|
||||||
const Microsoft::Console::Types::Viewport view,
|
const Microsoft::Console::Types::Viewport view,
|
||||||
SCREEN_INFORMATION& screenInfo);
|
SCREEN_INFORMATION& screenInfo);
|
||||||
|
|
||||||
|
|||||||
@@ -26,4 +26,4 @@ void WriteConvRegionToScreen(const SCREEN_INFORMATION& ScreenInfo,
|
|||||||
const Microsoft::Console::Types::Viewport& convRegion);
|
const Microsoft::Console::Types::Viewport& convRegion);
|
||||||
|
|
||||||
[[nodiscard]] HRESULT ConsoleImeResizeCompStrView();
|
[[nodiscard]] HRESULT ConsoleImeResizeCompStrView();
|
||||||
[[nodiscard]] HRESULT ConsoleImeResizeCompStrScreenBuffer(const COORD coordNewScreenSize);
|
[[nodiscard]] HRESULT ConsoleImeResizeCompStrScreenBuffer(const til::size coordNewScreenSize);
|
||||||
|
|||||||
@@ -12,11 +12,6 @@
|
|||||||
using namespace Microsoft::Console::Types;
|
using namespace Microsoft::Console::Types;
|
||||||
using Microsoft::Console::Interactivity::ServiceLocator;
|
using Microsoft::Console::Interactivity::ServiceLocator;
|
||||||
|
|
||||||
bool IsValidSmallRect(_In_ PSMALL_RECT const Rect)
|
|
||||||
{
|
|
||||||
return (Rect->Right >= Rect->Left && Rect->Bottom >= Rect->Top);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WriteConvRegionToScreen(const SCREEN_INFORMATION& ScreenInfo,
|
void WriteConvRegionToScreen(const SCREEN_INFORMATION& ScreenInfo,
|
||||||
const Viewport& convRegion)
|
const Viewport& convRegion)
|
||||||
{
|
{
|
||||||
@@ -38,38 +33,31 @@ void WriteConvRegionToScreen(const SCREEN_INFORMATION& ScreenInfo,
|
|||||||
const auto areaInfo = ConvAreaInfo.GetAreaBufferInfo();
|
const auto areaInfo = ConvAreaInfo.GetAreaBufferInfo();
|
||||||
|
|
||||||
// Do clipping region
|
// Do clipping region
|
||||||
SMALL_RECT Region;
|
til::inclusive_rect Region;
|
||||||
Region.Left = currentViewport.Left + areaInfo.rcViewCaWindow.Left + areaInfo.coordConView.X;
|
Region.Left = currentViewport.Left + areaInfo.rcViewCaWindow.Left + areaInfo.coordConView.X;
|
||||||
Region.Right = Region.Left + (areaInfo.rcViewCaWindow.Right - areaInfo.rcViewCaWindow.Left);
|
Region.Right = Region.Left + (areaInfo.rcViewCaWindow.Right - areaInfo.rcViewCaWindow.Left);
|
||||||
Region.Top = currentViewport.Top + areaInfo.rcViewCaWindow.Top + areaInfo.coordConView.Y;
|
Region.Top = currentViewport.Top + areaInfo.rcViewCaWindow.Top + areaInfo.coordConView.Y;
|
||||||
Region.Bottom = Region.Top + (areaInfo.rcViewCaWindow.Bottom - areaInfo.rcViewCaWindow.Top);
|
Region.Bottom = Region.Top + (areaInfo.rcViewCaWindow.Bottom - areaInfo.rcViewCaWindow.Top);
|
||||||
|
|
||||||
SMALL_RECT ClippedRegion;
|
Region.Left = std::max(Region.Left, currentViewport.Left);
|
||||||
ClippedRegion.Left = std::max(Region.Left, currentViewport.Left);
|
Region.Top = std::max(Region.Top, currentViewport.Top);
|
||||||
ClippedRegion.Top = std::max(Region.Top, currentViewport.Top);
|
Region.Right = std::min(Region.Right, currentViewport.Right);
|
||||||
ClippedRegion.Right = std::min(Region.Right, currentViewport.Right);
|
Region.Bottom = std::min(Region.Bottom, currentViewport.Bottom);
|
||||||
ClippedRegion.Bottom = std::min(Region.Bottom, currentViewport.Bottom);
|
|
||||||
|
|
||||||
if (IsValidSmallRect(&ClippedRegion))
|
if (Region)
|
||||||
{
|
{
|
||||||
Region = ClippedRegion;
|
Region.Left = std::max(Region.Left, convRegion.Left());
|
||||||
ClippedRegion.Left = std::max(Region.Left, convRegion.Left());
|
Region.Top = std::max(Region.Top, convRegion.Top());
|
||||||
ClippedRegion.Top = std::max(Region.Top, convRegion.Top());
|
Region.Right = std::min(Region.Right, convRegion.RightInclusive());
|
||||||
ClippedRegion.Right = std::min(Region.Right, convRegion.RightInclusive());
|
Region.Bottom = std::min(Region.Bottom, convRegion.BottomInclusive());
|
||||||
ClippedRegion.Bottom = std::min(Region.Bottom, convRegion.BottomInclusive());
|
if (Region)
|
||||||
if (IsValidSmallRect(&ClippedRegion))
|
|
||||||
{
|
{
|
||||||
// if we have a renderer, we need to update.
|
// if we have a renderer, we need to update.
|
||||||
// we've already confirmed (above with an early return) that we're on conversion areas that are a part of the active (visible/rendered) screen
|
// we've already confirmed (above with an early return) that we're on conversion areas that are a part of the active (visible/rendered) screen
|
||||||
// so send invalidates to those regions such that we're queried for data on the next frame and repainted.
|
// so send invalidates to those regions such that we're queried for data on the next frame and repainted.
|
||||||
if (ServiceLocator::LocateGlobals().pRender != nullptr)
|
if (ServiceLocator::LocateGlobals().pRender != nullptr)
|
||||||
{
|
{
|
||||||
// convert inclusive rectangle to exclusive rectangle
|
ServiceLocator::LocateGlobals().pRender->TriggerRedraw(Viewport::FromInclusive(Region));
|
||||||
auto srExclusive = ClippedRegion;
|
|
||||||
srExclusive.Right++;
|
|
||||||
srExclusive.Bottom++;
|
|
||||||
|
|
||||||
ServiceLocator::LocateGlobals().pRender->TriggerRedraw(Viewport::FromExclusive(srExclusive));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,7 +78,7 @@ void WriteConvRegionToScreen(const SCREEN_INFORMATION& ScreenInfo,
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] HRESULT ConsoleImeResizeCompStrScreenBuffer(const COORD coordNewScreenSize)
|
[[nodiscard]] HRESULT ConsoleImeResizeCompStrScreenBuffer(const til::size coordNewScreenSize)
|
||||||
{
|
{
|
||||||
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||||
const auto pIme = &gci.ConsoleIme;
|
const auto pIme = &gci.ConsoleIme;
|
||||||
|
|||||||
@@ -537,9 +537,9 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
|
|||||||
auto tempIter = tempBuffer.cbegin();
|
auto tempIter = tempBuffer.cbegin();
|
||||||
auto outIter = buffer.begin();
|
auto outIter = buffer.begin();
|
||||||
|
|
||||||
for (auto i = 0; i < size.Y; i++)
|
for (til::CoordType i = 0; i < size.Y; i++)
|
||||||
{
|
{
|
||||||
for (auto j = 0; j < size.X; j++)
|
for (til::CoordType j = 0; j < size.X; j++)
|
||||||
{
|
{
|
||||||
// Any time we see the lead flag, we presume there will be a trailing one following it.
|
// Any time we see the lead flag, we presume there will be a trailing one following it.
|
||||||
// Giving us two bytes of space (one per cell in the ascii part of the character union)
|
// Giving us two bytes of space (one per cell in the ascii part of the character union)
|
||||||
@@ -615,9 +615,9 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
|
|||||||
const auto size = rectangle.Dimensions();
|
const auto size = rectangle.Dimensions();
|
||||||
auto outIter = buffer.begin();
|
auto outIter = buffer.begin();
|
||||||
|
|
||||||
for (auto i = 0; i < size.Y; i++)
|
for (til::CoordType i = 0; i < size.Y; i++)
|
||||||
{
|
{
|
||||||
for (auto j = 0; j < size.X; j++)
|
for (til::CoordType j = 0; j < size.X; j++)
|
||||||
{
|
{
|
||||||
// Clear lead/trailing flags. We'll determine it for ourselves versus the given codepage.
|
// Clear lead/trailing flags. We'll determine it for ourselves versus the given codepage.
|
||||||
WI_ClearAllFlags(outIter->Attributes, COMMON_LVB_SBCSDBCS);
|
WI_ClearAllFlags(outIter->Attributes, COMMON_LVB_SBCSDBCS);
|
||||||
@@ -684,9 +684,9 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
|
|||||||
const auto size = rectangle.Dimensions();
|
const auto size = rectangle.Dimensions();
|
||||||
auto bufferIter = buffer.begin();
|
auto bufferIter = buffer.begin();
|
||||||
|
|
||||||
for (SHORT i = 0; i < size.Y; i++)
|
for (til::CoordType i = 0; i < size.Y; i++)
|
||||||
{
|
{
|
||||||
for (SHORT j = 0; j < size.X; j++)
|
for (til::CoordType j = 0; j < size.X; j++)
|
||||||
{
|
{
|
||||||
// Prepare a candidate charinfo on the output side copying the colors but not the lead/trail information.
|
// Prepare a candidate charinfo on the output side copying the colors but not the lead/trail information.
|
||||||
CHAR_INFO candidate;
|
CHAR_INFO candidate;
|
||||||
@@ -756,8 +756,7 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The buffer given should be big enough to hold the dimensions of the request.
|
// The buffer given should be big enough to hold the dimensions of the request.
|
||||||
size_t targetArea;
|
const auto targetArea = targetSize.area<size_t>();
|
||||||
RETURN_IF_FAILED(SizeTMult(targetSize.X, targetSize.Y, &targetArea));
|
|
||||||
RETURN_HR_IF(E_INVALIDARG, targetArea < targetBuffer.size());
|
RETURN_HR_IF(E_INVALIDARG, targetArea < targetBuffer.size());
|
||||||
|
|
||||||
// Clip the request rectangle to the size of the storage buffer
|
// Clip the request rectangle to the size of the storage buffer
|
||||||
@@ -767,13 +766,13 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
|
|||||||
|
|
||||||
// Find the target point (where to write the user's buffer)
|
// Find the target point (where to write the user's buffer)
|
||||||
// It will either be 0,0 or offset into the buffer by the inverse of the negative values.
|
// It will either be 0,0 or offset into the buffer by the inverse of the negative values.
|
||||||
COORD targetPoint;
|
til::point targetPoint;
|
||||||
targetPoint.X = clip.Left < 0 ? -clip.Left : 0;
|
targetPoint.X = clip.Left < 0 ? -clip.Left : 0;
|
||||||
targetPoint.Y = clip.Top < 0 ? -clip.Top : 0;
|
targetPoint.Y = clip.Top < 0 ? -clip.Top : 0;
|
||||||
|
|
||||||
// The clipped rect must be inside the buffer size, so it has a minimum value of 0. (max of itself and 0)
|
// The clipped rect must be inside the buffer size, so it has a minimum value of 0. (max of itself and 0)
|
||||||
clip.Left = std::max(clip.Left, 0i16);
|
clip.Left = std::max(clip.Left, 0);
|
||||||
clip.Top = std::max(clip.Top, 0i16);
|
clip.Top = std::max(clip.Top, 0);
|
||||||
|
|
||||||
// The final "request rectangle" or the area inside the buffer we want to read, is the clipped dimensions.
|
// The final "request rectangle" or the area inside the buffer we want to read, is the clipped dimensions.
|
||||||
const auto clippedRequestRectangle = Viewport::FromExclusive(clip);
|
const auto clippedRequestRectangle = Viewport::FromExclusive(clip);
|
||||||
@@ -784,7 +783,7 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
|
|||||||
// Get an iterator to the beginning of the return buffer
|
// Get an iterator to the beginning of the return buffer
|
||||||
// We might have to seek this forward or skip around if we clipped the request.
|
// We might have to seek this forward or skip around if we clipped the request.
|
||||||
auto targetIter = targetBuffer.begin();
|
auto targetIter = targetBuffer.begin();
|
||||||
COORD targetPos = { 0 };
|
til::point targetPos;
|
||||||
const auto targetLimit = Viewport::FromDimensions(targetPoint, clippedRequestRectangle.Dimensions());
|
const auto targetLimit = Viewport::FromDimensions(targetPoint, clippedRequestRectangle.Dimensions());
|
||||||
|
|
||||||
// Get an iterator to the beginning of the request inside the screen buffer
|
// Get an iterator to the beginning of the request inside the screen buffer
|
||||||
@@ -902,7 +901,7 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
|
|||||||
|
|
||||||
// Do clipping according to the legacy patterns.
|
// Do clipping according to the legacy patterns.
|
||||||
auto writeRegion = requestRectangle.ToInclusive();
|
auto writeRegion = requestRectangle.ToInclusive();
|
||||||
SMALL_RECT sourceRect;
|
til::inclusive_rect sourceRect;
|
||||||
if (writeRegion.Right > storageSize.X - 1)
|
if (writeRegion.Right > storageSize.X - 1)
|
||||||
{
|
{
|
||||||
writeRegion.Right = storageSize.X - 1;
|
writeRegion.Right = storageSize.X - 1;
|
||||||
@@ -949,15 +948,9 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
|
|||||||
for (; target.Y < writeRectangle.BottomExclusive(); target.Y++)
|
for (; target.Y < writeRectangle.BottomExclusive(); target.Y++)
|
||||||
{
|
{
|
||||||
// We find the offset into the original buffer by the dimensions of the original request rectangle.
|
// We find the offset into the original buffer by the dimensions of the original request rectangle.
|
||||||
ptrdiff_t rowOffset = 0;
|
const auto rowOffset = (target.Y - requestRectangle.Top()) * requestRectangle.Width();
|
||||||
RETURN_IF_FAILED(PtrdiffTSub(target.Y, requestRectangle.Top(), &rowOffset));
|
const auto colOffset = target.X - requestRectangle.Left();
|
||||||
RETURN_IF_FAILED(PtrdiffTMult(rowOffset, requestRectangle.Width(), &rowOffset));
|
const auto totalOffset = rowOffset + colOffset;
|
||||||
|
|
||||||
ptrdiff_t colOffset = 0;
|
|
||||||
RETURN_IF_FAILED(PtrdiffTSub(target.X, requestRectangle.Left(), &colOffset));
|
|
||||||
|
|
||||||
ptrdiff_t totalOffset = 0;
|
|
||||||
RETURN_IF_FAILED(PtrdiffTAdd(rowOffset, colOffset, &totalOffset));
|
|
||||||
|
|
||||||
// Now we make a subspan starting from that offset for as much of the original request as would fit
|
// Now we make a subspan starting from that offset for as much of the original request as would fit
|
||||||
const auto subspan = buffer.subspan(totalOffset, writeRectangle.Width());
|
const auto subspan = buffer.subspan(totalOffset, writeRectangle.Width());
|
||||||
@@ -1027,7 +1020,7 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] HRESULT ApiRoutines::ReadConsoleOutputAttributeImpl(const SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT ApiRoutines::ReadConsoleOutputAttributeImpl(const SCREEN_INFORMATION& context,
|
||||||
const COORD origin,
|
const til::point origin,
|
||||||
gsl::span<WORD> buffer,
|
gsl::span<WORD> buffer,
|
||||||
size_t& written) noexcept
|
size_t& written) noexcept
|
||||||
{
|
{
|
||||||
@@ -1048,7 +1041,7 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] HRESULT ApiRoutines::ReadConsoleOutputCharacterAImpl(const SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT ApiRoutines::ReadConsoleOutputCharacterAImpl(const SCREEN_INFORMATION& context,
|
||||||
const COORD origin,
|
const til::point origin,
|
||||||
gsl::span<char> buffer,
|
gsl::span<char> buffer,
|
||||||
size_t& written) noexcept
|
size_t& written) noexcept
|
||||||
{
|
{
|
||||||
@@ -1077,7 +1070,7 @@ void EventsToUnicode(_Inout_ std::deque<std::unique_ptr<IInputEvent>>& inEvents,
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] HRESULT ApiRoutines::ReadConsoleOutputCharacterWImpl(const SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT ApiRoutines::ReadConsoleOutputCharacterWImpl(const SCREEN_INFORMATION& context,
|
||||||
const COORD origin,
|
const til::point origin,
|
||||||
gsl::span<wchar_t> buffer,
|
gsl::span<wchar_t> buffer,
|
||||||
size_t& written) noexcept
|
size_t& written) noexcept
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -194,6 +194,15 @@ static void _releaseNotifier() noexcept
|
|||||||
_comServerExitEvent.SetEvent();
|
_comServerExitEvent.SetEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This method has the same behavior as gsl::narrow<T>, but instead of throwing an
|
||||||
|
// exception on narrowing failure it'll return false. On success it returns true.
|
||||||
|
template<typename T, typename U>
|
||||||
|
constexpr bool narrow_maybe(U u, T& out) noexcept
|
||||||
|
{
|
||||||
|
out = gsl::narrow_cast<T>(u);
|
||||||
|
return static_cast<U>(out) == u && (std::is_signed_v<T> == std::is_signed_v<U> || (out < T{}) == (u < U{}));
|
||||||
|
}
|
||||||
|
|
||||||
// Routine Description:
|
// Routine Description:
|
||||||
// - Main entry point for EXE version of console launching.
|
// - Main entry point for EXE version of console launching.
|
||||||
// This can be used as a debugging/diagnostics tool as well as a method of testing the console without
|
// This can be used as a debugging/diagnostics tool as well as a method of testing the console without
|
||||||
|
|||||||
@@ -82,8 +82,8 @@ struct NullDeviceComm : public IDeviceComm
|
|||||||
|
|
||||||
CONSOLE_API_CONNECTINFO fakeConnectInfo{};
|
CONSOLE_API_CONNECTINFO fakeConnectInfo{};
|
||||||
fakeConnectInfo.ConsoleInfo.SetShowWindow(SW_NORMAL);
|
fakeConnectInfo.ConsoleInfo.SetShowWindow(SW_NORMAL);
|
||||||
fakeConnectInfo.ConsoleInfo.SetScreenBufferSize(til::size{ 80, 25 }.to_win32_coord());
|
fakeConnectInfo.ConsoleInfo.SetScreenBufferSize({ 80, 25 });
|
||||||
fakeConnectInfo.ConsoleInfo.SetWindowSize(til::size{ 80, 25 }.to_win32_coord());
|
fakeConnectInfo.ConsoleInfo.SetWindowSize({ 80, 25 });
|
||||||
fakeConnectInfo.ConsoleInfo.SetStartupFlags(STARTF_USECOUNTCHARS);
|
fakeConnectInfo.ConsoleInfo.SetStartupFlags(STARTF_USECOUNTCHARS);
|
||||||
wcscpy_s(fakeConnectInfo.Title, fakeTitle.data());
|
wcscpy_s(fakeConnectInfo.Title, fakeTitle.data());
|
||||||
fakeConnectInfo.TitleLength = gsl::narrow_cast<DWORD>(fakeTitle.size() * sizeof(wchar_t)); // bytes, not wchars
|
fakeConnectInfo.TitleLength = gsl::narrow_cast<DWORD>(fakeTitle.size() * sizeof(wchar_t)); // bytes, not wchars
|
||||||
@@ -132,7 +132,7 @@ extern "C" __declspec(dllexport) int LLVMFuzzerTestOneInput(const uint8_t* data,
|
|||||||
auto& gci = Microsoft::Console::Interactivity::ServiceLocator::LocateGlobals().getConsoleInformation();
|
auto& gci = Microsoft::Console::Interactivity::ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||||
|
|
||||||
const auto u16String{ til::u8u16(std::string_view{ reinterpret_cast<const char*>(data), size }) };
|
const auto u16String{ til::u8u16(std::string_view{ reinterpret_cast<const char*>(data), size }) };
|
||||||
SHORT scrollY{};
|
til::CoordType scrollY{};
|
||||||
auto sizeInBytes{ u16String.size() * 2 };
|
auto sizeInBytes{ u16String.size() * 2 };
|
||||||
gci.LockConsole();
|
gci.LockConsole();
|
||||||
auto u = wil::scope_exit([&]() { gci.UnlockConsole(); });
|
auto u = wil::scope_exit([&]() { gci.UnlockConsole(); });
|
||||||
|
|||||||
@@ -769,7 +769,7 @@ void OutputTests::ReadConsoleOutputWWithClipping()
|
|||||||
VERIFY_WIN32_BOOL_SUCCEEDED(ReadConsoleOutputW(consoleOutputHandle, buffer.data(), regionDimensions, regionOrigin, &affected));
|
VERIFY_WIN32_BOOL_SUCCEEDED(ReadConsoleOutputW(consoleOutputHandle, buffer.data(), regionDimensions, regionOrigin, &affected));
|
||||||
VERIFY_ARE_EQUAL(expectedRegion, affected);
|
VERIFY_ARE_EQUAL(expectedRegion, affected);
|
||||||
|
|
||||||
const auto affectedViewport = Viewport::FromInclusive(affected);
|
const auto affectedViewport = Viewport::FromInclusive(til::wrap_small_rect(affected));
|
||||||
const auto filledBuffer = Viewport::FromDimensions({ 0, 0 }, affectedViewport.Dimensions());
|
const auto filledBuffer = Viewport::FromDimensions({ 0, 0 }, affectedViewport.Dimensions());
|
||||||
|
|
||||||
for (SHORT row = 0; row < regionDimensions.Y; row++)
|
for (SHORT row = 0; row < regionDimensions.Y; row++)
|
||||||
@@ -865,7 +865,7 @@ void OutputTests::ReadConsoleOutputWNegativePositions()
|
|||||||
VERIFY_ARE_EQUAL(expectedRegion, affected);
|
VERIFY_ARE_EQUAL(expectedRegion, affected);
|
||||||
|
|
||||||
// Verify the data read affected only the expected area
|
// Verify the data read affected only the expected area
|
||||||
const auto affectedViewport = Viewport::FromInclusive(affected);
|
const auto affectedViewport = Viewport::FromInclusive(til::wrap_small_rect(affected));
|
||||||
|
|
||||||
// Because of the negative origin, the API will report that it filled starting at the 0 coordinate, but it believed
|
// Because of the negative origin, the API will report that it filled starting at the 0 coordinate, but it believed
|
||||||
// the original buffer's origin was at -3, -10. This means we have to read at that offset into the buffer we provided
|
// the original buffer's origin was at -3, -10. This means we have to read at that offset into the buffer we provided
|
||||||
@@ -955,7 +955,7 @@ void OutputTests::ReadConsoleOutputWPartialUserBuffer()
|
|||||||
expected.Top = regionOrigin.Y;
|
expected.Top = regionOrigin.Y;
|
||||||
expected.Bottom = regionDimensions.Y - 1;
|
expected.Bottom = regionDimensions.Y - 1;
|
||||||
|
|
||||||
const auto filledExpected = Viewport::FromInclusive(expected);
|
const auto filledExpected = Viewport::FromInclusive(til::wrap_small_rect(expected));
|
||||||
|
|
||||||
// translate the expected region into the origin at 0,0 because that's what the API will report.
|
// translate the expected region into the origin at 0,0 because that's what the API will report.
|
||||||
expected.Right -= expected.Left;
|
expected.Right -= expected.Left;
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ void IntegrityTest::_TestValidationHelper(const bool fIsBlockExpected,
|
|||||||
wistd::unique_ptr<wchar_t[]> stringData = wil::make_unique_nothrow<wchar_t[]>(cch);
|
wistd::unique_ptr<wchar_t[]> stringData = wil::make_unique_nothrow<wchar_t[]>(cch);
|
||||||
THROW_IF_NULL_ALLOC(stringData);
|
THROW_IF_NULL_ALLOC(stringData);
|
||||||
|
|
||||||
COORD coordRead = { 0 };
|
til::point coordRead;
|
||||||
for (coordRead.Y = 0; coordRead.Y < 8; coordRead.Y++)
|
for (coordRead.Y = 0; coordRead.Y < 8; coordRead.Y++)
|
||||||
{
|
{
|
||||||
ZeroMemory(stringData.get(), sizeof(wchar_t) * cch);
|
ZeroMemory(stringData.get(), sizeof(wchar_t) * cch);
|
||||||
|
|||||||
@@ -120,11 +120,16 @@ void ApiRoutines::GetConsoleScreenBufferInfoExImpl(const SCREEN_INFORMATION& con
|
|||||||
// If they're in the alt buffer, then when they query in that way, the
|
// If they're in the alt buffer, then when they query in that way, the
|
||||||
// value they'll get is the main buffer's size, which isn't updated
|
// value they'll get is the main buffer's size, which isn't updated
|
||||||
// until we switch back to it.
|
// until we switch back to it.
|
||||||
context.GetActiveBuffer().GetScreenBufferInformation(&data.dwSize,
|
til::size dwSize;
|
||||||
&data.dwCursorPosition,
|
til::point dwCursorPosition;
|
||||||
&data.srWindow,
|
til::inclusive_rect srWindow;
|
||||||
|
til::size dwMaximumWindowSize;
|
||||||
|
|
||||||
|
context.GetActiveBuffer().GetScreenBufferInformation(&dwSize,
|
||||||
|
&dwCursorPosition,
|
||||||
|
&srWindow,
|
||||||
&data.wAttributes,
|
&data.wAttributes,
|
||||||
&data.dwMaximumWindowSize,
|
&dwMaximumWindowSize,
|
||||||
&data.wPopupAttributes,
|
&data.wPopupAttributes,
|
||||||
data.ColorTable);
|
data.ColorTable);
|
||||||
|
|
||||||
@@ -134,8 +139,13 @@ void ApiRoutines::GetConsoleScreenBufferInfoExImpl(const SCREEN_INFORMATION& con
|
|||||||
// to return an inclusive rect.
|
// to return an inclusive rect.
|
||||||
// - For GetConsoleScreenBufferInfo, it will leave these values
|
// - For GetConsoleScreenBufferInfo, it will leave these values
|
||||||
// untouched, returning an exclusive rect.
|
// untouched, returning an exclusive rect.
|
||||||
data.srWindow.Right += 1;
|
srWindow.Right += 1;
|
||||||
data.srWindow.Bottom += 1;
|
srWindow.Bottom += 1;
|
||||||
|
|
||||||
|
data.dwSize = til::unwrap_coord_size(dwSize);
|
||||||
|
data.dwCursorPosition = til::unwrap_coord(dwCursorPosition);
|
||||||
|
data.srWindow = til::unwrap_small_rect(srWindow);
|
||||||
|
data.dwMaximumWindowSize = til::unwrap_coord_size(dwMaximumWindowSize);
|
||||||
}
|
}
|
||||||
CATCH_LOG();
|
CATCH_LOG();
|
||||||
}
|
}
|
||||||
@@ -179,8 +189,8 @@ void ApiRoutines::GetConsoleSelectionInfoImpl(CONSOLE_SELECTION_INFO& consoleSel
|
|||||||
|
|
||||||
WI_SetFlag(consoleSelectionInfo.dwFlags, CONSOLE_SELECTION_IN_PROGRESS);
|
WI_SetFlag(consoleSelectionInfo.dwFlags, CONSOLE_SELECTION_IN_PROGRESS);
|
||||||
|
|
||||||
consoleSelectionInfo.dwSelectionAnchor = selection.GetSelectionAnchor();
|
consoleSelectionInfo.dwSelectionAnchor = til::unwrap_coord(selection.GetSelectionAnchor());
|
||||||
consoleSelectionInfo.srSelection = selection.GetSelectionRectangle();
|
consoleSelectionInfo.srSelection = til::unwrap_small_rect(selection.GetSelectionRectangle());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -216,7 +226,7 @@ void ApiRoutines::GetNumberOfConsoleMouseButtonsImpl(ULONG& buttons) noexcept
|
|||||||
// - S_OK, E_INVALIDARG or code from thrown exception
|
// - S_OK, E_INVALIDARG or code from thrown exception
|
||||||
[[nodiscard]] HRESULT ApiRoutines::GetConsoleFontSizeImpl(const SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT ApiRoutines::GetConsoleFontSizeImpl(const SCREEN_INFORMATION& context,
|
||||||
const DWORD index,
|
const DWORD index,
|
||||||
COORD& size) noexcept
|
til::size& size) noexcept
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -232,7 +242,7 @@ void ApiRoutines::GetNumberOfConsoleMouseButtonsImpl(ULONG& buttons) noexcept
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Invalid font is 0,0 with STATUS_INVALID_PARAMETER
|
// Invalid font is 0,0 with STATUS_INVALID_PARAMETER
|
||||||
size = { 0 };
|
size = {};
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -258,7 +268,7 @@ void ApiRoutines::GetNumberOfConsoleMouseButtonsImpl(ULONG& buttons) noexcept
|
|||||||
|
|
||||||
const auto& activeScreenInfo = context.GetActiveBuffer();
|
const auto& activeScreenInfo = context.GetActiveBuffer();
|
||||||
|
|
||||||
COORD WindowSize;
|
til::size WindowSize;
|
||||||
if (isForMaximumWindowSize)
|
if (isForMaximumWindowSize)
|
||||||
{
|
{
|
||||||
WindowSize = activeScreenInfo.GetMaxWindowSizeInCharacters();
|
WindowSize = activeScreenInfo.GetMaxWindowSizeInCharacters();
|
||||||
@@ -267,7 +277,7 @@ void ApiRoutines::GetNumberOfConsoleMouseButtonsImpl(ULONG& buttons) noexcept
|
|||||||
{
|
{
|
||||||
WindowSize = activeScreenInfo.GetCurrentFont().GetUnscaledSize();
|
WindowSize = activeScreenInfo.GetCurrentFont().GetUnscaledSize();
|
||||||
}
|
}
|
||||||
consoleFontInfoEx.dwFontSize = WindowSize;
|
consoleFontInfoEx.dwFontSize = til::unwrap_coord_size(WindowSize);
|
||||||
|
|
||||||
consoleFontInfoEx.nFont = 0;
|
consoleFontInfoEx.nFont = 0;
|
||||||
|
|
||||||
@@ -307,7 +317,7 @@ void ApiRoutines::GetNumberOfConsoleMouseButtonsImpl(ULONG& buttons) noexcept
|
|||||||
FontInfo fi(FaceName,
|
FontInfo fi(FaceName,
|
||||||
gsl::narrow_cast<unsigned char>(consoleFontInfoEx.FontFamily),
|
gsl::narrow_cast<unsigned char>(consoleFontInfoEx.FontFamily),
|
||||||
consoleFontInfoEx.FontWeight,
|
consoleFontInfoEx.FontWeight,
|
||||||
consoleFontInfoEx.dwFontSize,
|
til::wrap_coord_size(consoleFontInfoEx.dwFontSize),
|
||||||
gci.OutputCP);
|
gci.OutputCP);
|
||||||
|
|
||||||
// TODO: MSFT: 9574827 - should this have a failure case?
|
// TODO: MSFT: 9574827 - should this have a failure case?
|
||||||
@@ -486,7 +496,7 @@ void ApiRoutines::FlushConsoleInputBuffer(InputBuffer& context) noexcept
|
|||||||
// - context - The output buffer concerned
|
// - context - The output buffer concerned
|
||||||
// - size - receives the size in character count (rows/columns)
|
// - size - receives the size in character count (rows/columns)
|
||||||
void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& context,
|
void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& context,
|
||||||
COORD& size) noexcept
|
til::size& size) noexcept
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -508,7 +518,7 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
|
|||||||
// Return Value:
|
// Return Value:
|
||||||
// - S_OK, E_INVALIDARG, or failure code from thrown exception
|
// - S_OK, E_INVALIDARG, or failure code from thrown exception
|
||||||
[[nodiscard]] HRESULT ApiRoutines::SetConsoleScreenBufferSizeImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT ApiRoutines::SetConsoleScreenBufferSizeImpl(SCREEN_INFORMATION& context,
|
||||||
const COORD size) noexcept
|
const til::size size) noexcept
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -545,8 +555,8 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
|
|||||||
auto overflow = screenInfo.GetViewport().BottomRightExclusive() - screenInfo.GetBufferSize().Dimensions();
|
auto overflow = screenInfo.GetViewport().BottomRightExclusive() - screenInfo.GetBufferSize().Dimensions();
|
||||||
if (overflow.X > 0 || overflow.Y > 0)
|
if (overflow.X > 0 || overflow.Y > 0)
|
||||||
{
|
{
|
||||||
overflow = { std::max<SHORT>(overflow.X, 0), std::max<SHORT>(overflow.Y, 0) };
|
overflow = { -std::max(overflow.X, 0), -std::max(overflow.Y, 0) };
|
||||||
RETURN_IF_NTSTATUS_FAILED(screenInfo.SetViewportOrigin(false, -overflow, false));
|
RETURN_IF_NTSTATUS_FAILED(screenInfo.SetViewportOrigin(false, overflow, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
// And also that the cursor position is clamped within the buffer boundaries.
|
// And also that the cursor position is clamped within the buffer boundaries.
|
||||||
@@ -597,7 +607,7 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
|
|||||||
|
|
||||||
commandLine.Hide(FALSE);
|
commandLine.Hide(FALSE);
|
||||||
|
|
||||||
LOG_IF_FAILED(context.ResizeScreenBuffer(data.dwSize, TRUE));
|
LOG_IF_FAILED(context.ResizeScreenBuffer(til::wrap_coord_size(data.dwSize), TRUE));
|
||||||
|
|
||||||
commandLine.Show();
|
commandLine.Show();
|
||||||
}
|
}
|
||||||
@@ -631,14 +641,14 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
|
|||||||
|
|
||||||
context.SetDefaultAttributes(TextAttribute{ data.wAttributes }, TextAttribute{ data.wPopupAttributes });
|
context.SetDefaultAttributes(TextAttribute{ data.wAttributes }, TextAttribute{ data.wPopupAttributes });
|
||||||
|
|
||||||
const auto requestedViewport = Viewport::FromExclusive(data.srWindow);
|
const auto requestedViewport = Viewport::FromExclusive(til::wrap_exclusive_small_rect(data.srWindow));
|
||||||
|
|
||||||
auto NewSize = requestedViewport.Dimensions();
|
auto NewSize = requestedViewport.Dimensions();
|
||||||
// If we have a window, clamp the requested viewport to the max window size
|
// If we have a window, clamp the requested viewport to the max window size
|
||||||
if (!ServiceLocator::LocateGlobals().IsHeadless())
|
if (!ServiceLocator::LocateGlobals().IsHeadless())
|
||||||
{
|
{
|
||||||
NewSize.X = std::min(NewSize.X, data.dwMaximumWindowSize.X);
|
NewSize.X = std::min<til::CoordType>(NewSize.X, data.dwMaximumWindowSize.X);
|
||||||
NewSize.Y = std::min(NewSize.Y, data.dwMaximumWindowSize.Y);
|
NewSize.Y = std::min<til::CoordType>(NewSize.Y, data.dwMaximumWindowSize.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If wrap text is on, then the window width must be the same size as the buffer width
|
// If wrap text is on, then the window width must be the same size as the buffer width
|
||||||
@@ -676,8 +686,8 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
|
|||||||
auto overflow = context.GetViewport().BottomRightExclusive() - context.GetBufferSize().Dimensions();
|
auto overflow = context.GetViewport().BottomRightExclusive() - context.GetBufferSize().Dimensions();
|
||||||
if (overflow.X > 0 || overflow.Y > 0)
|
if (overflow.X > 0 || overflow.Y > 0)
|
||||||
{
|
{
|
||||||
overflow = { std::max<SHORT>(overflow.X, 0), std::max<SHORT>(overflow.Y, 0) };
|
overflow = { -std::max(overflow.X, 0), -std::max(overflow.Y, 0) };
|
||||||
RETURN_IF_NTSTATUS_FAILED(context.SetViewportOrigin(false, -overflow, false));
|
RETURN_IF_NTSTATUS_FAILED(context.SetViewportOrigin(false, overflow, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
// And also that the cursor position is clamped within the buffer boundaries.
|
// And also that the cursor position is clamped within the buffer boundaries.
|
||||||
@@ -702,7 +712,7 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
|
|||||||
// Return Value:
|
// Return Value:
|
||||||
// - S_OK, E_INVALIDARG, or failure code from thrown exception
|
// - S_OK, E_INVALIDARG, or failure code from thrown exception
|
||||||
[[nodiscard]] HRESULT ApiRoutines::SetConsoleCursorPositionImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT ApiRoutines::SetConsoleCursorPositionImpl(SCREEN_INFORMATION& context,
|
||||||
const COORD position) noexcept
|
const til::point position) noexcept
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -733,7 +743,7 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
|
|||||||
// GH#1222 and GH#9754 - Use the "virtual" viewport here, so that the
|
// GH#1222 and GH#9754 - Use the "virtual" viewport here, so that the
|
||||||
// viewport snaps back to the virtual viewport's location.
|
// viewport snaps back to the virtual viewport's location.
|
||||||
const auto currentViewport = buffer.GetVirtualViewport().ToInclusive();
|
const auto currentViewport = buffer.GetVirtualViewport().ToInclusive();
|
||||||
COORD delta{ 0 };
|
til::point delta;
|
||||||
{
|
{
|
||||||
// When evaluating the X offset, we must convert the buffer position to
|
// When evaluating the X offset, we must convert the buffer position to
|
||||||
// equivalent screen coordinates, taking line rendition into account.
|
// equivalent screen coordinates, taking line rendition into account.
|
||||||
@@ -759,7 +769,7 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
COORD newWindowOrigin{ 0 };
|
til::point newWindowOrigin;
|
||||||
newWindowOrigin.X = currentViewport.Left + delta.X;
|
newWindowOrigin.X = currentViewport.Left + delta.X;
|
||||||
newWindowOrigin.Y = currentViewport.Top + delta.Y;
|
newWindowOrigin.Y = currentViewport.Top + delta.Y;
|
||||||
// SetViewportOrigin will worry about clamping these values to the
|
// SetViewportOrigin will worry about clamping these values to the
|
||||||
@@ -815,7 +825,7 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
|
|||||||
// - S_OK, E_INVALIDARG, or failure code from thrown exception
|
// - S_OK, E_INVALIDARG, or failure code from thrown exception
|
||||||
[[nodiscard]] HRESULT ApiRoutines::SetConsoleWindowInfoImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT ApiRoutines::SetConsoleWindowInfoImpl(SCREEN_INFORMATION& context,
|
||||||
const bool isAbsolute,
|
const bool isAbsolute,
|
||||||
const SMALL_RECT& windowRect) noexcept
|
const til::inclusive_rect& windowRect) noexcept
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -836,9 +846,9 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
|
|||||||
|
|
||||||
RETURN_HR_IF(E_INVALIDARG, (Window.Right < Window.Left || Window.Bottom < Window.Top));
|
RETURN_HR_IF(E_INVALIDARG, (Window.Right < Window.Left || Window.Bottom < Window.Top));
|
||||||
|
|
||||||
COORD NewWindowSize;
|
til::point NewWindowSize;
|
||||||
NewWindowSize.X = (SHORT)(CalcWindowSizeX(Window));
|
NewWindowSize.X = CalcWindowSizeX(Window);
|
||||||
NewWindowSize.Y = (SHORT)(CalcWindowSizeY(Window));
|
NewWindowSize.Y = CalcWindowSizeY(Window);
|
||||||
|
|
||||||
// see MSFT:17415266
|
// see MSFT:17415266
|
||||||
// If we have a actual head, we care about the maximum size the window can be.
|
// If we have a actual head, we care about the maximum size the window can be.
|
||||||
@@ -889,9 +899,9 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
|
|||||||
// Return Value:
|
// Return Value:
|
||||||
// - S_OK, E_INVALIDARG, or failure code from thrown exception
|
// - S_OK, E_INVALIDARG, or failure code from thrown exception
|
||||||
[[nodiscard]] HRESULT ApiRoutines::ScrollConsoleScreenBufferAImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT ApiRoutines::ScrollConsoleScreenBufferAImpl(SCREEN_INFORMATION& context,
|
||||||
const SMALL_RECT& source,
|
const til::inclusive_rect& source,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
std::optional<SMALL_RECT> clip,
|
std::optional<til::inclusive_rect> clip,
|
||||||
const char fillCharacter,
|
const char fillCharacter,
|
||||||
const WORD fillAttribute) noexcept
|
const WORD fillAttribute) noexcept
|
||||||
{
|
{
|
||||||
@@ -919,9 +929,9 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont
|
|||||||
// Return Value:
|
// Return Value:
|
||||||
// - S_OK, E_INVALIDARG, or failure code from thrown exception
|
// - S_OK, E_INVALIDARG, or failure code from thrown exception
|
||||||
[[nodiscard]] HRESULT ApiRoutines::ScrollConsoleScreenBufferWImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT ApiRoutines::ScrollConsoleScreenBufferWImpl(SCREEN_INFORMATION& context,
|
||||||
const SMALL_RECT& source,
|
const til::inclusive_rect& source,
|
||||||
const COORD target,
|
const til::point target,
|
||||||
std::optional<SMALL_RECT> clip,
|
std::optional<til::inclusive_rect> clip,
|
||||||
const wchar_t fillCharacter,
|
const wchar_t fillCharacter,
|
||||||
const WORD fillAttribute,
|
const WORD fillAttribute,
|
||||||
const bool enableCmdShim) noexcept
|
const bool enableCmdShim) noexcept
|
||||||
@@ -1221,7 +1231,7 @@ void ApiRoutines::GetConsoleDisplayModeImpl(ULONG& flags) noexcept
|
|||||||
// - See: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686028(v=vs.85).aspx
|
// - See: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686028(v=vs.85).aspx
|
||||||
[[nodiscard]] HRESULT ApiRoutines::SetConsoleDisplayModeImpl(SCREEN_INFORMATION& context,
|
[[nodiscard]] HRESULT ApiRoutines::SetConsoleDisplayModeImpl(SCREEN_INFORMATION& context,
|
||||||
const ULONG flags,
|
const ULONG flags,
|
||||||
COORD& newSize) noexcept
|
til::size& newSize) noexcept
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -49,8 +49,8 @@ public:
|
|||||||
|
|
||||||
wil::unique_event_nothrow hInputEvent;
|
wil::unique_event_nothrow hInputEvent;
|
||||||
|
|
||||||
SHORT sVerticalScrollSize;
|
int sVerticalScrollSize;
|
||||||
SHORT sHorizontalScrollSize;
|
int sHorizontalScrollSize;
|
||||||
|
|
||||||
int dpi = USER_DEFAULT_SCREEN_DPI;
|
int dpi = USER_DEFAULT_SCREEN_DPI;
|
||||||
ULONG cursorPixelWidth = 1;
|
ULONG cursorPixelWidth = 1;
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ BOOL CheckBisectProcessW(const SCREEN_INFORMATION& ScreenInfo,
|
|||||||
_In_reads_bytes_(cBytes) const WCHAR* pwchBuffer,
|
_In_reads_bytes_(cBytes) const WCHAR* pwchBuffer,
|
||||||
_In_ size_t cWords,
|
_In_ size_t cWords,
|
||||||
_In_ size_t cBytes,
|
_In_ size_t cBytes,
|
||||||
_In_ SHORT sOriginalXPosition,
|
_In_ til::CoordType sOriginalXPosition,
|
||||||
_In_ BOOL fPrintableControlChars)
|
_In_ BOOL fPrintableControlChars)
|
||||||
{
|
{
|
||||||
if (WI_IsFlagSet(ScreenInfo.OutputMode, ENABLE_PROCESSED_OUTPUT))
|
if (WI_IsFlagSet(ScreenInfo.OutputMode, ENABLE_PROCESSED_OUTPUT))
|
||||||
@@ -151,7 +151,7 @@ BOOL CheckBisectProcessW(const SCREEN_INFORMATION& ScreenInfo,
|
|||||||
case UNICODE_TAB:
|
case UNICODE_TAB:
|
||||||
{
|
{
|
||||||
size_t TabSize = NUMBER_OF_SPACES_IN_TAB(sOriginalXPosition);
|
size_t TabSize = NUMBER_OF_SPACES_IN_TAB(sOriginalXPosition);
|
||||||
sOriginalXPosition = (SHORT)(sOriginalXPosition + TabSize);
|
sOriginalXPosition = (til::CoordType)(sOriginalXPosition + TabSize);
|
||||||
if (cBytes < TabSize)
|
if (cBytes < TabSize)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
cBytes -= TabSize;
|
cBytes -= TabSize;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ BOOL CheckBisectProcessW(const SCREEN_INFORMATION& ScreenInfo,
|
|||||||
_In_reads_bytes_(cBytes) const WCHAR* pwchBuffer,
|
_In_reads_bytes_(cBytes) const WCHAR* pwchBuffer,
|
||||||
_In_ size_t cWords,
|
_In_ size_t cWords,
|
||||||
_In_ size_t cBytes,
|
_In_ size_t cBytes,
|
||||||
_In_ SHORT sOriginalXPosition,
|
_In_ til::CoordType sOriginalXPosition,
|
||||||
_In_ BOOL fPrintableControlChars);
|
_In_ BOOL fPrintableControlChars);
|
||||||
|
|
||||||
int ConvertToOem(const UINT uiCodePage,
|
int ConvertToOem(const UINT uiCodePage,
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ using namespace Microsoft::Console::Interactivity;
|
|||||||
// - targetOrigin - upper left coordinates of new location rectangle
|
// - targetOrigin - upper left coordinates of new location rectangle
|
||||||
static void _CopyRectangle(SCREEN_INFORMATION& screenInfo,
|
static void _CopyRectangle(SCREEN_INFORMATION& screenInfo,
|
||||||
const Viewport& source,
|
const Viewport& source,
|
||||||
const COORD targetOrigin)
|
const til::point targetOrigin)
|
||||||
{
|
{
|
||||||
const auto sourceOrigin = source.Origin();
|
const auto sourceOrigin = source.Origin();
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ static void _CopyRectangle(SCREEN_INFORMATION& screenInfo,
|
|||||||
{
|
{
|
||||||
const auto delta = targetOrigin.Y - source.Top();
|
const auto delta = targetOrigin.Y - source.Top();
|
||||||
|
|
||||||
screenInfo.GetTextBuffer().ScrollRows(source.Top(), source.Height(), gsl::narrow<SHORT>(delta));
|
screenInfo.GetTextBuffer().ScrollRows(source.Top(), source.Height(), delta);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -121,7 +121,7 @@ static void _CopyRectangle(SCREEN_INFORMATION& screenInfo,
|
|||||||
// Return Value:
|
// Return Value:
|
||||||
// - vector of attribute data
|
// - vector of attribute data
|
||||||
std::vector<WORD> ReadOutputAttributes(const SCREEN_INFORMATION& screenInfo,
|
std::vector<WORD> ReadOutputAttributes(const SCREEN_INFORMATION& screenInfo,
|
||||||
const COORD coordRead,
|
const til::point coordRead,
|
||||||
const size_t amountToRead)
|
const size_t amountToRead)
|
||||||
{
|
{
|
||||||
// Short circuit. If nothing to read, leave early.
|
// Short circuit. If nothing to read, leave early.
|
||||||
@@ -178,7 +178,7 @@ std::vector<WORD> ReadOutputAttributes(const SCREEN_INFORMATION& screenInfo,
|
|||||||
// Return Value:
|
// Return Value:
|
||||||
// - wstring
|
// - wstring
|
||||||
std::wstring ReadOutputStringW(const SCREEN_INFORMATION& screenInfo,
|
std::wstring ReadOutputStringW(const SCREEN_INFORMATION& screenInfo,
|
||||||
const COORD coordRead,
|
const til::point coordRead,
|
||||||
const size_t amountToRead)
|
const size_t amountToRead)
|
||||||
{
|
{
|
||||||
// Short circuit. If nothing to read, leave early.
|
// Short circuit. If nothing to read, leave early.
|
||||||
@@ -238,7 +238,7 @@ std::wstring ReadOutputStringW(const SCREEN_INFORMATION& screenInfo,
|
|||||||
// Return Value:
|
// Return Value:
|
||||||
// - string of char data
|
// - string of char data
|
||||||
std::string ReadOutputStringA(const SCREEN_INFORMATION& screenInfo,
|
std::string ReadOutputStringA(const SCREEN_INFORMATION& screenInfo,
|
||||||
const COORD coordRead,
|
const til::point coordRead,
|
||||||
const size_t amountToRead)
|
const size_t amountToRead)
|
||||||
{
|
{
|
||||||
const auto wstr = ReadOutputStringW(screenInfo, coordRead, amountToRead);
|
const auto wstr = ReadOutputStringW(screenInfo, coordRead, amountToRead);
|
||||||
@@ -247,7 +247,7 @@ std::string ReadOutputStringA(const SCREEN_INFORMATION& screenInfo,
|
|||||||
return ConvertToA(gci.OutputCP, wstr);
|
return ConvertToA(gci.OutputCP, wstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenBufferSizeChange(const COORD coordNewSize)
|
void ScreenBufferSizeChange(const til::size coordNewSize)
|
||||||
{
|
{
|
||||||
const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||||
|
|
||||||
@@ -305,7 +305,7 @@ bool StreamScrollRegion(SCREEN_INFORMATION& screenInfo)
|
|||||||
// Trigger a graphical update if we're active.
|
// Trigger a graphical update if we're active.
|
||||||
if (screenInfo.IsActiveScreenBuffer())
|
if (screenInfo.IsActiveScreenBuffer())
|
||||||
{
|
{
|
||||||
COORD coordDelta = { 0 };
|
til::point coordDelta;
|
||||||
coordDelta.Y = -1;
|
coordDelta.Y = -1;
|
||||||
|
|
||||||
auto pNotifier = ServiceLocator::LocateAccessibilityNotifier();
|
auto pNotifier = ServiceLocator::LocateAccessibilityNotifier();
|
||||||
@@ -336,9 +336,9 @@ bool StreamScrollRegion(SCREEN_INFORMATION& screenInfo)
|
|||||||
// - fillAttrsGiven - Attribute to fill source region with.
|
// - fillAttrsGiven - Attribute to fill source region with.
|
||||||
// NOTE: Throws exceptions
|
// NOTE: Throws exceptions
|
||||||
void ScrollRegion(SCREEN_INFORMATION& screenInfo,
|
void ScrollRegion(SCREEN_INFORMATION& screenInfo,
|
||||||
const SMALL_RECT scrollRectGiven,
|
const til::inclusive_rect scrollRectGiven,
|
||||||
const std::optional<SMALL_RECT> clipRectGiven,
|
const std::optional<til::inclusive_rect> clipRectGiven,
|
||||||
const COORD destinationOriginGiven,
|
const til::point destinationOriginGiven,
|
||||||
const wchar_t fillCharGiven,
|
const wchar_t fillCharGiven,
|
||||||
const TextAttribute fillAttrsGiven)
|
const TextAttribute fillAttrsGiven)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,26 +22,26 @@ Revision History:
|
|||||||
#include "../buffer/out/OutputCell.hpp"
|
#include "../buffer/out/OutputCell.hpp"
|
||||||
#include "../buffer/out/OutputCellRect.hpp"
|
#include "../buffer/out/OutputCellRect.hpp"
|
||||||
|
|
||||||
void ScreenBufferSizeChange(const COORD coordNewSize);
|
void ScreenBufferSizeChange(const til::size coordNewSize);
|
||||||
|
|
||||||
[[nodiscard]] NTSTATUS DoCreateScreenBuffer();
|
[[nodiscard]] NTSTATUS DoCreateScreenBuffer();
|
||||||
|
|
||||||
std::vector<WORD> ReadOutputAttributes(const SCREEN_INFORMATION& screenInfo,
|
std::vector<WORD> ReadOutputAttributes(const SCREEN_INFORMATION& screenInfo,
|
||||||
const COORD coordRead,
|
const til::point coordRead,
|
||||||
const size_t amountToRead);
|
const size_t amountToRead);
|
||||||
|
|
||||||
std::wstring ReadOutputStringW(const SCREEN_INFORMATION& screenInfo,
|
std::wstring ReadOutputStringW(const SCREEN_INFORMATION& screenInfo,
|
||||||
const COORD coordRead,
|
const til::point coordRead,
|
||||||
const size_t amountToRead);
|
const size_t amountToRead);
|
||||||
|
|
||||||
std::string ReadOutputStringA(const SCREEN_INFORMATION& screenInfo,
|
std::string ReadOutputStringA(const SCREEN_INFORMATION& screenInfo,
|
||||||
const COORD coordRead,
|
const til::point coordRead,
|
||||||
const size_t amountToRead);
|
const size_t amountToRead);
|
||||||
|
|
||||||
void ScrollRegion(SCREEN_INFORMATION& screenInfo,
|
void ScrollRegion(SCREEN_INFORMATION& screenInfo,
|
||||||
const SMALL_RECT scrollRect,
|
const til::inclusive_rect scrollRect,
|
||||||
const std::optional<SMALL_RECT> clipRect,
|
const std::optional<til::inclusive_rect> clipRect,
|
||||||
const COORD destinationOrigin,
|
const til::point destinationOrigin,
|
||||||
const wchar_t fillCharGiven,
|
const wchar_t fillCharGiven,
|
||||||
const TextAttribute fillAttrsGiven);
|
const TextAttribute fillAttrsGiven);
|
||||||
|
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ TextBuffer& ConhostInternalGetSet::GetTextBuffer()
|
|||||||
// - the exclusive coordinates of the viewport.
|
// - the exclusive coordinates of the viewport.
|
||||||
til::rect ConhostInternalGetSet::GetViewport() const
|
til::rect ConhostInternalGetSet::GetViewport() const
|
||||||
{
|
{
|
||||||
return til::rect{ _io.GetActiveOutputBuffer().GetVirtualViewport().ToInclusive() };
|
return _io.GetActiveOutputBuffer().GetVirtualViewport().ToExclusive();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routine Description:
|
// Routine Description:
|
||||||
@@ -129,8 +129,8 @@ til::rect ConhostInternalGetSet::GetViewport() const
|
|||||||
void ConhostInternalGetSet::SetViewportPosition(const til::point position)
|
void ConhostInternalGetSet::SetViewportPosition(const til::point position)
|
||||||
{
|
{
|
||||||
auto& info = _io.GetActiveOutputBuffer();
|
auto& info = _io.GetActiveOutputBuffer();
|
||||||
const auto dimensions = til::size{ info.GetViewport().Dimensions() };
|
const auto dimensions = info.GetViewport().Dimensions();
|
||||||
const auto windowRect = til::rect{ position, dimensions }.to_small_rect();
|
const auto windowRect = til::rect{ position, dimensions }.to_inclusive_rect();
|
||||||
THROW_IF_FAILED(ServiceLocator::LocateGlobals().api->SetConsoleWindowInfoImpl(info, true, windowRect));
|
THROW_IF_FAILED(ServiceLocator::LocateGlobals().api->SetConsoleWindowInfoImpl(info, true, windowRect));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,8 +174,8 @@ void ConhostInternalGetSet::SetScrollingRegion(const til::inclusive_rect& scroll
|
|||||||
{
|
{
|
||||||
auto& screenInfo = _io.GetActiveOutputBuffer();
|
auto& screenInfo = _io.GetActiveOutputBuffer();
|
||||||
auto srScrollMargins = screenInfo.GetRelativeScrollMargins().ToInclusive();
|
auto srScrollMargins = screenInfo.GetRelativeScrollMargins().ToInclusive();
|
||||||
srScrollMargins.Top = gsl::narrow<short>(scrollMargins.Top);
|
srScrollMargins.Top = scrollMargins.Top;
|
||||||
srScrollMargins.Bottom = gsl::narrow<short>(scrollMargins.Bottom);
|
srScrollMargins.Bottom = scrollMargins.Bottom;
|
||||||
screenInfo.SetScrollMargins(Viewport::FromInclusive(srScrollMargins));
|
screenInfo.SetScrollMargins(Viewport::FromInclusive(srScrollMargins));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,15 +391,13 @@ void ConhostInternalGetSet::PlayMidiNote(const int noteNumber, const int velocit
|
|||||||
// - height: The new height of the window, in rows
|
// - height: The new height of the window, in rows
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - True if handled successfully. False otherwise.
|
// - True if handled successfully. False otherwise.
|
||||||
bool ConhostInternalGetSet::ResizeWindow(const size_t width, const size_t height)
|
bool ConhostInternalGetSet::ResizeWindow(const til::CoordType sColumns, const til::CoordType sRows)
|
||||||
{
|
{
|
||||||
SHORT sColumns = 0;
|
// Ensure we can safely use gsl::narrow_cast<short>(...).
|
||||||
SHORT sRows = 0;
|
if (sColumns <= 0 || sRows <= 0 || sColumns > SHRT_MAX || sRows > SHRT_MAX)
|
||||||
|
{
|
||||||
THROW_IF_FAILED(SizeTToShort(width, &sColumns));
|
return false;
|
||||||
THROW_IF_FAILED(SizeTToShort(height, &sRows));
|
}
|
||||||
// We should do nothing if 0 is passed in for a size.
|
|
||||||
RETURN_BOOL_IF_FALSE(width > 0 && height > 0);
|
|
||||||
|
|
||||||
auto api = ServiceLocator::LocateGlobals().api;
|
auto api = ServiceLocator::LocateGlobals().api;
|
||||||
auto& screenInfo = _io.GetActiveOutputBuffer();
|
auto& screenInfo = _io.GetActiveOutputBuffer();
|
||||||
@@ -411,19 +409,19 @@ bool ConhostInternalGetSet::ResizeWindow(const size_t width, const size_t height
|
|||||||
const auto oldViewport = screenInfo.GetVirtualViewport();
|
const auto oldViewport = screenInfo.GetVirtualViewport();
|
||||||
auto newViewport = Viewport::FromDimensions(oldViewport.Origin(), sColumns, sRows);
|
auto newViewport = Viewport::FromDimensions(oldViewport.Origin(), sColumns, sRows);
|
||||||
// Always resize the width of the console
|
// Always resize the width of the console
|
||||||
csbiex.dwSize.X = sColumns;
|
csbiex.dwSize.X = gsl::narrow_cast<short>(sColumns);
|
||||||
// Only set the screen buffer's height if it's currently less than
|
// Only set the screen buffer's height if it's currently less than
|
||||||
// what we're requesting.
|
// what we're requesting.
|
||||||
if (sRows > csbiex.dwSize.Y)
|
if (sRows > csbiex.dwSize.Y)
|
||||||
{
|
{
|
||||||
csbiex.dwSize.Y = sRows;
|
csbiex.dwSize.Y = gsl::narrow_cast<short>(sRows);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the cursor row is now past the bottom of the viewport, we'll have to
|
// If the cursor row is now past the bottom of the viewport, we'll have to
|
||||||
// move the viewport down to bring it back into view. However, we don't want
|
// move the viewport down to bring it back into view. However, we don't want
|
||||||
// to do this in pty mode, because the conpty resize operation is dependent
|
// to do this in pty mode, because the conpty resize operation is dependent
|
||||||
// on the viewport *not* being adjusted.
|
// on the viewport *not* being adjusted.
|
||||||
const short cursorOverflow = csbiex.dwCursorPosition.Y - newViewport.BottomInclusive();
|
const auto cursorOverflow = csbiex.dwCursorPosition.Y - newViewport.BottomInclusive();
|
||||||
if (cursorOverflow > 0 && !IsConsolePty())
|
if (cursorOverflow > 0 && !IsConsolePty())
|
||||||
{
|
{
|
||||||
newViewport = Viewport::Offset(newViewport, { 0, cursorOverflow });
|
newViewport = Viewport::Offset(newViewport, { 0, cursorOverflow });
|
||||||
@@ -434,7 +432,7 @@ bool ConhostInternalGetSet::ResizeWindow(const size_t width, const size_t height
|
|||||||
|
|
||||||
// SetConsoleScreenBufferInfoEx however expects exclusive rects
|
// SetConsoleScreenBufferInfoEx however expects exclusive rects
|
||||||
const auto sre = newViewport.ToExclusive();
|
const auto sre = newViewport.ToExclusive();
|
||||||
csbiex.srWindow = sre;
|
csbiex.srWindow = til::unwrap_exclusive_small_rect(sre);
|
||||||
|
|
||||||
THROW_IF_FAILED(api->SetConsoleScreenBufferInfoExImpl(screenInfo, csbiex));
|
THROW_IF_FAILED(api->SetConsoleScreenBufferInfoExImpl(screenInfo, csbiex));
|
||||||
THROW_IF_FAILED(api->SetConsoleWindowInfoImpl(screenInfo, true, sri));
|
THROW_IF_FAILED(api->SetConsoleWindowInfoImpl(screenInfo, true, sri));
|
||||||
@@ -477,9 +475,9 @@ void ConhostInternalGetSet::NotifyAccessibilityChange(const til::rect& changedRe
|
|||||||
if (screenInfo.HasAccessibilityEventing())
|
if (screenInfo.HasAccessibilityEventing())
|
||||||
{
|
{
|
||||||
screenInfo.NotifyAccessibilityEventing(
|
screenInfo.NotifyAccessibilityEventing(
|
||||||
gsl::narrow_cast<short>(changedRect.left),
|
changedRect.left,
|
||||||
gsl::narrow_cast<short>(changedRect.top),
|
changedRect.top,
|
||||||
gsl::narrow_cast<short>(changedRect.right - 1),
|
changedRect.right - 1,
|
||||||
gsl::narrow_cast<short>(changedRect.bottom - 1));
|
changedRect.bottom - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public:
|
|||||||
|
|
||||||
void ShowWindow(bool showOrHide) override;
|
void ShowWindow(bool showOrHide) override;
|
||||||
|
|
||||||
bool ResizeWindow(const size_t width, const size_t height) override;
|
bool ResizeWindow(const til::CoordType width, const til::CoordType height) override;
|
||||||
|
|
||||||
void SetConsoleOutputCP(const unsigned int codepage) override;
|
void SetConsoleOutputCP(const unsigned int codepage) override;
|
||||||
unsigned int GetConsoleOutputCP() const override;
|
unsigned int GetConsoleOutputCP() const override;
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ using Microsoft::Console::Interactivity::ServiceLocator;
|
|||||||
// Arguments:
|
// Arguments:
|
||||||
// - screenInfo - Reference to screen on which the popup should be drawn/overlaid.
|
// - screenInfo - Reference to screen on which the popup should be drawn/overlaid.
|
||||||
// - proposedSize - Suggested size of the popup. May be adjusted based on screen size.
|
// - proposedSize - Suggested size of the popup. May be adjusted based on screen size.
|
||||||
Popup::Popup(SCREEN_INFORMATION& screenInfo, const COORD proposedSize) :
|
Popup::Popup(SCREEN_INFORMATION& screenInfo, const til::size proposedSize) :
|
||||||
_screenInfo(screenInfo),
|
_screenInfo(screenInfo),
|
||||||
_userInputFunction(&Popup::_getUserInputInternal)
|
_userInputFunction(&Popup::_getUserInputInternal)
|
||||||
{
|
{
|
||||||
@@ -39,12 +39,12 @@ Popup::Popup(SCREEN_INFORMATION& screenInfo, const COORD proposedSize) :
|
|||||||
|
|
||||||
_region.Left = origin.X;
|
_region.Left = origin.X;
|
||||||
_region.Top = origin.Y;
|
_region.Top = origin.Y;
|
||||||
_region.Right = gsl::narrow<SHORT>(origin.X + size.X - 1i16);
|
_region.Right = origin.X + size.X - 1;
|
||||||
_region.Bottom = gsl::narrow<SHORT>(origin.Y + size.Y - 1i16);
|
_region.Bottom = origin.Y + size.Y - 1;
|
||||||
|
|
||||||
_oldScreenSize = screenInfo.GetBufferSize().Dimensions();
|
_oldScreenSize = screenInfo.GetBufferSize().Dimensions();
|
||||||
|
|
||||||
SMALL_RECT TargetRect;
|
til::inclusive_rect TargetRect;
|
||||||
TargetRect.Left = 0;
|
TargetRect.Left = 0;
|
||||||
TargetRect.Top = _region.Top;
|
TargetRect.Top = _region.Top;
|
||||||
TargetRect.Right = _oldScreenSize.X - 1;
|
TargetRect.Right = _oldScreenSize.X - 1;
|
||||||
@@ -68,7 +68,7 @@ Popup::Popup(SCREEN_INFORMATION& screenInfo, const COORD proposedSize) :
|
|||||||
Popup::~Popup()
|
Popup::~Popup()
|
||||||
{
|
{
|
||||||
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||||
const auto countWas = gci.PopupCount.fetch_sub(1i16);
|
const auto countWas = gci.PopupCount.fetch_sub(1);
|
||||||
if (1 == countWas)
|
if (1 == countWas)
|
||||||
{
|
{
|
||||||
// Notify we're done showing popups.
|
// Notify we're done showing popups.
|
||||||
@@ -87,7 +87,7 @@ void Popup::Draw()
|
|||||||
void Popup::_DrawBorder()
|
void Popup::_DrawBorder()
|
||||||
{
|
{
|
||||||
// fill attributes of top line
|
// fill attributes of top line
|
||||||
COORD WriteCoord;
|
til::point WriteCoord;
|
||||||
WriteCoord.X = _region.Left;
|
WriteCoord.X = _region.Left;
|
||||||
WriteCoord.Y = _region.Top;
|
WriteCoord.Y = _region.Top;
|
||||||
_screenInfo.Write(OutputCellIterator(_attributes, Width() + 2), WriteCoord);
|
_screenInfo.Write(OutputCellIterator(_attributes, Width() + 2), WriteCoord);
|
||||||
@@ -103,7 +103,7 @@ void Popup::_DrawBorder()
|
|||||||
WriteCoord.X = _region.Right;
|
WriteCoord.X = _region.Right;
|
||||||
_screenInfo.Write(OutputCellIterator(UNICODE_BOX_DRAW_LIGHT_DOWN_AND_LEFT, 1), WriteCoord);
|
_screenInfo.Write(OutputCellIterator(UNICODE_BOX_DRAW_LIGHT_DOWN_AND_LEFT, 1), WriteCoord);
|
||||||
|
|
||||||
for (SHORT i = 0; i < Height(); i++)
|
for (til::CoordType i = 0; i < Height(); i++)
|
||||||
{
|
{
|
||||||
WriteCoord.Y += 1;
|
WriteCoord.Y += 1;
|
||||||
WriteCoord.X = _region.Left;
|
WriteCoord.X = _region.Left;
|
||||||
@@ -145,11 +145,11 @@ void Popup::_DrawPrompt(const UINT id)
|
|||||||
auto text = _LoadString(id);
|
auto text = _LoadString(id);
|
||||||
|
|
||||||
// Draw empty popup.
|
// Draw empty popup.
|
||||||
COORD WriteCoord;
|
til::point WriteCoord;
|
||||||
WriteCoord.X = _region.Left + 1i16;
|
WriteCoord.X = _region.Left + 1;
|
||||||
WriteCoord.Y = _region.Top + 1i16;
|
WriteCoord.Y = _region.Top + 1;
|
||||||
size_t lStringLength = Width();
|
auto lStringLength = Width();
|
||||||
for (SHORT i = 0; i < Height(); i++)
|
for (til::CoordType i = 0; i < Height(); i++)
|
||||||
{
|
{
|
||||||
const OutputCellIterator it(UNICODE_SPACE, _attributes, lStringLength);
|
const OutputCellIterator it(UNICODE_SPACE, _attributes, lStringLength);
|
||||||
const auto done = _screenInfo.Write(it, WriteCoord);
|
const auto done = _screenInfo.Write(it, WriteCoord);
|
||||||
@@ -158,12 +158,12 @@ void Popup::_DrawPrompt(const UINT id)
|
|||||||
WriteCoord.Y += 1;
|
WriteCoord.Y += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteCoord.X = _region.Left + 1i16;
|
WriteCoord.X = _region.Left + 1;
|
||||||
WriteCoord.Y = _region.Top + 1i16;
|
WriteCoord.Y = _region.Top + 1;
|
||||||
|
|
||||||
// write prompt to screen
|
// write prompt to screen
|
||||||
lStringLength = text.size();
|
lStringLength = gsl::narrow<til::CoordType>(text.size());
|
||||||
if (lStringLength > (ULONG)Width())
|
if (lStringLength > Width())
|
||||||
{
|
{
|
||||||
text = text.substr(0, Width());
|
text = text.substr(0, Width());
|
||||||
}
|
}
|
||||||
@@ -182,10 +182,10 @@ void Popup::End()
|
|||||||
{
|
{
|
||||||
// restore previous contents to screen
|
// restore previous contents to screen
|
||||||
|
|
||||||
SMALL_RECT SourceRect;
|
til::inclusive_rect SourceRect;
|
||||||
SourceRect.Left = 0i16;
|
SourceRect.Left = 0;
|
||||||
SourceRect.Top = _region.Top;
|
SourceRect.Top = _region.Top;
|
||||||
SourceRect.Right = _oldScreenSize.X - 1i16;
|
SourceRect.Right = _oldScreenSize.X - 1;
|
||||||
SourceRect.Bottom = _region.Bottom;
|
SourceRect.Bottom = _region.Bottom;
|
||||||
|
|
||||||
const auto sourceViewport = Viewport::FromInclusive(SourceRect);
|
const auto sourceViewport = Viewport::FromInclusive(SourceRect);
|
||||||
@@ -200,7 +200,7 @@ void Popup::End()
|
|||||||
// - proposedSize - The suggested size of the popup that may need to be adjusted to fit
|
// - proposedSize - The suggested size of the popup that may need to be adjusted to fit
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - Coordinate size that the popup should consume in the screen buffer
|
// - Coordinate size that the popup should consume in the screen buffer
|
||||||
COORD Popup::_CalculateSize(const SCREEN_INFORMATION& screenInfo, const COORD proposedSize)
|
til::size Popup::_CalculateSize(const SCREEN_INFORMATION& screenInfo, const til::size proposedSize)
|
||||||
{
|
{
|
||||||
// determine popup dimensions
|
// determine popup dimensions
|
||||||
auto size = proposedSize;
|
auto size = proposedSize;
|
||||||
@@ -225,14 +225,14 @@ COORD Popup::_CalculateSize(const SCREEN_INFORMATION& screenInfo, const COORD pr
|
|||||||
// - size - The size that the popup will consume
|
// - size - The size that the popup will consume
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - Coordinate position of the origin point of the popup
|
// - Coordinate position of the origin point of the popup
|
||||||
COORD Popup::_CalculateOrigin(const SCREEN_INFORMATION& screenInfo, const COORD size)
|
til::point Popup::_CalculateOrigin(const SCREEN_INFORMATION& screenInfo, const til::size size)
|
||||||
{
|
{
|
||||||
const auto viewport = screenInfo.GetViewport();
|
const auto viewport = screenInfo.GetViewport();
|
||||||
|
|
||||||
// determine origin. center popup on window
|
// determine origin. center popup on window
|
||||||
COORD origin;
|
til::point origin;
|
||||||
origin.X = gsl::narrow<SHORT>((viewport.Width() - size.X) / 2 + viewport.Left());
|
origin.X = (viewport.Width() - size.X) / 2 + viewport.Left();
|
||||||
origin.Y = gsl::narrow<SHORT>((viewport.Height() - size.Y) / 2 + viewport.Top());
|
origin.Y = (viewport.Height() - size.Y) / 2 + viewport.Top();
|
||||||
return origin;
|
return origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,18 +240,18 @@ COORD Popup::_CalculateOrigin(const SCREEN_INFORMATION& screenInfo, const COORD
|
|||||||
// - Helper to return the width of the popup in columns
|
// - Helper to return the width of the popup in columns
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - Width of popup inside attached screen buffer.
|
// - Width of popup inside attached screen buffer.
|
||||||
SHORT Popup::Width() const noexcept
|
til::CoordType Popup::Width() const noexcept
|
||||||
{
|
{
|
||||||
return _region.Right - _region.Left - 1i16;
|
return _region.Right - _region.Left - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routine Description:
|
// Routine Description:
|
||||||
// - Helper to return the height of the popup in columns
|
// - Helper to return the height of the popup in columns
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - Height of popup inside attached screen buffer.
|
// - Height of popup inside attached screen buffer.
|
||||||
SHORT Popup::Height() const noexcept
|
til::CoordType Popup::Height() const noexcept
|
||||||
{
|
{
|
||||||
return _region.Bottom - _region.Top - 1i16;
|
return _region.Bottom - _region.Top - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routine Description:
|
// Routine Description:
|
||||||
@@ -259,11 +259,11 @@ SHORT Popup::Height() const noexcept
|
|||||||
// we should overlay the cursor for user input.
|
// we should overlay the cursor for user input.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - Coordinate location on the popup where the cursor should be placed.
|
// - Coordinate location on the popup where the cursor should be placed.
|
||||||
COORD Popup::GetCursorPosition() const noexcept
|
til::point Popup::GetCursorPosition() const noexcept
|
||||||
{
|
{
|
||||||
COORD CursorPosition;
|
til::point CursorPosition;
|
||||||
CursorPosition.X = _region.Right - static_cast<SHORT>(MINIMUM_COMMAND_PROMPT_SIZE);
|
CursorPosition.X = _region.Right - MINIMUM_COMMAND_PROMPT_SIZE;
|
||||||
CursorPosition.Y = _region.Top + 1i16;
|
CursorPosition.Y = _region.Top + 1;
|
||||||
return CursorPosition;
|
return CursorPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,11 +29,11 @@ class CommandHistory;
|
|||||||
class Popup
|
class Popup
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static constexpr unsigned int MINIMUM_COMMAND_PROMPT_SIZE = 5;
|
static constexpr til::CoordType MINIMUM_COMMAND_PROMPT_SIZE = 5;
|
||||||
|
|
||||||
using UserInputFunction = std::function<NTSTATUS(COOKED_READ_DATA&, bool&, DWORD&, wchar_t&)>;
|
using UserInputFunction = std::function<NTSTATUS(COOKED_READ_DATA&, bool&, DWORD&, wchar_t&)>;
|
||||||
|
|
||||||
Popup(SCREEN_INFORMATION& screenInfo, const COORD proposedSize);
|
Popup(SCREEN_INFORMATION& screenInfo, const til::size proposedSize);
|
||||||
virtual ~Popup();
|
virtual ~Popup();
|
||||||
[[nodiscard]] virtual NTSTATUS Process(COOKED_READ_DATA& cookedReadData) noexcept = 0;
|
[[nodiscard]] virtual NTSTATUS Process(COOKED_READ_DATA& cookedReadData) noexcept = 0;
|
||||||
|
|
||||||
@@ -41,10 +41,10 @@ public:
|
|||||||
|
|
||||||
void End();
|
void End();
|
||||||
|
|
||||||
SHORT Width() const noexcept;
|
til::CoordType Width() const noexcept;
|
||||||
SHORT Height() const noexcept;
|
til::CoordType Height() const noexcept;
|
||||||
|
|
||||||
COORD GetCursorPosition() const noexcept;
|
til::point GetCursorPosition() const noexcept;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// used in test code to alter how the popup fetches use input
|
// used in test code to alter how the popup fetches use input
|
||||||
@@ -61,13 +61,13 @@ protected:
|
|||||||
void _DrawPrompt(const UINT id);
|
void _DrawPrompt(const UINT id);
|
||||||
virtual void _DrawContent() = 0;
|
virtual void _DrawContent() = 0;
|
||||||
|
|
||||||
SMALL_RECT _region; // region popup occupies
|
til::inclusive_rect _region; // region popup occupies
|
||||||
SCREEN_INFORMATION& _screenInfo;
|
SCREEN_INFORMATION& _screenInfo;
|
||||||
TextAttribute _attributes; // text attributes
|
TextAttribute _attributes; // text attributes
|
||||||
|
|
||||||
private:
|
private:
|
||||||
COORD _CalculateSize(const SCREEN_INFORMATION& screenInfo, const COORD proposedSize);
|
til::size _CalculateSize(const SCREEN_INFORMATION& screenInfo, const til::size proposedSize);
|
||||||
COORD _CalculateOrigin(const SCREEN_INFORMATION& screenInfo, const COORD size);
|
til::point _CalculateOrigin(const SCREEN_INFORMATION& screenInfo, const til::size size);
|
||||||
|
|
||||||
void _DrawBorder();
|
void _DrawBorder();
|
||||||
|
|
||||||
@@ -77,6 +77,6 @@ private:
|
|||||||
wchar_t& wch) noexcept;
|
wchar_t& wch) noexcept;
|
||||||
|
|
||||||
OutputCellRect _oldContents; // contains data under popup
|
OutputCellRect _oldContents; // contains data under popup
|
||||||
COORD _oldScreenSize;
|
til::size _oldScreenSize;
|
||||||
UserInputFunction _userInputFunction;
|
UserInputFunction _userInputFunction;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -85,7 +85,6 @@ TRACELOGGING_DECLARE_PROVIDER(g_hConhostV2EventTraceProvider);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../inc/contsf.h"
|
#include "../inc/contsf.h"
|
||||||
#include "../inc/operators.hpp"
|
|
||||||
#include "../inc/conattrs.hpp"
|
#include "../inc/conattrs.hpp"
|
||||||
|
|
||||||
// TODO: MSFT 9355094 Find a better way of doing this. http://osgvsowi/9355094
|
// TODO: MSFT 9355094 Find a better way of doing this. http://osgvsowi/9355094
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ COOKED_READ_DATA::COOKED_READ_DATA(_In_ InputBuffer* const pInputBuffer,
|
|||||||
_currentPosition = cchInitialData;
|
_currentPosition = cchInitialData;
|
||||||
|
|
||||||
OriginalCursorPosition() = screenInfo.GetTextBuffer().GetCursor().GetPosition();
|
OriginalCursorPosition() = screenInfo.GetTextBuffer().GetCursor().GetPosition();
|
||||||
OriginalCursorPosition().X -= (SHORT)_currentPosition;
|
OriginalCursorPosition().X -= (til::CoordType)_currentPosition;
|
||||||
|
|
||||||
const auto sScreenBufferSizeX = screenInfo.GetBufferSize().Width();
|
const auto sScreenBufferSizeX = screenInfo.GetBufferSize().Width();
|
||||||
while (OriginalCursorPosition().X < 0)
|
while (OriginalCursorPosition().X < 0)
|
||||||
@@ -164,17 +164,17 @@ SCREEN_INFORMATION& COOKED_READ_DATA::ScreenInfo() noexcept
|
|||||||
return _screenInfo;
|
return _screenInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
const COORD& COOKED_READ_DATA::OriginalCursorPosition() const noexcept
|
til::point COOKED_READ_DATA::OriginalCursorPosition() const noexcept
|
||||||
{
|
{
|
||||||
return _originalCursorPosition;
|
return _originalCursorPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
COORD& COOKED_READ_DATA::OriginalCursorPosition() noexcept
|
til::point& COOKED_READ_DATA::OriginalCursorPosition() noexcept
|
||||||
{
|
{
|
||||||
return _originalCursorPosition;
|
return _originalCursorPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
COORD& COOKED_READ_DATA::BeforeDialogCursorPosition() noexcept
|
til::point& COOKED_READ_DATA::BeforeDialogCursorPosition() noexcept
|
||||||
{
|
{
|
||||||
return _beforeDialogCursorPosition;
|
return _beforeDialogCursorPosition;
|
||||||
}
|
}
|
||||||
@@ -482,7 +482,7 @@ bool COOKED_READ_DATA::ProcessInput(const wchar_t wchOrig,
|
|||||||
{
|
{
|
||||||
const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||||
size_t NumSpaces = 0;
|
size_t NumSpaces = 0;
|
||||||
SHORT ScrollY = 0;
|
til::CoordType ScrollY = 0;
|
||||||
size_t NumToWrite;
|
size_t NumToWrite;
|
||||||
auto wch = wchOrig;
|
auto wch = wchOrig;
|
||||||
bool fStartFromDelim;
|
bool fStartFromDelim;
|
||||||
@@ -702,11 +702,11 @@ bool COOKED_READ_DATA::ProcessInput(const wchar_t wchOrig,
|
|||||||
|
|
||||||
if (_echoInput && CallWrite)
|
if (_echoInput && CallWrite)
|
||||||
{
|
{
|
||||||
COORD CursorPosition;
|
til::point CursorPosition;
|
||||||
|
|
||||||
// save cursor position
|
// save cursor position
|
||||||
CursorPosition = _screenInfo.GetTextBuffer().GetCursor().GetPosition();
|
CursorPosition = _screenInfo.GetTextBuffer().GetCursor().GetPosition();
|
||||||
CursorPosition.X = (SHORT)(CursorPosition.X + NumSpaces);
|
CursorPosition.X = (til::CoordType)(CursorPosition.X + NumSpaces);
|
||||||
|
|
||||||
// clear the current command line from the screen
|
// clear the current command line from the screen
|
||||||
// clang-format off
|
// clang-format off
|
||||||
@@ -840,7 +840,7 @@ size_t COOKED_READ_DATA::Write(const std::wstring_view wstr)
|
|||||||
if (IsEchoInput())
|
if (IsEchoInput())
|
||||||
{
|
{
|
||||||
size_t NumSpaces = 0;
|
size_t NumSpaces = 0;
|
||||||
SHORT ScrollY = 0;
|
til::CoordType ScrollY = 0;
|
||||||
|
|
||||||
FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(ScreenInfo(),
|
FAIL_FAST_IF_NTSTATUS_FAILED(WriteCharsLegacy(ScreenInfo(),
|
||||||
_backupLimit,
|
_backupLimit,
|
||||||
|
|||||||
@@ -80,10 +80,10 @@ public:
|
|||||||
|
|
||||||
SCREEN_INFORMATION& ScreenInfo() noexcept;
|
SCREEN_INFORMATION& ScreenInfo() noexcept;
|
||||||
|
|
||||||
const COORD& OriginalCursorPosition() const noexcept;
|
til::point OriginalCursorPosition() const noexcept;
|
||||||
COORD& OriginalCursorPosition() noexcept;
|
til::point& OriginalCursorPosition() noexcept;
|
||||||
|
|
||||||
COORD& BeforeDialogCursorPosition() noexcept;
|
til::point& BeforeDialogCursorPosition() noexcept;
|
||||||
|
|
||||||
bool IsEchoInput() const noexcept;
|
bool IsEchoInput() const noexcept;
|
||||||
bool IsInsertMode() const noexcept;
|
bool IsInsertMode() const noexcept;
|
||||||
@@ -147,8 +147,8 @@ private:
|
|||||||
SCREEN_INFORMATION& _screenInfo;
|
SCREEN_INFORMATION& _screenInfo;
|
||||||
|
|
||||||
// Note that cookedReadData's _originalCursorPosition is the position before ANY text was entered on the edit line.
|
// Note that cookedReadData's _originalCursorPosition is the position before ANY text was entered on the edit line.
|
||||||
COORD _originalCursorPosition;
|
til::point _originalCursorPosition;
|
||||||
COORD _beforeDialogCursorPosition; // Currently only used for F9 (ProcessCommandNumberInput) since it's the only pop-up to move the cursor when it starts.
|
til::point _beforeDialogCursorPosition; // Currently only used for F9 (ProcessCommandNumberInput) since it's the only pop-up to move the cursor when it starts.
|
||||||
|
|
||||||
const bool _echoInput;
|
const bool _echoInput;
|
||||||
const bool _lineInput;
|
const bool _lineInput;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user