Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions src/buffer/out/textBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2628,11 +2628,8 @@ void TextBuffer::_AppendRTFText(std::string& contentBuilder, const std::wstring_
}
}

void TextBuffer::SerializeToPath(const wchar_t* destination) const
void TextBuffer::SerializeTo(HANDLE handle) const
{
const wil::unique_handle file{ CreateFileW(destination, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr) };
THROW_LAST_ERROR_IF(!file);

static constexpr size_t writeThreshold = 32 * 1024;
std::wstring buffer;
buffer.reserve(writeThreshold + writeThreshold / 2);
Expand Down Expand Up @@ -2661,7 +2658,7 @@ void TextBuffer::SerializeToPath(const wchar_t* destination) const
{
const auto fileSize = gsl::narrow<DWORD>(buffer.size() * sizeof(wchar_t));
DWORD bytesWritten = 0;
THROW_IF_WIN32_BOOL_FALSE(WriteFile(file.get(), buffer.data(), fileSize, &bytesWritten, nullptr));
THROW_IF_WIN32_BOOL_FALSE(WriteFile(handle, buffer.data(), fileSize, &bytesWritten, nullptr));
THROW_WIN32_IF_MSG(ERROR_WRITE_FAULT, bytesWritten != fileSize, "failed to write");
buffer.clear();
}
Expand Down
2 changes: 1 addition & 1 deletion src/buffer/out/textBuffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ class TextBuffer final
const bool isIntenseBold,
std::function<std::tuple<COLORREF, COLORREF, COLORREF>(const TextAttribute&)> GetAttributeColors) const noexcept;

void SerializeToPath(const wchar_t* destination) const;
void SerializeTo(HANDLE handle) const;

struct PositionInformation
{
Expand Down
21 changes: 0 additions & 21 deletions src/cascadia/CascadiaPackage/Package-Dev.appxmanifest
Original file line number Diff line number Diff line change
Expand Up @@ -107,27 +107,6 @@
</uap3:Properties>
</uap3:AppExtension>
</uap3:Extension>
<com:Extension Category="windows.comInterface">
<com:ComInterface>
<com:ProxyStub Id="DEC4804D-56D1-4F73-9FBE-6828E7C85C56" DisplayName="OpenConsoleHandoffProxy" Path="OpenConsoleProxy.dll"/>
<com:Interface Id="E686C757-9A35-4A1C-B3CE-0BCC8B5C69F4" ProxyStubClsid="DEC4804D-56D1-4F73-9FBE-6828E7C85C56"/>
<com:Interface Id="6F23DA90-15C5-4203-9DB0-64E73F1B1B00" ProxyStubClsid="DEC4804D-56D1-4F73-9FBE-6828E7C85C56"/> <!-- ITerminalHandoff3 -->
<com:Interface Id="746E6BC0-AB05-4E38-AB14-71E86763141F" ProxyStubClsid="DEC4804D-56D1-4F73-9FBE-6828E7C85C56"/>
</com:ComInterface>
</com:Extension>
<com:Extension Category="windows.comServer">
<com:ComServer>
<com:ExeServer DisplayName="OpenConsole" Executable="OpenConsole.exe">
<com:Class Id="1F9F2BF5-5BC3-4F17-B0E6-912413F1F451"/>
</com:ExeServer>
<com:ExeServer DisplayName="WindowsTerminal" Executable="WindowsTerminal.exe">
<com:Class Id="051F34EE-C1FD-4B19-AF75-9BA54648434C"/>
</com:ExeServer>
<com:SurrogateServer DisplayName="WindowsTerminalShellExt">
<com:Class Id="52065414-e077-47ec-a3ac-1cc5455e1b54" Path="WindowsTerminalShellExt.dll" ThreadingModel="STA"/>
</com:SurrogateServer>
</com:ComServer>
</com:Extension>
Comment on lines -110 to -130
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Woops. I keep this staged locally, because this makes it build & deploy with VS 2026 for me. I didn't intend to push this.

<desktop4:Extension Category="windows.fileExplorerContextMenus">
<desktop4:FileExplorerContextMenus>
<desktop5:ItemType Type="Directory">
Expand Down
3 changes: 1 addition & 2 deletions src/cascadia/TerminalApp/IPaneContent.idl
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ namespace TerminalApp
None,
Content,
MovePane,
PersistLayout,
PersistAll
Persist,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we want to keep the distinction between PersistLayout and PersistAll? See #19341

};

runtimeclass BellEventArgs
Expand Down
34 changes: 30 additions & 4 deletions src/cascadia/TerminalApp/TerminalPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2218,7 +2218,7 @@ namespace winrt::TerminalApp::implementation
}
}

