mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-10 00:48:23 -06:00
Add a system message to session restore (#17113)
This adds a system message which displays the time at which the buffer snapshot was written to disk. Additionally, this PR moves the snapshot loading into a background thread, so that the UI thread is unblocked and that multiple tabs/panes can load simultaneously. Closes #17031 Closes #17074 ## Validation Steps Performed Repeatedly closing and opening WT adds more and more messages. Currently, the messages get somewhat corrupted due to a bug in our line-wrap handling, or some similar part.
This commit is contained in:
parent
19f43f70bd
commit
0c3c7470b0
1
.github/actions/spelling/expect/expect.txt
vendored
1
.github/actions/spelling/expect/expect.txt
vendored
@ -1718,6 +1718,7 @@ sysparams
|
||||
sysparamsext
|
||||
SYSTEMHAND
|
||||
SYSTEMMENU
|
||||
SYSTEMTIME
|
||||
tabview
|
||||
TAdd
|
||||
taef
|
||||
|
||||
@ -1777,6 +1777,38 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return;
|
||||
}
|
||||
|
||||
FILETIME lastWriteTime;
|
||||
SYSTEMTIME lastWriteSystemTime;
|
||||
if (!GetFileTime(file.get(), nullptr, nullptr, &lastWriteTime) ||
|
||||
!FileTimeToSystemTime(&lastWriteTime, &lastWriteSystemTime))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
wchar_t dateBuf[256];
|
||||
const auto dateLen = GetDateFormatEx(nullptr, 0, &lastWriteSystemTime, nullptr, &dateBuf[0], ARRAYSIZE(dateBuf), nullptr);
|
||||
wchar_t timeBuf[256];
|
||||
const auto timeLen = GetTimeFormatEx(nullptr, 0, &lastWriteSystemTime, nullptr, &timeBuf[0], ARRAYSIZE(timeBuf));
|
||||
|
||||
std::wstring message;
|
||||
if (dateLen > 0 && timeLen > 0)
|
||||
{
|
||||
const auto msg = RS_(L"SessionRestoreMessage");
|
||||
const std::wstring_view date{ &dateBuf[0], gsl::narrow_cast<size_t>(dateLen) };
|
||||
const std::wstring_view time{ &timeBuf[0], gsl::narrow_cast<size_t>(timeLen) };
|
||||
// This escape sequence string
|
||||
// * sets the color to white on a bright black background ("\x1b[100;37m")
|
||||
// * prints " [Restored <date> <time>] <spaces until end of line> "
|
||||
// * resets the color ("\x1b[m")
|
||||
// * newlines
|
||||
// * clears the screen ("\x1b[2J")
|
||||
// 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];
|
||||
DWORD read = 0;
|
||||
|
||||
@ -1802,9 +1834,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
}
|
||||
|
||||
// This pushes the restored contents up into the scrollback.
|
||||
const auto lock = _terminal->LockForWriting();
|
||||
_terminal->Write(L"\x1b[2J");
|
||||
{
|
||||
const auto lock = _terminal->LockForWriting();
|
||||
|
||||
// Normally the cursor should already be at the start of the line, but let's be absolutely sure it is.
|
||||
if (_terminal->GetCursorPosition().x != 0)
|
||||
{
|
||||
_terminal->Write(L"\r\n");
|
||||
}
|
||||
|
||||
_terminal->Write(message);
|
||||
}
|
||||
}
|
||||
|
||||
void ControlCore::_rendererWarning(const HRESULT hr, wil::zwstring_view parameter)
|
||||
|
||||
@ -296,4 +296,8 @@ Please either install the missing font or choose another one.</value>
|
||||
<value>Select output</value>
|
||||
<comment>The tooltip for a button for selecting all of a command's output</comment>
|
||||
</data>
|
||||
<data name="SessionRestoreMessage" xml:space="preserve">
|
||||
<value>Restored</value>
|
||||
<comment>"Restored" as in "This content was restored"</comment>
|
||||
</data>
|
||||
</root>
|
||||
@ -1187,11 +1187,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
if (!_restorePath.empty())
|
||||
{
|
||||
winrt::get_self<ControlCore>(_core)->RestoreFromPath(_restorePath.c_str());
|
||||
_restorePath = {};
|
||||
_restoreInBackground();
|
||||
}
|
||||
else
|
||||
{
|
||||
_core.Connection().Start();
|
||||
}
|
||||
|
||||
_core.Connection().Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1278,6 +1279,44 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return true;
|
||||
}
|
||||
|
||||
winrt::fire_and_forget TermControl::_restoreInBackground()
|
||||
{
|
||||
const auto path = std::exchange(_restorePath, {});
|
||||
const auto weakSelf = get_weak();
|
||||
winrt::apartment_context uiThread;
|
||||
|
||||
try
|
||||
{
|
||||
co_await winrt::resume_background();
|
||||
|
||||
const auto self = weakSelf.get();
|
||||
if (!self)
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
winrt::get_self<ControlCore>(_core)->RestoreFromPath(path.c_str());
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
try
|
||||
{
|
||||
co_await uiThread;
|
||||
|
||||
const auto self = weakSelf.get();
|
||||
if (!self)
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
if (const auto connection = _core.Connection())
|
||||
{
|
||||
connection.Start();
|
||||
}
|
||||
}
|
||||
CATCH_LOG();
|
||||
}
|
||||
|
||||
void TermControl::_CharacterHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||
const Input::CharacterReceivedRoutedEventArgs& e)
|
||||
{
|
||||
|
||||
@ -319,6 +319,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
Reattach
|
||||
};
|
||||
bool _InitializeTerminal(const InitializeReason reason);
|
||||
winrt::fire_and_forget _restoreInBackground();
|
||||
void _SetFontSize(int fontSize);
|
||||
void _TappedHandler(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Input::TappedRoutedEventArgs& e);
|
||||
void _KeyDownHandler(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Input::KeyRoutedEventArgs& e);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user