mirror of
https://github.com/microsoft/terminal.git
synced 2026-07-08 18:16:28 +00:00
Make DECSTR cursor restore behave like xterm in alt screen buffer (#20032)
There is some disagreement among terminal emulators as to whether DECSTR (and therefore, soft reset) restores the cursor in the active buffer or in all buffers. We had previously chosen to restore the cursor in all buffers. xterm restores the cursor only in the active buffer. Closes #19918
This commit is contained in:
@@ -123,6 +123,7 @@ class ScreenBufferTests
|
|||||||
TEST_METHOD(VtResizePreservingAttributes);
|
TEST_METHOD(VtResizePreservingAttributes);
|
||||||
|
|
||||||
TEST_METHOD(VtSoftResetCursorPosition);
|
TEST_METHOD(VtSoftResetCursorPosition);
|
||||||
|
TEST_METHOD(VtSoftResetAltBufferCursorState);
|
||||||
|
|
||||||
TEST_METHOD(VtScrollMarginsNewlineColor);
|
TEST_METHOD(VtScrollMarginsNewlineColor);
|
||||||
|
|
||||||
@@ -1510,6 +1511,30 @@ void ScreenBufferTests::VtSoftResetCursorPosition()
|
|||||||
VERIFY_ARE_EQUAL(til::point(1, 1), cursor.GetPosition());
|
VERIFY_ARE_EQUAL(til::point(1, 1), cursor.GetPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScreenBufferTests::VtSoftResetAltBufferCursorState()
|
||||||
|
{
|
||||||
|
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||||
|
gci.LockConsole(); // Lock must be taken to manipulate buffer.
|
||||||
|
auto unlock = wil::scope_exit([&] { gci.UnlockConsole(); });
|
||||||
|
|
||||||
|
auto& si = gci.GetActiveOutputBuffer();
|
||||||
|
auto& stateMachine = si.GetStateMachine();
|
||||||
|
|
||||||
|
Log::Comment(L"Move cursor on the main buffer.");
|
||||||
|
stateMachine.ProcessString(L"\x1b[4;7H");
|
||||||
|
VERIFY_ARE_EQUAL(til::point(6, 3), si.GetTextBuffer().GetCursor().GetPosition());
|
||||||
|
|
||||||
|
Log::Comment(L"Enter alt buffer, soft reset, and return to main buffer.");
|
||||||
|
stateMachine.ProcessString(L"\x1b[?1049h");
|
||||||
|
VERIFY_IS_TRUE(gci.GetActiveOutputBuffer()._IsAltBuffer());
|
||||||
|
stateMachine.ProcessString(L"\x1b[!p");
|
||||||
|
stateMachine.ProcessString(L"\x1b[?1049l");
|
||||||
|
VERIFY_IS_FALSE(gci.GetActiveOutputBuffer()._IsAltBuffer());
|
||||||
|
|
||||||
|
Log::Comment(L"Returning from alt buffer should restore the main cursor position.");
|
||||||
|
VERIFY_ARE_EQUAL(til::point(6, 3), gci.GetActiveOutputBuffer().GetTextBuffer().GetCursor().GetPosition());
|
||||||
|
}
|
||||||
|
|
||||||
void ScreenBufferTests::VtScrollMarginsNewlineColor()
|
void ScreenBufferTests::VtScrollMarginsNewlineColor()
|
||||||
{
|
{
|
||||||
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||||
|
|||||||
@@ -3002,17 +3002,15 @@ void AdaptDispatch::SoftReset()
|
|||||||
SetGraphicsRendition({}); // Normal rendition.
|
SetGraphicsRendition({}); // Normal rendition.
|
||||||
SetCharacterProtectionAttribute({}); // Default (unprotected)
|
SetCharacterProtectionAttribute({}); // Default (unprotected)
|
||||||
|
|
||||||
// Reset the saved cursor state.
|
// Reset only the active saved cursor state.
|
||||||
// Note that XTerm only resets the main buffer state, but that
|
// This matches xterm behavior when DECSTR is processed while using
|
||||||
// seems likely to be a bug. Most other terminals reset both.
|
// the alternate screen buffer (GH#19918).
|
||||||
_savedCursorState.at(0) = {}; // Main buffer
|
_savedCursorState.at(_usingAltBuffer ? 1 : 0) = {};
|
||||||
_savedCursorState.at(1) = {}; // Alt buffer
|
|
||||||
|
|
||||||
// The TerminalOutput state in these buffers must be reset to
|
// The TerminalOutput state in this buffer must be reset to
|
||||||
// the same state as the _termOutput instance, which is not
|
// the same state as the _termOutput instance, which is not
|
||||||
// necessarily equivalent to a full reset.
|
// necessarily equivalent to a full reset.
|
||||||
_savedCursorState.at(0).TermOutput = _termOutput;
|
_savedCursorState.at(_usingAltBuffer ? 1 : 0).TermOutput = _termOutput;
|
||||||
_savedCursorState.at(1).TermOutput = _termOutput;
|
|
||||||
|
|
||||||
// Soft reset the Sixel parser if in use.
|
// Soft reset the Sixel parser if in use.
|
||||||
if (_sixelParser)
|
if (_sixelParser)
|
||||||
|
|||||||
Reference in New Issue
Block a user