void TerminalPage::PersistState(bool serializeBuffer)
void TerminalPage::PersistState()
{
// This method may be called for a window even if it hasn't had a tab yet or lost all of them.
// We shouldn't persist such windows.
Expand All @@ -2233,7 +2233,7 @@ namespace winrt::TerminalApp::implementation
for (auto tab : _tabs)
{
auto t = winrt::get_self<implementation::Tab>(tab);
auto tabActions = t->BuildStartupActions(serializeBuffer ? BuildStartupKind::PersistAll : BuildStartupKind::PersistLayout);
auto tabActions = t->BuildStartupActions(BuildStartupKind::Persist);
actions.insert(actions.end(), std::make_move_iterator(tabActions.begin()), std::make_move_iterator(tabActions.end()));
}

Expand Down Expand Up @@ -2319,6 +2319,29 @@ namespace winrt::TerminalApp::implementation
CloseWindowRequested.raise(*this, nullptr);
}

std::vector<IPaneContent> TerminalPage::Panes() const
{
std::vector<IPaneContent> panes;

for (const auto tab : _tabs)
{
const auto impl = _GetTabImpl(tab);
if (!impl)
{
continue;
}

impl->GetRootPane()->WalkTree([&](auto&& pane) {
if (auto content = pane->GetContent())
{
panes.push_back(std::move(content));
}
});
}

return panes;
}

// Method Description:
// - Move the viewport of the terminal of the currently focused tab up or
// down a number of lines.
Expand Down Expand Up @@ -3527,9 +3550,12 @@ namespace winrt::TerminalApp::implementation

if (hasSessionId)
{
using namespace std::string_view_literals;

const auto settingsDir = CascadiaSettings::SettingsDirectory();
const auto idStr = Utils::GuidToPlainString(sessionId);
const auto path = fmt::format(FMT_COMPILE(L"{}\\buffer_{}.txt"), settingsDir, idStr);
const auto admin = IsRunningElevated();
const auto filenamePrefix = admin ? L"elevated_"sv : L"buffer_"sv;
const auto path = fmt::format(FMT_COMPILE(L"{}\\{}{}.txt"), settingsDir, filenamePrefix, sessionId);
control.RestoreFromPath(path);
}

Expand Down
3 changes: 2 additions & 1 deletion src/cascadia/TerminalApp/TerminalPage.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ namespace winrt::TerminalApp::implementation

safe_void_coroutine RequestQuit();
safe_void_coroutine CloseWindow();
void PersistState(bool serializeBuffer);
void PersistState();
std::vector<IPaneContent> Panes() const;

void ToggleFocusMode();
void ToggleFullscreen();
Expand Down
8 changes: 1 addition & 7 deletions src/cascadia/TerminalApp/TerminalPaneContent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,22 +140,16 @@ namespace winrt::TerminalApp::implementation
// "attach existing" rather than a "create"
args.ContentId(_control.ContentId());
break;
case BuildStartupKind::PersistAll:
case BuildStartupKind::Persist:
{
const auto connection = _control.Connection();
const auto id = connection ? connection.SessionId() : winrt::guid{};

if (id != winrt::guid{})
{
const auto settingsDir = CascadiaSettings::SettingsDirectory();
const auto idStr = ::Microsoft::Console::Utils::GuidToPlainString(id);
const auto path = fmt::format(FMT_COMPILE(L"{}\\buffer_{}.txt"), settingsDir, idStr);
_control.PersistToPath(path);
args.SessionId(id);
}
break;
}
case BuildStartupKind::PersistLayout:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like we'd want to keep the branches separate

default:
break;
}
Expand Down
9 changes: 7 additions & 2 deletions src/cascadia/TerminalApp/TerminalWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,11 +253,11 @@ namespace winrt::TerminalApp::implementation
AppLogic::Current()->NotifyRootInitialized();
}

void TerminalWindow::PersistState(bool serializeBuffer)
void TerminalWindow::PersistState()
{
if (_root)
{
_root->PersistState(serializeBuffer);
_root->PersistState();
}
}

Expand Down Expand Up @@ -830,6 +830,11 @@ namespace winrt::TerminalApp::implementation
return _root.as<winrt::Windows::UI::Xaml::Controls::Control>();
}

winrt::Windows::Foundation::Collections::IVector<IPaneContent> TerminalWindow::Panes() const
{
return winrt::single_threaded_vector(_root->Panes());
}

// Method Description:
// - Gets the title of the currently focused terminal control. If there
// isn't a control selected for any reason, returns "Terminal"
Expand Down
3 changes: 2 additions & 1 deletion src/cascadia/TerminalApp/TerminalWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ namespace winrt::TerminalApp::implementation

void Create();

void PersistState(bool serializeBuffer);
void PersistState();

void UpdateSettings(winrt::TerminalApp::SettingsLoadEventArgs args);

Expand Down Expand Up @@ -111,6 +111,7 @@ namespace winrt::TerminalApp::implementation
float CalcSnappedDimension(const bool widthOrHeight, const float dimension) const;

Windows::UI::Xaml::UIElement GetRoot() noexcept;
winrt::Windows::Foundation::Collections::IVector<IPaneContent> Panes() const;

