Show parts of the scrollback on restore (#17334)

First, this makes use of `PSEUDOCONSOLE_INHERIT_CURSOR` to stop ConPTY
from emitting a CSI 2 J on startup. Then, it uses
`Terminal::SetViewportPosition` to fake-scroll the viewport down so that
only 3 lines of scrollback are visible. It avoids printing actual
newlines because if we later change the text buffer to actually track
the written contents, we don't want those newlines to end up in the next
buffer snapshot.

Closes #17274

## Validation Steps Performed
* Restore cmd multiple times
* There's always exactly 3 lines visible 
This commit is contained in:
Leonard Hecker 2024-05-30 16:25:02 +02:00 committed by GitHub
parent ad362fc866
commit bdc7c4fdbc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 25 additions and 16 deletions

View File

@ -2994,15 +2994,6 @@ namespace winrt::TerminalApp::implementation
const auto content = _manager.CreateCore(settings.DefaultSettings(), settings.UnfocusedSettings(), connection); const auto content = _manager.CreateCore(settings.DefaultSettings(), settings.UnfocusedSettings(), connection);
const TermControl control{ content }; const TermControl control{ content };
if (const auto id = settings.DefaultSettings().SessionId(); id != winrt::guid{})
{
const auto settingsDir = CascadiaSettings::SettingsDirectory();
const auto idStr = Utils::GuidToPlainString(id);
const auto path = fmt::format(FMT_COMPILE(L"{}\\buffer_{}.txt"), settingsDir, idStr);
control.RestoreFromPath(path);
}
return _SetupControl(control); return _SetupControl(control);
} }
@ -3102,7 +3093,10 @@ namespace winrt::TerminalApp::implementation
return nullptr; return nullptr;
} }
auto connection = existingConnection ? existingConnection : _CreateConnectionFromSettings(profile, controlSettings.DefaultSettings(), false); const auto sessionId = controlSettings.DefaultSettings().SessionId();
const auto hasSessionId = sessionId != winrt::guid{};
auto connection = existingConnection ? existingConnection : _CreateConnectionFromSettings(profile, controlSettings.DefaultSettings(), hasSessionId);
if (existingConnection) if (existingConnection)
{ {
connection.Resize(controlSettings.DefaultSettings().InitialRows(), controlSettings.DefaultSettings().InitialCols()); connection.Resize(controlSettings.DefaultSettings().InitialRows(), controlSettings.DefaultSettings().InitialCols());
@ -3124,6 +3118,14 @@ namespace winrt::TerminalApp::implementation
const auto control = _CreateNewControlAndContent(controlSettings, connection); const auto control = _CreateNewControlAndContent(controlSettings, connection);
if (hasSessionId)
{
const auto settingsDir = CascadiaSettings::SettingsDirectory();
const auto idStr = Utils::GuidToPlainString(sessionId);
const auto path = fmt::format(FMT_COMPILE(L"{}\\buffer_{}.txt"), settingsDir, idStr);
control.RestoreFromPath(path);
}
auto paneContent{ winrt::make<TerminalPaneContent>(profile, _terminalSettingsCache, control) }; auto paneContent{ winrt::make<TerminalPaneContent>(profile, _terminalSettingsCache, control) };
auto resultPane = std::make_shared<Pane>(paneContent); auto resultPane = std::make_shared<Pane>(paneContent);

View File

@ -1787,12 +1787,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// * prints " [Restored <date> <time>] <spaces until end of line> " // * prints " [Restored <date> <time>] <spaces until end of line> "
// * resets the color ("\x1b[m") // * resets the color ("\x1b[m")
// * newlines // * newlines
// * clears the screen ("\x1b[2J") message = fmt::format(FMT_COMPILE(L"\x1b[100;37m [{} {} {}]\x1b[K\x1b[m\r\n"), msg, date, time);
// The last step is necessary because we launch ConPTY without PSEUDOCONSOLE_INHERIT_CURSOR by default.
// This will cause ConPTY to emit a \x1b[2J sequence on startup to ensure it and the terminal are in-sync.
// If we didn't do a \x1b[2J ourselves as well, the user would briefly see the last state of the terminal,
// before it's quickly scrolled away once ConPTY has finished starting up, which looks weird.
message = fmt::format(FMT_COMPILE(L"\x1b[100;37m [{} {} {}]\x1b[K\x1b[m\r\n\x1b[2J"), msg, date, time);
} }
wchar_t buffer[32 * 1024]; wchar_t buffer[32 * 1024];
@ -1830,6 +1825,18 @@ namespace winrt::Microsoft::Terminal::Control::implementation
} }
_terminal->Write(message); _terminal->Write(message);
// Show 3 lines of scrollback to the user, so they know it's there. Otherwise, in particular with the well
// hidden touch scrollbars in WinUI 2 and later, there's no indication that there's something to scroll up to.
//
// We only show 3 lines because ConPTY doesn't know about our restored buffer contents initially,
// and so ReadConsole calls will return whitespace.
//
// We also avoid using actual newlines or similar here, because if we ever change our text buffer implementation
// to actually track the written contents, we don't want this to be part of the next buffer snapshot.
const auto cursorPosition = _terminal->GetCursorPosition();
const auto y = std::max(0, cursorPosition.y - 4);
_terminal->SetViewportPosition({ 0, y });
} }
} }