Skip to content

Commit 4cf71d3

Browse files
Fix DECSTR cursor restore in alt screen buffer (#19918)
1 parent a1a43a4 commit 4cf71d3

2 files changed

Lines changed: 29 additions & 5 deletions

File tree

src/host/ut_host/ScreenBufferTests.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ class ScreenBufferTests
123123
TEST_METHOD(VtResizePreservingAttributes);
124124

125125
TEST_METHOD(VtSoftResetCursorPosition);
126+
TEST_METHOD(VtSoftResetAltBufferCursorState);
126127

127128
TEST_METHOD(VtScrollMarginsNewlineColor);
128129

@@ -1510,6 +1511,30 @@ void ScreenBufferTests::VtSoftResetCursorPosition()
15101511
VERIFY_ARE_EQUAL(til::point(1, 1), cursor.GetPosition());
15111512
}
15121513

1514+
void ScreenBufferTests::VtSoftResetAltBufferCursorState()
1515+
{
1516+
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
1517+
gci.LockConsole(); // Lock must be taken to manipulate buffer.
1518+
auto unlock = wil::scope_exit([&] { gci.UnlockConsole(); });
1519+
1520+
auto& si = gci.GetActiveOutputBuffer();
1521+
auto& stateMachine = si.GetStateMachine();
1522+
1523+
Log::Comment(L"Move cursor on the main buffer.");
1524+
stateMachine.ProcessString(L"\x1b[4;7H");
1525+
VERIFY_ARE_EQUAL(til::point(6, 3), si.GetTextBuffer().GetCursor().GetPosition());
1526+
1527+
Log::Comment(L"Enter alt buffer, soft reset, and return to main buffer.");
1528+
stateMachine.ProcessString(L"\x1b[?1049h");
1529+
VERIFY_IS_TRUE(gci.GetActiveOutputBuffer()._IsAltBuffer());
1530+
stateMachine.ProcessString(L"\x1b[!p");
1531+
stateMachine.ProcessString(L"\x1b[?1049l");
1532+
VERIFY_IS_FALSE(gci.GetActiveOutputBuffer()._IsAltBuffer());
1533+
1534+
Log::Comment(L"Returning from alt buffer should restore the main cursor position.");
1535+
VERIFY_ARE_EQUAL(til::point(6, 3), gci.GetActiveOutputBuffer().GetTextBuffer().GetCursor().GetPosition());
1536+
}
1537+
15131538
void ScreenBufferTests::VtScrollMarginsNewlineColor()
15141539
{
15151540
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();

src/terminal/adapter/adaptDispatch.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2981,11 +2981,10 @@ void AdaptDispatch::SoftReset()
29812981
SetGraphicsRendition({}); // Normal rendition.
29822982
SetCharacterProtectionAttribute({}); // Default (unprotected)
29832983

2984-
// Reset the saved cursor state.
2985-
// Note that XTerm only resets the main buffer state, but that
2986-
// seems likely to be a bug. Most other terminals reset both.
2987-
_savedCursorState.at(0) = {}; // Main buffer
2988-
_savedCursorState.at(1) = {}; // Alt buffer
2984+
// Reset only the active saved cursor state.
2985+
// This matches xterm behavior when DECSTR is processed while using
2986+
// the alternate screen buffer (GH#19918).
2987+
_savedCursorState.at(_usingAltBuffer ? 1 : 0) = {};
29892988

29902989
// The TerminalOutput state in these buffers must be reset to
29912990
// the same state as the _termOutput instance, which is not

0 commit comments

Comments
 (0)