diff --git a/src/host/screenInfo.cpp b/src/host/screenInfo.cpp index 3fabea0ba..dc54614e9 100644 --- a/src/host/screenInfo.cpp +++ b/src/host/screenInfo.cpp @@ -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) { @@ -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; diff --git a/src/host/ut_host/ScreenBufferTests.cpp b/src/host/ut_host/ScreenBufferTests.cpp index 5cb6cd036..9e48965e5 100644 --- a/src/host/ut_host/ScreenBufferTests.cpp +++ b/src/host/ut_host/ScreenBufferTests.cpp @@ -180,6 +180,8 @@ class ScreenBufferTests TEST_METHOD(RestoreDownAltBufferWithTerminalScrolling); TEST_METHOD(ClearAlternateBuffer); + + TEST_METHOD(InitializeTabStopsInVTMode); }; void ScreenBufferTests::SingleAlternateBufferCreationTest() @@ -4347,3 +4349,25 @@ void ScreenBufferTests::ClearAlternateBuffer() VerifyText(siMain.GetTextBuffer()); } + +void ScreenBufferTests::InitializeTabStopsInVTMode() +{ + // This is a test for microsoft/terminal#1189. 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()); +}