Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
13 changes: 13 additions & 0 deletions src/host/screenInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ SCREEN_INFORMATION::SCREEN_INFORMATION(
LineChar[3] = UNICODE_BOX_DRAW_LIGHT_VERTICAL;
LineChar[4] = UNICODE_BOX_DRAW_LIGHT_UP_AND_RIGHT;
LineChar[5] = UNICODE_BOX_DRAW_LIGHT_UP_AND_LEFT;

// Check if VT mode is enabled. Note that this can be true w/o calling
// SetConsoleMode, if VirtualTerminalLevel is set to !=0 in the registry.
const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
if (gci.GetVirtTermLevel() != 0)
{
Expand Down Expand Up @@ -132,6 +135,16 @@ SCREEN_INFORMATION::~SCREEN_INFORMATION()

const NTSTATUS status = pScreen->_InitializeOutputStateMachine();

if (pScreen->InVTMode())
{
// microsoft/terminal#411: If VT mode is enabled, lets construct the
// VT tab stops. Without this line, if a user has
// VirtualTerminalLevel set, then
// SetConsoleMode(ENABLE_VIRTUAL_TERMINAL_PROCESSING) won't set our
// tab stops, because we're never going from vt off -> on
pScreen->SetDefaultVtTabStops();
}

if (NT_SUCCESS(status))
{
*ppScreen = pScreen;
Expand Down
24 changes: 24 additions & 0 deletions src/host/ut_host/ScreenBufferTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ class ScreenBufferTests
TEST_METHOD(RestoreDownAltBufferWithTerminalScrolling);

TEST_METHOD(ClearAlternateBuffer);

TEST_METHOD(InitializeTabStopsInVTMode);
};

void ScreenBufferTests::SingleAlternateBufferCreationTest()
Expand Down Expand Up @@ -4347,3 +4349,25 @@ void ScreenBufferTests::ClearAlternateBuffer()

VerifyText(siMain.GetTextBuffer());
}

void ScreenBufferTests::InitializeTabStopsInVTMode()
{
// This is a test for microsoft/terminal#411. Refer to that issue for more
// context.

auto& g = ServiceLocator::LocateGlobals();
auto& gci = g.getConsoleInformation();

VERIFY_IS_FALSE(gci.GetActiveOutputBuffer().AreTabsSet());

// Enable VT mode before we construct the buffer. This emulates setting the
// VirtualTerminalLevel reg key before launching the console.
gci.SetVirtTermLevel(1);

// Clean up the old buffer, and re-create it. This new buffer will be
// created as if the VT mode was always on.
m_state->CleanupGlobalScreenBuffer();
m_state->PrepareGlobalScreenBuffer();

VERIFY_IS_TRUE(gci.GetActiveOutputBuffer().AreTabsSet());
}