hstring Title();
void TitlebarClicked();
Expand Down
4 changes: 3 additions & 1 deletion src/cascadia/TerminalApp/TerminalWindow.idl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import "IPaneContent.idl";
import "TerminalPage.idl";
import "ShortcutActionDispatch.idl";

Expand Down Expand Up @@ -59,9 +60,10 @@ namespace TerminalApp
Boolean ShouldImmediatelyHandoffToElevated();
void HandoffToElevated();

void PersistState(Boolean serializeBuffer);
void PersistState();

Windows.UI.Xaml.UIElement GetRoot();
IVector<IPaneContent> Panes { get; };

String Title { get; };
Boolean FocusMode { get; };
Expand Down
34 changes: 31 additions & 3 deletions src/cascadia/TerminalControl/ControlCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1806,15 +1806,43 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_closeConnection();
}

void ControlCore::PersistToPath(const wchar_t* path) const
void ControlCore::PersistTo(HANDLE handle) const
{
const auto lock = _terminal->LockForReading();
_terminal->SerializeMainBuffer(path);
_terminal->SerializeMainBuffer(handle);
}

void ControlCore::RestoreFromPath(const wchar_t* path) const
{
const wil::unique_handle file{ CreateFileW(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, nullptr) };
wil::unique_handle file{ CreateFileW(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, nullptr) };

// This block of code exists temporarily to fix buffer dumps that were
// previously persisted as "buffer_" but really should be named "elevated_".
// If loading the properly named file fails, retry with the old name.
if (!file)
{
static constexpr std::wstring_view needle{ L"\\elevated_" };

// Check if the path contains "\elevated_", indicating that we're in an elevated session.
const std::wstring_view pathView{ path };
const auto idx = pathView.find(needle);

if (idx != std::wstring_view::npos)
{
// If so, try to open the file with "\buffer_" instead, which is what we previously used.
std::wstring altPath{ pathView };
altPath.replace(idx, needle.size(), L"\\buffer_");

file.reset(CreateFileW(altPath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, nullptr));

// If the alternate file is found, move it to the correct location.
if (file)
{
LOG_IF_WIN32_BOOL_FALSE(MoveFileW(altPath.c_str(), path));
}
}
}

if (!file)
{
return;
Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalControl/ControlCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void ColorSelection(const Control::SelectionColor& fg, const Control::SelectionColor& bg, Core::MatchMode matchMode);

void Close();
void PersistToPath(const wchar_t* path) const;
void PersistTo(HANDLE handle) const;
void RestoreFromPath(const wchar_t* path) const;

void ClearQuickFix();
Expand Down
4 changes: 2 additions & 2 deletions src/cascadia/TerminalControl/TermControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2681,7 +2681,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_restorePath = std::move(path);
}

void TermControl::PersistToPath(const winrt::hstring& path) const
void TermControl::PersistTo(int64_t handle) const
{
// Don't persist us if we weren't ever initialized. In that case, we
// never got an initial size, never instantiated a buffer, and didn't
Expand All @@ -2693,7 +2693,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// file then.
if (_initializedTerminal)
{
winrt::get_self<ControlCore>(_core)->PersistToPath(path.c_str());
winrt::get_self<ControlCore>(_core)->PersistTo(reinterpret_cast<HANDLE>(handle));
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalControl/TermControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
bool SwitchSelectionEndpoint();
bool ExpandSelectionToWord();
void RestoreFromPath(winrt::hstring path);
void PersistToPath(const winrt::hstring& path) const;
void PersistTo(int64_t handle) const;
void OpenCWD();
void Close();
Windows::Foundation::Size CharacterDimensions() const;
Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalControl/TermControl.idl
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ namespace Microsoft.Terminal.Control
Boolean ExpandSelectionToWord();
void ClearBuffer(ClearBufferType clearType);
void RestoreFromPath(String path);
void PersistToPath(String path);
void PersistTo(Int64 handle);
void OpenCWD();
void Close();
Windows.Foundation.Size CharacterDimensions { get; };
Expand Down
4 changes: 2 additions & 2 deletions src/cascadia/TerminalCore/Terminal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1530,9 +1530,9 @@ std::wstring Terminal::CurrentCommand() const
return _activeBuffer().CurrentCommand();
}

void Terminal::SerializeMainBuffer(const wchar_t* destination) const
void Terminal::SerializeMainBuffer(HANDLE handle) const
{
_mainBuffer->SerializeToPath(destination);
_mainBuffer->SerializeTo(handle);
}

void Terminal::ColorSelection(const TextAttribute& attr, winrt::Microsoft::Terminal::Core::MatchMode matchMode)
Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalCore/Terminal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ class Microsoft::Terminal::Core::Terminal final :

std::wstring CurrentCommand() const;

void SerializeMainBuffer(const wchar_t* destination) const;
void SerializeMainBuffer(HANDLE handle) const;

#pragma region ITerminalApi
// These methods are defined in TerminalApi.cpp
Expand Down
Loading
Loading