Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for querying the character cell size #17504

Merged
merged 2 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/terminal/adapter/DispatchTypes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,8 @@ namespace Microsoft::Console::VirtualTerminal::DispatchTypes
IconifyWindow = 2,
RefreshWindow = 7,
ResizeWindowInCharacters = 8,
ReportTextSizeInPixels = 14,
ReportCharacterCellSize = 16,
ReportTextSizeInCharacters = 18
};

Expand Down
5 changes: 5 additions & 0 deletions src/terminal/adapter/PageManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ void Page::SetAttributes(const TextAttribute& attr, ITerminalApi* api) const
}
}

til::size Page::Size() const noexcept
{
return { Width(), Height() };
}

til::CoordType Page::Top() const noexcept
{
// If we ever support vertical window panning, the page top won't
Expand Down
1 change: 1 addition & 0 deletions src/terminal/adapter/PageManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ namespace Microsoft::Console::VirtualTerminal
Cursor& Cursor() const noexcept;
const TextAttribute& Attributes() const noexcept;
void SetAttributes(const TextAttribute& attr, ITerminalApi* api = nullptr) const;
til::size Size() const noexcept;
til::CoordType Top() const noexcept;
til::CoordType Bottom() const noexcept;
til::CoordType Width() const noexcept;
Expand Down
4 changes: 2 additions & 2 deletions src/terminal/adapter/SixelParser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ namespace Microsoft::Console::VirtualTerminal
public:
static constexpr VTInt DefaultConformance = 9;

static til::size CellSizeForLevel(const VTInt conformanceLevel) noexcept;
static size_t MaxColorsForLevel(const VTInt conformanceLevel) noexcept;
static til::size CellSizeForLevel(const VTInt conformanceLevel = DefaultConformance) noexcept;
static size_t MaxColorsForLevel(const VTInt conformanceLevel = DefaultConformance) noexcept;

SixelParser(AdaptDispatch& dispatcher, const StateMachine& stateMachine, const VTInt conformanceLevel = DefaultConformance) noexcept;
void SoftReset();
Expand Down
22 changes: 18 additions & 4 deletions src/terminal/adapter/adaptDispatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3648,6 +3648,12 @@ bool AdaptDispatch::WindowManipulation(const DispatchTypes::WindowManipulationTy
// Other Window Manipulation functions:
// MSFT:13271098 - QueryViewport
// MSFT:13271146 - QueryScreenSize

const auto reportSize = [&](const auto size) {
const auto reportType = function - 10;
_api.ReturnResponse(fmt::format(FMT_COMPILE(L"\033[{};{};{}t"), reportType, size.height, size.width));
};

switch (function)
{
case DispatchTypes::WindowManipulationType::DeIconifyWindow:
Expand All @@ -3663,11 +3669,19 @@ bool AdaptDispatch::WindowManipulation(const DispatchTypes::WindowManipulationTy
_api.ResizeWindow(parameter2.value_or(0), parameter1.value_or(0));
return true;
case DispatchTypes::WindowManipulationType::ReportTextSizeInCharacters:
{
const auto page = _pages.VisiblePage();
_api.ReturnResponse(fmt::format(FMT_COMPILE(L"\033[8;{};{}t"), page.Height(), page.Width()));
reportSize(_pages.VisiblePage().Size());
return true;
case DispatchTypes::WindowManipulationType::ReportTextSizeInPixels:
// Prior to the existence of the character cell size query, Sixel applications
// that wanted to know the cell size would request the text area in pixels and
// divide that by the text area in characters. But for this to work, we need to
// return the virtual pixel size, as used in the Sixel graphics emulation, and
// not the physical pixel size (which should be of no concern to applications).
reportSize(_pages.VisiblePage().Size() * SixelParser::CellSizeForLevel());
return true;
case DispatchTypes::WindowManipulationType::ReportCharacterCellSize:
reportSize(SixelParser::CellSizeForLevel());
return true;
}
default:
return false;
}
Expand Down
17 changes: 15 additions & 2 deletions src/terminal/adapter/ut_adapter/adapterTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3377,10 +3377,23 @@ class AdapterTest

TEST_METHOD(WindowManipulationTypeTests)
{
// Our pixel size reports are based on a virtual cell size of 10x20 pixels
// for compatibility with the VT240 and VT340 graphic terminals.
const auto cellSize = til::size{ 10, 20 };

_testGetSet->PrepData();
_pDispatch->WindowManipulation(DispatchTypes::WindowManipulationType::ReportTextSizeInCharacters, NULL, NULL);
const auto [textBuffer, viewport, _] = _testGetSet->GetBufferAndViewport();
const std::wstring expectedResponse = fmt::format(L"\033[8;{};{}t", viewport.height(), textBuffer.GetSize().Width());

_pDispatch->WindowManipulation(DispatchTypes::WindowManipulationType::ReportTextSizeInCharacters, NULL, NULL);
std::wstring expectedResponse = fmt::format(L"\033[8;{};{}t", viewport.height(), textBuffer.GetSize().Width());
_testGetSet->ValidateInputEvent(expectedResponse.c_str());

_pDispatch->WindowManipulation(DispatchTypes::WindowManipulationType::ReportTextSizeInPixels, NULL, NULL);
expectedResponse = fmt::format(L"\033[4;{};{}t", viewport.height() * cellSize.height, textBuffer.GetSize().Width() * cellSize.width);
_testGetSet->ValidateInputEvent(expectedResponse.c_str());

_pDispatch->WindowManipulation(DispatchTypes::WindowManipulationType::ReportCharacterCellSize, NULL, NULL);
expectedResponse = fmt::format(L"\033[6;{};{}t", cellSize.height, cellSize.width);
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
}

Expand Down
Loading