New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a system message to session restore #17113
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1718,6 +1718,7 @@ sysparams | |
sysparamsext | ||
SYSTEMHAND | ||
SYSTEMMENU | ||
SYSTEMTIME | ||
tabview | ||
TAdd | ||
taef | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1796,6 +1796,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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we also start with a
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The serializer will always end the dump in a trailing newline. However, if you look further down below, you'll see that I check that the cursor is at the start of the line/row, just to be sure, and otherwise I'm printing another newline. |
||
} | ||
|
||
wchar_t buffer[32 * 1024]; | ||
DWORD read = 0; | ||
|
||
|
@@ -1821,9 +1853,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) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to put the args in here too? I'm not sure if there's any locales where the translation would require re-ordering those bits |
||
<comment>"Restored" as in "This content was restored"</comment> | ||
</data> | ||
</root> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1181,11 +1181,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 | ||
{ | ||
|
@@ -1272,6 +1273,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(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 1% worried about starting the connection on the BG thread instead of the window thread, but I don't actually see anything in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm also quite worried about this but looking at how it writes |
||
} | ||
} | ||
CATCH_LOG(); | ||
} | ||
|
||
void TermControl::_CharacterHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/, | ||
const Input::CharacterReceivedRoutedEventArgs& e) | ||
{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we explode entirely if this fails? or just skip printing the "[restored ]" message?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think this is fine. If either of these fails, the file is probably not safe to read anyway.