mirror of
https://github.com/microsoft/terminal.git
synced 2026-07-08 18:16:28 +00:00
This reverts commit 4b8b6ffc67: Add
support for "workspaces" based on window names (#20162)
@DHowett found the following blocking issues:
-
https://github.com/microsoft/terminal/pull/20162#discussion_r3359134869
- unrelated changes in `tools/runformat.cmd` and `OpenConsole.psm1`
This commit is contained in:
@@ -441,7 +441,6 @@
|
||||
"openTabColorPicker",
|
||||
"openTabRenamer",
|
||||
"openWindowRenamer",
|
||||
"openWorkspace",
|
||||
"paste",
|
||||
"prevTab",
|
||||
"quakeMode",
|
||||
@@ -480,7 +479,6 @@
|
||||
"toggleReadOnlyMode",
|
||||
"toggleShaderEffects",
|
||||
"toggleSplitOrientation",
|
||||
"workspaces",
|
||||
"wt",
|
||||
"unbound"
|
||||
],
|
||||
@@ -1723,28 +1721,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"OpenWorkspaceAction": {
|
||||
"description": "Arguments corresponding to an openWorkspace Action",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/$defs/ShortcutAction"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
"const": "openWorkspace"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"description": "The name of the workspace to open. If omitted, the workspaces UI will be shown so the user can pick one."
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"FocusPaneAction": {
|
||||
"description": "Arguments corresponding to a focusPane Action",
|
||||
"allOf": [
|
||||
@@ -2064,11 +2040,6 @@
|
||||
"unfocusedFrame": {
|
||||
"description": "The color of the window frame when the window is inactive. This only works on Windows 11",
|
||||
"$ref": "#/$defs/ThemeColor"
|
||||
},
|
||||
"showWorkspacesButton": {
|
||||
"description": "When set to true, the workspaces button will be shown in the tab row.",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2237,9 +2208,6 @@
|
||||
{
|
||||
"$ref": "#/$defs/RenameWindowAction"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/OpenWorkspaceAction"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/FocusPaneAction"
|
||||
},
|
||||
|
||||
@@ -938,30 +938,6 @@ namespace winrt::TerminalApp::implementation
|
||||
co_return;
|
||||
}
|
||||
|
||||
// Launch `wt -w <name>` so the monarch can either summon an existing
|
||||
// window with that name or restore a persisted workspace.
|
||||
safe_void_coroutine TerminalPage::_OpenWorkspaceWindow(const winrt::hstring name)
|
||||
{
|
||||
co_await winrt::resume_background();
|
||||
|
||||
const auto exePath{ GetWtExePath() };
|
||||
// Quote/escape the window name so that ShellExecute -> CommandLineToArgvW
|
||||
// round-trips it as a single argument even when it contains spaces or
|
||||
// other characters that need escaping.
|
||||
const auto cmdline = fmt::format(FMT_COMPILE(L"-w {}"), QuoteAndEscapeCommandlineArg(std::wstring_view{ name }));
|
||||
|
||||
SHELLEXECUTEINFOW seInfo{ 0 };
|
||||
seInfo.cbSize = sizeof(seInfo);
|
||||
seInfo.fMask = SEE_MASK_NOASYNC;
|
||||
seInfo.lpVerb = L"open";
|
||||
seInfo.lpFile = exePath.c_str();
|
||||
seInfo.lpParameters = cmdline.c_str();
|
||||
seInfo.nShow = SW_SHOWNORMAL;
|
||||
LOG_IF_WIN32_BOOL_FALSE(ShellExecuteExW(&seInfo));
|
||||
|
||||
co_return;
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleNewWindow(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& actionArgs)
|
||||
{
|
||||
@@ -1082,7 +1058,6 @@ namespace winrt::TerminalApp::implementation
|
||||
// Fun!
|
||||
// WindowRenamerTextBox().Focus(FocusState::Programmatic);
|
||||
_renamerLayoutUpdatedRevoker.revoke();
|
||||
_renamerLayoutCount = 0;
|
||||
_renamerLayoutUpdatedRevoker = WindowRenamerTextBox().LayoutUpdated(winrt::auto_revoke, [weakThis = get_weak()](auto&&, auto&&) {
|
||||
if (auto self{ weakThis.get() })
|
||||
{
|
||||
@@ -1658,35 +1633,4 @@ namespace winrt::TerminalApp::implementation
|
||||
args.Handled(handled);
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleOpenWorkspace(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
// Open (or summon) a named window. We launch a new `wt -w <name>`
|
||||
// process which the monarch will route to the correct live window or
|
||||
// restore from a persisted workspace.
|
||||
if (args)
|
||||
{
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<OpenWorkspaceArgs>())
|
||||
{
|
||||
const auto name = realArgs.Name();
|
||||
if (!name.empty())
|
||||
{
|
||||
_OpenWorkspaceWindow(name);
|
||||
}
|
||||
args.Handled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleWorkspaces(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
if (_workspaceFlyout && _workspaceDropdown)
|
||||
{
|
||||
_workspaceFlyout.ShowAt(_workspaceDropdown);
|
||||
}
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -92,10 +92,6 @@ INewContentArgs Pane::GetTerminalArgsForPane(BuildStartupKind kind) const
|
||||
{
|
||||
// Leaves are the only things that have controls
|
||||
assert(_IsLeaf());
|
||||
if (!_content)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return _content.GetNewTerminalArgs(kind);
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +85,6 @@ namespace winrt::TerminalApp::implementation
|
||||
WINRT_PROPERTY(TerminalApp::CommandlineArgs, Command, nullptr);
|
||||
WINRT_PROPERTY(winrt::hstring, Content);
|
||||
WINRT_PROPERTY(Windows::Foundation::IReference<Windows::Foundation::Rect>, InitialBounds);
|
||||
WINRT_PROPERTY(winrt::Microsoft::Terminal::Settings::Model::WindowLayout, PersistedLayout, nullptr);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,5 @@ namespace TerminalApp
|
||||
CommandlineArgs Command { get; };
|
||||
String Content { get; };
|
||||
Windows.Foundation.IReference<Windows.Foundation.Rect> InitialBounds { get; };
|
||||
Microsoft.Terminal.Settings.Model.WindowLayout PersistedLayout;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -743,42 +743,6 @@
|
||||
<value>unnamed window</value>
|
||||
<comment>text used to identify when a window hasn't been assigned a name by the user</comment>
|
||||
</data>
|
||||
<data name="NameThisWindowMenuItem" xml:space="preserve">
|
||||
<value>Name this window...</value>
|
||||
<comment>Menu item text shown when the current window has no name assigned</comment>
|
||||
</data>
|
||||
<data name="RenameThisWindowMenuItem" xml:space="preserve">
|
||||
<value>Rename this window...</value>
|
||||
<comment>Menu item text shown when the current window already has a name</comment>
|
||||
</data>
|
||||
<data name="WindowListUnnamedEntry" xml:space="preserve">
|
||||
<value>#{0} (unnamed)</value>
|
||||
<comment>{locked="{0}"}{0} is the window ID number. Shown in the workspace flyout for windows that have no name assigned.</comment>
|
||||
</data>
|
||||
<data name="DeleteWorkspaceMenuItem" xml:space="preserve">
|
||||
<value>Delete workspace?</value>
|
||||
<comment>Menu item text shown in the right-click context menu on a saved workspace</comment>
|
||||
</data>
|
||||
<data name="OpenWorkspaceMenuItem" xml:space="preserve">
|
||||
<value>Open workspace</value>
|
||||
<comment>Menu item text for opening a saved workspace</comment>
|
||||
</data>
|
||||
<data name="ConfirmDeleteWorkspaceTitle" xml:space="preserve">
|
||||
<value>Delete "{0}"?</value>
|
||||
<comment>{locked="{0}"}{0} is the workspace name. Shown as the title of a confirmation dialog when the user tries to delete a saved workspace.</comment>
|
||||
</data>
|
||||
<data name="ConfirmDeleteWorkspaceBody" xml:space="preserve">
|
||||
<value>Are you sure you want to delete "{0}"? Sessions associated with this workspace will also be deleted.</value>
|
||||
<comment>{locked="{0}"}{0} is the workspace name. Body text of the confirmation dialog shown when the user tries to delete a saved workspace.</comment>
|
||||
</data>
|
||||
<data name="ConfirmDeleteWorkspaceDelete" xml:space="preserve">
|
||||
<value>Delete</value>
|
||||
<comment>Primary button text on the delete workspace confirmation dialog</comment>
|
||||
</data>
|
||||
<data name="ConfirmDeleteWorkspaceCancel" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
<comment>Cancel button text on the delete workspace confirmation dialog</comment>
|
||||
</data>
|
||||
<data name="WindowRenamer.Subtitle" xml:space="preserve">
|
||||
<value>Enter a new name:</value>
|
||||
</data>
|
||||
@@ -837,9 +801,6 @@
|
||||
<data name="ElevationShield.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>This Terminal window is running as administrator</value>
|
||||
</data>
|
||||
<data name="WorkspaceDropdown.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Workspaces</value>
|
||||
</data>
|
||||
<data name="CommandPalette_MatchesAvailable" xml:space="preserve">
|
||||
<value>Suggestions found: {0}</value>
|
||||
<comment>{0} will be replaced with a number.</comment>
|
||||
|
||||
@@ -403,22 +403,6 @@ namespace winrt::TerminalApp::implementation
|
||||
_previouslyClosedPanesAndTabs.emplace_back(args);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - If this window has a name, persist its current workspace layout to
|
||||
// ApplicationState. Intended to be called from the close-pane / close-tab
|
||||
// paths while tab/pane content is still alive (before it gets torn down).
|
||||
void TerminalPage::_SaveWorkspaceIfNeeded()
|
||||
{
|
||||
const auto& windowName = _WindowProperties.WindowName();
|
||||
if (!windowName.empty())
|
||||
{
|
||||
if (const auto layout = GetWindowLayout())
|
||||
{
|
||||
ApplicationState::SharedInstance().SaveWorkspace(windowName, layout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Removes the tab (both TerminalControl and XAML) after prompting for approval
|
||||
// Arguments:
|
||||
@@ -466,14 +450,6 @@ namespace winrt::TerminalApp::implementation
|
||||
auto actions = t->BuildStartupActions(BuildStartupKind::None);
|
||||
_AddPreviouslyClosedPaneOrTab(std::move(actions));
|
||||
|
||||
// If this is the last tab in a named window, persist the workspace
|
||||
// layout now while tab content is still alive. After tab.Close()
|
||||
// the pane content will be torn down by the time _RemoveTab runs.
|
||||
if (_tabs.Size() == 1)
|
||||
{
|
||||
_SaveWorkspaceIfNeeded();
|
||||
}
|
||||
|
||||
tab.Close();
|
||||
}
|
||||
|
||||
@@ -495,13 +471,6 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
const auto focusedTabIndex{ _GetFocusedTabIndex() };
|
||||
|
||||
// NOTE: Workspace persistence for named windows used to live here,
|
||||
// but by the time _RemoveTab runs the pane content may already be
|
||||
// torn down (e.g. from the close-pane path). Instead, workspace
|
||||
// saves are handled earlier:
|
||||
// - Close-pane (last pane): in _HandleClosePaneRequested
|
||||
// - Close-tab: in _HandleCloseTabRequested
|
||||
|
||||
// Removing the tab from the collection should destroy its control and disconnect its connection,
|
||||
// but it doesn't always do so. The UI tree may still be holding the control and preventing its destruction.
|
||||
tab.Shutdown();
|
||||
@@ -829,21 +798,6 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
_AddPreviouslyClosedPaneOrTab(std::move(state.args));
|
||||
|
||||
// If this is the last pane on the last tab of a named window, persist
|
||||
// the workspace layout now while the pane content is still alive.
|
||||
// We can't wait until _RemoveTab, because pane->Close() below will
|
||||
// destroy the content before _RemoveTab is reached.
|
||||
if (_tabs.Size() == 1)
|
||||
{
|
||||
if (const auto activeTab{ _GetFocusedTabImpl() })
|
||||
{
|
||||
if (activeTab->GetLeafPaneCount() == 1)
|
||||
{
|
||||
_SaveWorkspaceIfNeeded();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If specified, detach before closing to directly update the pane structure
|
||||
pane->Close();
|
||||
}
|
||||
|
||||
@@ -19,8 +19,6 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
til::property_changed_event PropertyChanged;
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, ShowElevationShield, PropertyChanged.raise, false);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, ShowWorkspacesButton, PropertyChanged.raise, true);
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, WorkspaceName, PropertyChanged.raise, L"");
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,5 @@ namespace TerminalApp
|
||||
TabRowControl();
|
||||
Microsoft.UI.Xaml.Controls.TabView TabView { get; };
|
||||
Boolean ShowElevationShield;
|
||||
Boolean ShowWorkspacesButton;
|
||||
String WorkspaceName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:mtu="using:Microsoft.Terminal.UI"
|
||||
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
|
||||
Background="{ThemeResource TabViewBackground}"
|
||||
mc:Ignorable="d">
|
||||
@@ -36,45 +35,14 @@
|
||||
TabWidthMode="Equal">
|
||||
|
||||
<mux:TabView.TabStripHeader>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<!-- EA18 is the "Shield" glyph -->
|
||||
<FontIcon x:Uid="ElevationShield"
|
||||
Margin="9,4,0,4"
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
FontSize="16"
|
||||
Foreground="{ThemeResource SystemControlForegroundBaseMediumBrush}"
|
||||
Glyph=""
|
||||
Visibility="{x:Bind ShowElevationShield, Mode=OneWay}" />
|
||||
|
||||
<!-- Workspace/windows button -->
|
||||
<Button x:Name="WorkspaceDropdown"
|
||||
x:Uid="WorkspaceDropdown"
|
||||
Margin="4,0,0,4"
|
||||
Padding="8,0,0,0"
|
||||
VerticalAlignment="Stretch"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
Visibility="{x:Bind ShowWorkspacesButton, Mode=OneWay}">
|
||||
<Button.Content>
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="8">
|
||||
<!-- EE40 is the "TaskViewSettings" glyph -->
|
||||
<FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
FontSize="12"
|
||||
Glyph="" />
|
||||
<TextBlock x:Name="WorkspaceNameText"
|
||||
Padding="0,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="12"
|
||||
Text="{x:Bind WorkspaceName, Mode=OneWay}"
|
||||
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(WorkspaceName), Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
</Button.Content>
|
||||
<Button.Flyout>
|
||||
<MenuFlyout x:Name="WorkspaceFlyout" />
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<!-- EA18 is the "Shield" glyph -->
|
||||
<FontIcon x:Uid="ElevationShield"
|
||||
Margin="9,4,0,4"
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
FontSize="16"
|
||||
Foreground="{ThemeResource SystemControlForegroundBaseMediumBrush}"
|
||||
Glyph=""
|
||||
Visibility="{x:Bind ShowElevationShield, Mode=OneWay}" />
|
||||
</mux:TabView.TabStripHeader>
|
||||
|
||||
<mux:TabView.TabStripFooter>
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
#include "TerminalSettingsCache.h"
|
||||
|
||||
#include "LaunchPositionRequest.g.cpp"
|
||||
#include "WindowListEntry.g.cpp"
|
||||
#include "WindowListRequest.g.cpp"
|
||||
#include "RenameWindowRequestedArgs.g.cpp"
|
||||
#include "RequestMoveContentArgs.g.cpp"
|
||||
#include "TerminalPage.g.cpp"
|
||||
@@ -336,21 +334,6 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
auto tabRowImpl = winrt::get_self<implementation::TabRowControl>(_tabRow);
|
||||
_newTabButton = tabRowImpl->NewTabButton();
|
||||
_workspaceFlyout = tabRowImpl->WorkspaceFlyout();
|
||||
_workspaceDropdown = tabRowImpl->WorkspaceDropdown();
|
||||
|
||||
// Set the initial workspace name from the window name.
|
||||
// Use raw WindowName() so unnamed windows show no text.
|
||||
_tabRow.WorkspaceName(_WindowProperties.WindowName());
|
||||
|
||||
// Rebuild the workspace flyout each time it opens so it always
|
||||
// reflects the latest set of persisted workspaces.
|
||||
_workspaceFlyout.Opening([weakThis{ get_weak() }](auto&&, auto&&) {
|
||||
if (auto page{ weakThis.get() })
|
||||
{
|
||||
page->_PopulateWorkspaceFlyout();
|
||||
}
|
||||
});
|
||||
|
||||
if (_settings.GlobalSettings().ShowTabsInTitlebar())
|
||||
{
|
||||
@@ -460,12 +443,6 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
_tabRow.ShowElevationShield(IsRunningElevated() && _settings.GlobalSettings().ShowAdminShield());
|
||||
|
||||
// Apply the ShowWorkspacesButton theme setting.
|
||||
if (const auto theme = _settings.GlobalSettings().CurrentTheme())
|
||||
{
|
||||
_tabRow.ShowWorkspacesButton(theme.Window() ? theme.Window().ShowWorkspacesButton() : true);
|
||||
}
|
||||
|
||||
_adjustProcessPriorityThrottled = std::make_shared<ThrottledFunc<>>(
|
||||
DispatcherQueue::GetForCurrentThread(),
|
||||
til::throttled_func_options{
|
||||
@@ -2308,14 +2285,14 @@ namespace winrt::TerminalApp::implementation
|
||||
QuitRequested.raise(nullptr, nullptr);
|
||||
}
|
||||
|
||||
WindowLayout TerminalPage::GetWindowLayout()
|
||||
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.
|
||||
const auto tabCount = _tabs.Size();
|
||||
if (_startupState != StartupState::Initialized || tabCount == 0)
|
||||
{
|
||||
return nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<ActionAndArgs> actions;
|
||||
@@ -2330,7 +2307,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// Avoid persisting a window with zero tabs, because `BuildStartupActions` happened to return an empty vector.
|
||||
if (actions.empty())
|
||||
{
|
||||
return nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
// if the focused tab was not the last tab, restore that
|
||||
@@ -2379,49 +2356,7 @@ namespace winrt::TerminalApp::implementation
|
||||
RequestLaunchPosition.raise(*this, launchPosRequest);
|
||||
layout.InitialPosition(launchPosRequest.Position());
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
void TerminalPage::PersistState()
|
||||
{
|
||||
// There are two persistence mechanisms in play here:
|
||||
// * PersistedWindowLayouts (vector) — consumed on next startup to
|
||||
// re-open a matching set of windows. Cleared after restore.
|
||||
// * PersistedWorkspaces (name-keyed map) — the full tab/buffer
|
||||
// state of a named window, claimed by name on demand via
|
||||
// ApplicationState::TakeWorkspace.
|
||||
//
|
||||
// For named windows we save the full layout into the workspace map
|
||||
// and drop a lightweight `openWorkspace` stub into the generic vector,
|
||||
// so the generic restore path re-opens the named window which in
|
||||
// turn claims its own workspace. Unnamed windows don't have a stable
|
||||
// key, so their full layout is stored directly in the vector.
|
||||
if (const auto layout = GetWindowLayout())
|
||||
{
|
||||
const auto& windowName = _WindowProperties.WindowName();
|
||||
if (!windowName.empty())
|
||||
{
|
||||
// Persist the full layout into the workspace collection.
|
||||
ApplicationState::SharedInstance().SaveWorkspace(windowName, layout);
|
||||
|
||||
// Build a minimal layout with just an openWorkspace action
|
||||
// so the generic restore path re-opens this workspace by name.
|
||||
std::vector<ActionAndArgs> actions;
|
||||
ActionAndArgs action;
|
||||
action.Action(ShortcutAction::OpenWorkspace);
|
||||
OpenWorkspaceArgs args{ windowName };
|
||||
action.Args(args);
|
||||
actions.emplace_back(std::move(action));
|
||||
|
||||
WindowLayout stub;
|
||||
stub.TabLayout(winrt::single_threaded_vector<ActionAndArgs>(std::move(actions)));
|
||||
ApplicationState::SharedInstance().AppendPersistedWindowLayout(stub);
|
||||
}
|
||||
else
|
||||
{
|
||||
ApplicationState::SharedInstance().AppendPersistedWindowLayout(layout);
|
||||
}
|
||||
}
|
||||
ApplicationState::SharedInstance().AppendPersistedWindowLayout(layout);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -4122,12 +4057,6 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
_tabRow.ShowElevationShield(IsRunningElevated() && _settings.GlobalSettings().ShowAdminShield());
|
||||
|
||||
// Apply the ShowWorkspacesButton theme setting.
|
||||
if (const auto theme = _settings.GlobalSettings().CurrentTheme())
|
||||
{
|
||||
_tabRow.ShowWorkspacesButton(theme.Window() ? theme.Window().ShowWorkspacesButton() : true);
|
||||
}
|
||||
|
||||
Media::SolidColorBrush transparent{ Windows::UI::Colors::Transparent() };
|
||||
_tabView.Background(transparent);
|
||||
|
||||
@@ -5768,196 +5697,6 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
// Rebuild the workspace flyout contents. Called every time the flyout opens
|
||||
// so it reflects the current set of persisted workspaces.
|
||||
void TerminalPage::_PopulateWorkspaceFlyout()
|
||||
{
|
||||
if (!_workspaceFlyout)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_workspaceFlyout.Items().Clear();
|
||||
|
||||
// --- "Name / Rename this window" ---
|
||||
{
|
||||
MenuFlyoutItem item{};
|
||||
item.Text(_WindowProperties.WindowName().empty() ? RS_(L"NameThisWindowMenuItem") : RS_(L"RenameThisWindowMenuItem"));
|
||||
|
||||
auto iconElement = UI::IconPathConverter::IconWUX(L"\uE8AC"); // Rename glyph
|
||||
Automation::AutomationProperties::SetAccessibilityView(iconElement, Automation::Peers::AccessibilityView::Raw);
|
||||
item.Icon(iconElement);
|
||||
|
||||
item.Click([weakThis{ get_weak() }](auto&&, auto&&) {
|
||||
if (auto page{ weakThis.get() })
|
||||
{
|
||||
page->_actionDispatch->DoAction(ActionAndArgs{ ShortcutAction::OpenWindowRenamer, nullptr });
|
||||
}
|
||||
});
|
||||
_workspaceFlyout.Items().Append(item);
|
||||
}
|
||||
|
||||
// --- Gather open window info first so we can filter workspaces ---
|
||||
const auto windowListReq{ winrt::make<WindowListRequest>() };
|
||||
RequestWindowList.raise(*this, windowListReq);
|
||||
const auto windowEntries = windowListReq.Entries();
|
||||
|
||||
std::set<winrt::hstring> openWindowNames;
|
||||
if (windowEntries)
|
||||
{
|
||||
for (const auto& entry : windowEntries)
|
||||
{
|
||||
const auto& name = entry.Name();
|
||||
if (!name.empty())
|
||||
{
|
||||
openWindowNames.emplace(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- Saved workspaces section (only those not currently open) ---
|
||||
// Collect workspace names that aren't currently open so we can show
|
||||
// them both as top-level "open" items and inside the delete sub-menu.
|
||||
const auto workspaces = ApplicationState::SharedInstance().AllPersistedWorkspaces();
|
||||
if (workspaces && workspaces.Size() > 0)
|
||||
{
|
||||
bool addedSeparator = false;
|
||||
|
||||
for (const auto& pair : workspaces)
|
||||
{
|
||||
const auto name = pair.Key();
|
||||
|
||||
// Skip workspaces that correspond to a currently-open window.
|
||||
if (openWindowNames.contains(name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!addedSeparator)
|
||||
{
|
||||
_workspaceFlyout.Items().Append(MenuFlyoutSeparator{});
|
||||
addedSeparator = true;
|
||||
}
|
||||
|
||||
MenuFlyoutItem item{};
|
||||
item.Text(name);
|
||||
|
||||
auto iconElement = UI::IconPathConverter::IconWUX(L"\uE8F1"); // SwitchApps glyph
|
||||
Automation::AutomationProperties::SetAccessibilityView(iconElement, Automation::Peers::AccessibilityView::Raw);
|
||||
item.Icon(iconElement);
|
||||
|
||||
item.Click([weakThis{ get_weak() }, name](auto&&, auto&&) {
|
||||
if (auto page{ weakThis.get() })
|
||||
{
|
||||
page->_OpenWorkspaceWindow(name);
|
||||
}
|
||||
});
|
||||
|
||||
// Right-click to delete: attach a context flyout with a
|
||||
// "Delete workspace?" item that opens a confirmation dialog.
|
||||
{
|
||||
WUX::Controls::MenuFlyout deleteFlyout{};
|
||||
deleteFlyout.Placement(WUX::Controls::Primitives::FlyoutPlacementMode::BottomEdgeAlignedRight);
|
||||
|
||||
WUX::Controls::MenuFlyoutItem deleteItem{};
|
||||
deleteItem.Text(RS_(L"DeleteWorkspaceMenuItem"));
|
||||
|
||||
auto trashIcon = UI::IconPathConverter::IconWUX(L"\xE74D"); // Delete glyph
|
||||
|
||||
deleteItem.Click([weakThis{ get_weak() }, name](auto&&, auto&&) -> safe_void_coroutine {
|
||||
auto page{ weakThis.get() };
|
||||
if (!page)
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
// Build and show a confirmation ContentDialog.
|
||||
ContentDialog dialog{};
|
||||
dialog.Title(winrt::box_value(winrt::hstring{ RS_fmt(L"ConfirmDeleteWorkspaceTitle", name) }));
|
||||
dialog.Content(winrt::box_value(winrt::hstring{ RS_fmt(L"ConfirmDeleteWorkspaceBody", name) }));
|
||||
dialog.PrimaryButtonText(RS_(L"ConfirmDeleteWorkspaceDelete"));
|
||||
dialog.CloseButtonText(RS_(L"ConfirmDeleteWorkspaceCancel"));
|
||||
dialog.DefaultButton(ContentDialogButton::Close);
|
||||
|
||||
if (auto presenter{ page->_dialogPresenter.get() })
|
||||
{
|
||||
const auto result = co_await presenter.ShowDialog(dialog);
|
||||
// Re-check after co_await
|
||||
page = weakThis.get();
|
||||
if (!page)
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
if (result == ContentDialogResult::Primary)
|
||||
{
|
||||
ApplicationState::SharedInstance().RemoveWorkspace(name);
|
||||
page->_PopulateWorkspaceFlyout();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
deleteFlyout.Items().Append(deleteItem);
|
||||
WUX::Controls::Primitives::FlyoutBase::SetAttachedFlyout(item, deleteFlyout);
|
||||
item.ContextRequested([item](auto&&, auto&&) {
|
||||
WUX::Controls::Primitives::FlyoutBase::ShowAttachedFlyout(item);
|
||||
});
|
||||
}
|
||||
|
||||
_workspaceFlyout.Items().Append(item);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Open windows section ---
|
||||
if (windowEntries && windowEntries.Size() > 0)
|
||||
{
|
||||
_workspaceFlyout.Items().Append(MenuFlyoutSeparator{});
|
||||
|
||||
const auto thisWindowId = _WindowProperties.WindowId();
|
||||
|
||||
for (const auto& entry : windowEntries)
|
||||
{
|
||||
const auto id = entry.Id();
|
||||
const auto& name = entry.Name();
|
||||
|
||||
winrt::hstring displayText;
|
||||
if (name.empty())
|
||||
{
|
||||
displayText = winrt::hstring{ RS_fmt(L"WindowListUnnamedEntry", id) };
|
||||
}
|
||||
else
|
||||
{
|
||||
displayText = winrt::hstring{ fmt::format(FMT_COMPILE(L"#{}: {}"), id, name) };
|
||||
}
|
||||
|
||||
MenuFlyoutItem item{};
|
||||
item.Text(displayText);
|
||||
|
||||
if (id == thisWindowId)
|
||||
{
|
||||
auto iconElement = UI::IconPathConverter::IconWUX(L"\uE73E"); // CheckMark glyph
|
||||
Automation::AutomationProperties::SetAccessibilityView(iconElement, Automation::Peers::AccessibilityView::Raw);
|
||||
item.Icon(iconElement);
|
||||
item.IsEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto iconElement = UI::IconPathConverter::IconWUX(L"\uE737"); // ChromeRestore glyph
|
||||
Automation::AutomationProperties::SetAccessibilityView(iconElement, Automation::Peers::AccessibilityView::Raw);
|
||||
item.Icon(iconElement);
|
||||
|
||||
item.Click([weakThis{ get_weak() }, id](auto&&, auto&&) {
|
||||
if (auto page{ weakThis.get() })
|
||||
{
|
||||
page->SummonWindowByIdRequested.raise(*page, winrt::make<SummonWindowByIdRequestedArgs>(id));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_workspaceFlyout.Items().Append(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handler for our WindowProperties's PropertyChanged event. We'll use this
|
||||
// to pop the "Identify Window" toast when the user renames our window.
|
||||
void TerminalPage::_windowPropertyChanged(const IInspectable& /*sender*/, const WUX::Data::PropertyChangedEventArgs& args)
|
||||
@@ -5967,10 +5706,6 @@ namespace winrt::TerminalApp::implementation
|
||||
return;
|
||||
}
|
||||
|
||||
// Keep the workspace dropdown label in sync with the window name.
|
||||
// Use raw WindowName() so clearing the name hides the text.
|
||||
_tabRow.WorkspaceName(_WindowProperties.WindowName());
|
||||
|
||||
// DON'T display the confirmation if this is the name we were
|
||||
// given on startup!
|
||||
if (_startupState == StartupState::Initialized)
|
||||
|
||||
@@ -10,11 +10,8 @@
|
||||
#include "AppKeyBindings.h"
|
||||
#include "AppCommandlineArgs.h"
|
||||
#include "RenameWindowRequestedArgs.g.h"
|
||||
#include "SummonWindowByIdRequestedArgs.g.h"
|
||||
#include "RequestMoveContentArgs.g.h"
|
||||
#include "LaunchPositionRequest.g.h"
|
||||
#include "WindowListEntry.g.h"
|
||||
#include "WindowListRequest.g.h"
|
||||
#include "Toast.h"
|
||||
|
||||
#include "WindowsPackageManagerFactory.h"
|
||||
@@ -76,15 +73,6 @@ namespace winrt::TerminalApp::implementation
|
||||
_ProposedName{ name } {};
|
||||
};
|
||||
|
||||
struct SummonWindowByIdRequestedArgs : SummonWindowByIdRequestedArgsT<SummonWindowByIdRequestedArgs>
|
||||
{
|
||||
WINRT_PROPERTY(uint64_t, WindowId);
|
||||
|
||||
public:
|
||||
SummonWindowByIdRequestedArgs(uint64_t id) :
|
||||
_WindowId{ id } {};
|
||||
};
|
||||
|
||||
struct RequestMoveContentArgs : RequestMoveContentArgsT<RequestMoveContentArgs>
|
||||
{
|
||||
WINRT_PROPERTY(winrt::hstring, Window);
|
||||
@@ -106,25 +94,6 @@ namespace winrt::TerminalApp::implementation
|
||||
til::property<winrt::Microsoft::Terminal::Settings::Model::LaunchPosition> Position;
|
||||
};
|
||||
|
||||
struct WindowListEntry : WindowListEntryT<WindowListEntry>
|
||||
{
|
||||
WindowListEntry() = default;
|
||||
|
||||
til::property<uint64_t> Id;
|
||||
til::property<winrt::hstring> Name;
|
||||
};
|
||||
|
||||
struct WindowListRequest : WindowListRequestT<WindowListRequest>
|
||||
{
|
||||
WindowListRequest() :
|
||||
_Entries{ winrt::single_threaded_vector<winrt::TerminalApp::WindowListEntry>() } {}
|
||||
|
||||
winrt::Windows::Foundation::Collections::IVector<winrt::TerminalApp::WindowListEntry> Entries() const { return _Entries; }
|
||||
|
||||
private:
|
||||
winrt::Windows::Foundation::Collections::IVector<winrt::TerminalApp::WindowListEntry> _Entries;
|
||||
};
|
||||
|
||||
struct WinGetSearchParams
|
||||
{
|
||||
winrt::Microsoft::Management::Deployment::PackageMatchField Field;
|
||||
@@ -163,7 +132,6 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
safe_void_coroutine RequestQuit();
|
||||
safe_void_coroutine CloseWindow();
|
||||
winrt::Microsoft::Terminal::Settings::Model::WindowLayout GetWindowLayout();
|
||||
void PersistState();
|
||||
std::vector<IPaneContent> Panes() const;
|
||||
|
||||
@@ -235,7 +203,6 @@ namespace winrt::TerminalApp::implementation
|
||||
til::typed_event<IInspectable, IInspectable> IdentifyWindowsRequested;
|
||||
til::typed_event<IInspectable, winrt::TerminalApp::RenameWindowRequestedArgs> RenameWindowRequested;
|
||||
til::typed_event<IInspectable, IInspectable> SummonWindowRequested;
|
||||
til::typed_event<IInspectable, winrt::TerminalApp::SummonWindowByIdRequestedArgs> SummonWindowByIdRequested;
|
||||
til::typed_event<IInspectable, winrt::TerminalApp::Tab> FocusTabRequested;
|
||||
til::typed_event<IInspectable, winrt::Microsoft::Terminal::Control::WindowSizeChangedEventArgs> WindowSizeChanged;
|
||||
|
||||
@@ -248,7 +215,6 @@ namespace winrt::TerminalApp::implementation
|
||||
til::typed_event<Windows::Foundation::IInspectable, winrt::TerminalApp::RequestReceiveContentArgs> RequestReceiveContent;
|
||||
|
||||
til::typed_event<IInspectable, winrt::TerminalApp::LaunchPositionRequest> RequestLaunchPosition;
|
||||
til::typed_event<IInspectable, winrt::TerminalApp::WindowListRequest> RequestWindowList;
|
||||
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::Windows::UI::Xaml::Media::Brush, TitlebarBrush, PropertyChanged.raise, nullptr);
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::Windows::UI::Xaml::Media::Brush, FrameBrush, PropertyChanged.raise, nullptr);
|
||||
@@ -271,8 +237,6 @@ namespace winrt::TerminalApp::implementation
|
||||
TerminalApp::TabRowControl _tabRow{ nullptr };
|
||||
Windows::UI::Xaml::Controls::Grid _tabContent{ nullptr };
|
||||
Microsoft::UI::Xaml::Controls::SplitButton _newTabButton{ nullptr };
|
||||
Windows::UI::Xaml::Controls::MenuFlyout _workspaceFlyout{ nullptr };
|
||||
Windows::UI::Xaml::Controls::Button _workspaceDropdown{ nullptr };
|
||||
winrt::TerminalApp::ColorPickupFlyout _tabColorPicker{ nullptr };
|
||||
|
||||
Microsoft::Terminal::Settings::Model::CascadiaSettings _settings{ nullptr };
|
||||
@@ -371,7 +335,6 @@ namespace winrt::TerminalApp::implementation
|
||||
void _restartPaneConnection(const TerminalApp::TerminalPaneContent&, const winrt::Windows::Foundation::IInspectable&);
|
||||
|
||||
safe_void_coroutine _OpenNewWindow(const Microsoft::Terminal::Settings::Model::INewContentArgs newContentArgs);
|
||||
safe_void_coroutine _OpenWorkspaceWindow(const winrt::hstring name);
|
||||
|
||||
void _OpenNewTerminalViaDropdown(const Microsoft::Terminal::Settings::Model::NewTerminalArgs newTerminalArgs);
|
||||
|
||||
@@ -401,7 +364,6 @@ namespace winrt::TerminalApp::implementation
|
||||
void _CloseTabAtIndex(uint32_t index);
|
||||
void _RemoveTab(const winrt::TerminalApp::Tab& tab);
|
||||
safe_void_coroutine _RemoveTabs(const std::vector<winrt::TerminalApp::Tab> tabs);
|
||||
void _SaveWorkspaceIfNeeded();
|
||||
|
||||
void _InitializeTab(winrt::com_ptr<Tab> newTabImpl, uint32_t insertPosition = -1);
|
||||
void _RegisterTerminalEvents(Microsoft::Terminal::Control::TermControl term);
|
||||
@@ -615,7 +577,6 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void _PopulateContextMenu(const Microsoft::Terminal::Control::TermControl& control, const Microsoft::UI::Xaml::Controls::CommandBarFlyout& sender, const bool withSelection);
|
||||
void _PopulateQuickFixMenu(const Microsoft::Terminal::Control::TermControl& control, const Windows::UI::Xaml::Controls::MenuFlyout& sender);
|
||||
void _PopulateWorkspaceFlyout();
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyout _CreateRunAsAdminFlyout(int profileIndex);
|
||||
|
||||
winrt::Microsoft::Terminal::Control::TermControl _senderOrActiveControl(const winrt::Windows::Foundation::IInspectable& sender);
|
||||
@@ -642,5 +603,4 @@ namespace winrt::TerminalApp::implementation
|
||||
namespace winrt::TerminalApp::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(TerminalPage);
|
||||
BASIC_FACTORY(WindowListEntry);
|
||||
}
|
||||
|
||||
@@ -19,10 +19,6 @@ namespace TerminalApp
|
||||
{
|
||||
String ProposedName { get; };
|
||||
};
|
||||
[default_interface] runtimeclass SummonWindowByIdRequestedArgs
|
||||
{
|
||||
UInt64 WindowId { get; };
|
||||
};
|
||||
[default_interface] runtimeclass RequestMoveContentArgs
|
||||
{
|
||||
String Window { get; };
|
||||
@@ -54,20 +50,6 @@ namespace TerminalApp
|
||||
Microsoft.Terminal.Settings.Model.LaunchPosition Position;
|
||||
}
|
||||
|
||||
[default_interface] runtimeclass WindowListEntry
|
||||
{
|
||||
WindowListEntry();
|
||||
UInt64 Id;
|
||||
String Name;
|
||||
}
|
||||
|
||||
// Raised by TerminalPage when it needs the list of open windows.
|
||||
// The handler (AppHost) fills Entries synchronously.
|
||||
[default_interface] runtimeclass WindowListRequest
|
||||
{
|
||||
Windows.Foundation.Collections.IVector<WindowListEntry> Entries { get; };
|
||||
}
|
||||
|
||||
[default_interface] runtimeclass TerminalPage : Windows.UI.Xaml.Controls.Page, Windows.UI.Xaml.Data.INotifyPropertyChanged, Microsoft.Terminal.UI.IDirectKeyListener
|
||||
{
|
||||
TerminalPage(WindowProperties properties, ContentManager manager);
|
||||
@@ -111,7 +93,6 @@ namespace TerminalApp
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> IdentifyWindowsRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, RenameWindowRequestedArgs> RenameWindowRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> SummonWindowRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, SummonWindowByIdRequestedArgs> SummonWindowByIdRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Microsoft.Terminal.Control.WindowSizeChangedEventArgs> WindowSizeChanged;
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> OpenSystemMenu;
|
||||
@@ -122,6 +103,5 @@ namespace TerminalApp
|
||||
event Windows.Foundation.TypedEventHandler<Object, RequestReceiveContentArgs> RequestReceiveContent;
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, LaunchPositionRequest> RequestLaunchPosition;
|
||||
event Windows.Foundation.TypedEventHandler<Object, WindowListRequest> RequestWindowList;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,15 +258,6 @@ namespace winrt::TerminalApp::implementation
|
||||
AppLogic::Current()->NotifyRootInitialized();
|
||||
}
|
||||
|
||||
WindowLayout TerminalWindow::GetWindowLayout() const
|
||||
{
|
||||
if (_root)
|
||||
{
|
||||
return _root->GetWindowLayout();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void TerminalWindow::PersistState()
|
||||
{
|
||||
if (_root)
|
||||
@@ -1112,11 +1103,6 @@ namespace winrt::TerminalApp::implementation
|
||||
_initialContentArgs = wil::to_vector(args);
|
||||
}
|
||||
|
||||
void TerminalWindow::SetPersistedLayout(const winrt::Microsoft::Terminal::Settings::Model::WindowLayout& layout)
|
||||
{
|
||||
_cachedLayout = layout;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Parse the provided commandline arguments into actions, and try to
|
||||
// perform them immediately.
|
||||
@@ -1237,14 +1223,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void TerminalWindow::WindowName(const winrt::hstring& name)
|
||||
{
|
||||
const auto oldIsQuakeMode = _WindowProperties->IsQuakeWindow();
|
||||
const auto oldName = _WindowProperties->WindowName();
|
||||
_WindowProperties->WindowName(name);
|
||||
// If this window had a persisted workspace under the old name, rename
|
||||
// that entry too so we don't leave a stale copy behind.
|
||||
if (!oldName.empty() && !name.empty() && oldName != name)
|
||||
{
|
||||
ApplicationState::SharedInstance().RenameWorkspace(oldName, name);
|
||||
}
|
||||
if (!_root)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -71,7 +71,6 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void Create();
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::WindowLayout GetWindowLayout() const;
|
||||
void PersistState();
|
||||
|
||||
void UpdateSettings(winrt::TerminalApp::SettingsLoadEventArgs args);
|
||||
@@ -80,7 +79,6 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
int32_t SetStartupCommandline(TerminalApp::CommandlineArgs args);
|
||||
void SetStartupContent(const winrt::hstring& content, const Windows::Foundation::IReference<Windows::Foundation::Rect>& contentBounds);
|
||||
void SetPersistedLayout(const winrt::Microsoft::Terminal::Settings::Model::WindowLayout& layout);
|
||||
int32_t ExecuteCommandline(TerminalApp::CommandlineArgs args);
|
||||
void SetSettingsStartupArgs(const std::vector<winrt::Microsoft::Terminal::Settings::Model::ActionAndArgs>& actions);
|
||||
|
||||
@@ -224,7 +222,6 @@ namespace winrt::TerminalApp::implementation
|
||||
FORWARDED_TYPED_EVENT(SetTaskbarProgress, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable, _root, SetTaskbarProgress);
|
||||
FORWARDED_TYPED_EVENT(IdentifyWindowsRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, IdentifyWindowsRequested);
|
||||
FORWARDED_TYPED_EVENT(SummonWindowRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, SummonWindowRequested);
|
||||
FORWARDED_TYPED_EVENT(SummonWindowByIdRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::SummonWindowByIdRequestedArgs, _root, SummonWindowByIdRequested);
|
||||
FORWARDED_TYPED_EVENT(FocusTabRequested, Windows::Foundation::IInspectable, winrt::TerminalApp::Tab, _root, FocusTabRequested);
|
||||
FORWARDED_TYPED_EVENT(OpenSystemMenu, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, OpenSystemMenu);
|
||||
FORWARDED_TYPED_EVENT(QuitRequested, Windows::Foundation::IInspectable, Windows::Foundation::IInspectable, _root, QuitRequested);
|
||||
@@ -234,7 +231,6 @@ namespace winrt::TerminalApp::implementation
|
||||
FORWARDED_TYPED_EVENT(RequestReceiveContent, Windows::Foundation::IInspectable, winrt::TerminalApp::RequestReceiveContentArgs, _root, RequestReceiveContent);
|
||||
|
||||
FORWARDED_TYPED_EVENT(RequestLaunchPosition, Windows::Foundation::IInspectable, winrt::TerminalApp::LaunchPositionRequest, _root, RequestLaunchPosition);
|
||||
FORWARDED_TYPED_EVENT(RequestWindowList, Windows::Foundation::IInspectable, winrt::TerminalApp::WindowListRequest, _root, RequestWindowList);
|
||||
|
||||
#ifdef UNIT_TESTING
|
||||
friend class TerminalAppLocalTests::CommandlineTest;
|
||||
|
||||
@@ -56,13 +56,11 @@ namespace TerminalApp
|
||||
|
||||
Int32 SetStartupCommandline(CommandlineArgs args);
|
||||
void SetStartupContent(String json, Windows.Foundation.IReference<Windows.Foundation.Rect> bounds);
|
||||
void SetPersistedLayout(Microsoft.Terminal.Settings.Model.WindowLayout layout);
|
||||
Int32 ExecuteCommandline(CommandlineArgs args);
|
||||
|
||||
Boolean ShouldImmediatelyHandoffToElevated();
|
||||
void HandoffToElevated();
|
||||
|
||||
Microsoft.Terminal.Settings.Model.WindowLayout GetWindowLayout();
|
||||
void PersistState();
|
||||
|
||||
Windows.UI.Xaml.UIElement GetRoot();
|
||||
@@ -130,7 +128,6 @@ namespace TerminalApp
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> IdentifyWindowsRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> IsQuakeWindowChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> SummonWindowRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, SummonWindowByIdRequestedArgs> SummonWindowByIdRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, TerminalApp.Tab> FocusTabRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> OpenSystemMenu;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> QuitRequested;
|
||||
@@ -143,7 +140,6 @@ namespace TerminalApp
|
||||
event Windows.Foundation.TypedEventHandler<Object, RequestMoveContentArgs> RequestMoveContent;
|
||||
event Windows.Foundation.TypedEventHandler<Object, RequestReceiveContentArgs> RequestReceiveContent;
|
||||
event Windows.Foundation.TypedEventHandler<Object, LaunchPositionRequest> RequestLaunchPosition;
|
||||
event Windows.Foundation.TypedEventHandler<Object, WindowListRequest> RequestWindowList;
|
||||
|
||||
void AttachContent(String content, UInt32 tabIndex);
|
||||
void SendContentToOther(RequestReceiveContentArgs args);
|
||||
|
||||
@@ -73,8 +73,6 @@ static constexpr std::string_view NewWindowKey{ "newWindow" };
|
||||
static constexpr std::string_view IdentifyWindowKey{ "identifyWindow" };
|
||||
static constexpr std::string_view IdentifyWindowsKey{ "identifyWindows" };
|
||||
static constexpr std::string_view RenameWindowKey{ "renameWindow" };
|
||||
static constexpr std::string_view OpenWorkspaceKey{ "openWorkspace" };
|
||||
|
||||
static constexpr std::string_view OpenWindowRenamerKey{ "openWindowRenamer" };
|
||||
static constexpr std::string_view DisplayWorkingDirectoryKey{ "debugTerminalCwd" };
|
||||
static constexpr std::string_view SearchForTextKey{ "searchWeb" };
|
||||
@@ -103,7 +101,6 @@ static constexpr std::string_view OpenScratchpadKey{ "experimental.openScratchpa
|
||||
static constexpr std::string_view OpenAboutKey{ "openAbout" };
|
||||
static constexpr std::string_view QuickFixKey{ "quickFix" };
|
||||
static constexpr std::string_view OpenCWDKey{ "openCWD" };
|
||||
static constexpr std::string_view WorkspacesKey{ "workspaces" };
|
||||
|
||||
static constexpr std::string_view ActionKey{ "action" };
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include "PrevTabArgs.g.cpp"
|
||||
#include "NextTabArgs.g.cpp"
|
||||
#include "RenameWindowArgs.g.cpp"
|
||||
#include "OpenWorkspaceArgs.g.cpp"
|
||||
#include "SearchForTextArgs.g.cpp"
|
||||
#include "GlobalSummonArgs.g.cpp"
|
||||
#include "FocusPaneArgs.g.cpp"
|
||||
@@ -796,15 +795,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
return RS_switchable_(L"ResetWindowNameCommandKey");
|
||||
}
|
||||
|
||||
winrt::hstring OpenWorkspaceArgs::GenerateName(const winrt::WARC::ResourceContext& context) const
|
||||
{
|
||||
if (!Name().empty())
|
||||
{
|
||||
return winrt::hstring{ RS_switchable_fmt(L"OpenWorkspaceCommandKey", Name()) };
|
||||
}
|
||||
return RS_switchable_(L"OpenWorkspaceDefaultCommandKey");
|
||||
}
|
||||
|
||||
winrt::hstring SearchForTextArgs::GenerateName(const winrt::WARC::ResourceContext& context) const
|
||||
{
|
||||
if (QueryUrl().empty())
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
#include "PrevTabArgs.g.h"
|
||||
#include "NextTabArgs.g.h"
|
||||
#include "RenameWindowArgs.g.h"
|
||||
#include "OpenWorkspaceArgs.g.h"
|
||||
#include "SearchForTextArgs.g.h"
|
||||
#include "GlobalSummonArgs.g.h"
|
||||
#include "FocusPaneArgs.g.h"
|
||||
@@ -247,10 +246,6 @@ protected: \
|
||||
#define RENAME_WINDOW_ARGS(X) \
|
||||
X(winrt::hstring, Name, "name", false, ArgTypeHint::None, L"")
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define OPEN_WORKSPACE_ARGS(X) \
|
||||
X(winrt::hstring, Name, "name", false, ArgTypeHint::None, L"")
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define SEARCH_FOR_TEXT_ARGS(X) \
|
||||
X(winrt::hstring, QueryUrl, "queryUrl", false, ArgTypeHint::None, L"")
|
||||
@@ -945,8 +940,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
|
||||
ACTION_ARGS_STRUCT(RenameWindowArgs, RENAME_WINDOW_ARGS);
|
||||
|
||||
ACTION_ARGS_STRUCT(OpenWorkspaceArgs, OPEN_WORKSPACE_ARGS);
|
||||
|
||||
ACTION_ARGS_STRUCT(SearchForTextArgs, SEARCH_FOR_TEXT_ARGS);
|
||||
|
||||
struct GlobalSummonArgs : public GlobalSummonArgsT<GlobalSummonArgs>
|
||||
@@ -1066,7 +1059,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
|
||||
BASIC_FACTORY(SetMaximizedArgs);
|
||||
BASIC_FACTORY(SetColorSchemeArgs);
|
||||
BASIC_FACTORY(RenameWindowArgs);
|
||||
BASIC_FACTORY(OpenWorkspaceArgs);
|
||||
BASIC_FACTORY(ExecuteCommandlineArgs);
|
||||
BASIC_FACTORY(CloseOtherTabsArgs);
|
||||
BASIC_FACTORY(CloseTabsAfterArgs);
|
||||
|
||||
@@ -420,12 +420,6 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
String Name { get; };
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass OpenWorkspaceArgs : IActionArgs, IActionArgsDescriptorAccess
|
||||
{
|
||||
OpenWorkspaceArgs(String name);
|
||||
String Name { get; };
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass SearchForTextArgs : IActionArgs, IActionArgsDescriptorAccess
|
||||
{
|
||||
String QueryUrl { get; };
|
||||
|
||||
@@ -116,7 +116,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
{ ShortcutAction::OpenTabColorPicker, USES_RESOURCE(L"OpenTabColorPickerCommandKey") },
|
||||
{ ShortcutAction::OpenTabRenamer, USES_RESOURCE(L"OpenTabRenamerCommandKey") },
|
||||
{ ShortcutAction::OpenWindowRenamer, USES_RESOURCE(L"OpenWindowRenamerCommandKey") },
|
||||
{ ShortcutAction::OpenWorkspace, USES_RESOURCE(L"OpenWorkspaceDefaultCommandKey") },
|
||||
{ ShortcutAction::PasteText, USES_RESOURCE(L"PasteTextCommandKey") },
|
||||
{ ShortcutAction::PrevTab, USES_RESOURCE(L"PrevTabCommandKey") },
|
||||
{ ShortcutAction::QuickFix, USES_RESOURCE(L"QuickFixCommandKey") },
|
||||
@@ -163,7 +162,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
{ ShortcutAction::TogglePaneZoom, USES_RESOURCE(L"TogglePaneZoomCommandKey") },
|
||||
{ ShortcutAction::ToggleShaderEffects, USES_RESOURCE(L"ToggleShaderEffectsCommandKey") },
|
||||
{ ShortcutAction::ToggleSplitOrientation, USES_RESOURCE(L"ToggleSplitOrientationCommandKey") },
|
||||
{ ShortcutAction::Workspaces, USES_RESOURCE(L"WorkspacesCommandKey") },
|
||||
};
|
||||
}();
|
||||
|
||||
@@ -227,8 +225,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
return winrt::make<NextTabArgs>();
|
||||
case Model::ShortcutAction::OpenSettings:
|
||||
return winrt::make<OpenSettingsArgs>();
|
||||
case Model::ShortcutAction::OpenWorkspace:
|
||||
return winrt::make<OpenWorkspaceArgs>();
|
||||
case Model::ShortcutAction::SetFocusMode:
|
||||
return winrt::make<SetFocusModeArgs>();
|
||||
case Model::ShortcutAction::SetFullScreen:
|
||||
|
||||
@@ -113,9 +113,7 @@
|
||||
ON_ALL_ACTIONS(OpenScratchpad) \
|
||||
ON_ALL_ACTIONS(OpenAbout) \
|
||||
ON_ALL_ACTIONS(QuickFix) \
|
||||
ON_ALL_ACTIONS(OpenCWD) \
|
||||
ON_ALL_ACTIONS(OpenWorkspace) \
|
||||
ON_ALL_ACTIONS(Workspaces)
|
||||
ON_ALL_ACTIONS(OpenCWD)
|
||||
|
||||
#define ALL_SHORTCUT_ACTIONS_WITH_ARGS \
|
||||
ON_ALL_ACTIONS_WITH_ARGS(AdjustFontSize) \
|
||||
@@ -160,8 +158,7 @@
|
||||
ON_ALL_ACTIONS_WITH_ARGS(Suggestions) \
|
||||
ON_ALL_ACTIONS_WITH_ARGS(SelectCommand) \
|
||||
ON_ALL_ACTIONS_WITH_ARGS(SelectOutput) \
|
||||
ON_ALL_ACTIONS_WITH_ARGS(ColorSelection) \
|
||||
ON_ALL_ACTIONS_WITH_ARGS(OpenWorkspace)
|
||||
ON_ALL_ACTIONS_WITH_ARGS(ColorSelection)
|
||||
|
||||
// These two macros here are for actions that we only use as internal currency.
|
||||
// They don't need to be parsed by the settings model, or saved as actions to
|
||||
|
||||
@@ -253,9 +253,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
return *state;
|
||||
}
|
||||
|
||||
// Need the COMMA macro hack for IMap template arguments in the macros
|
||||
#define COMMA ,
|
||||
|
||||
// Method Description:
|
||||
// - Loads data from the given json blob. Will only read the data that's in
|
||||
// the specified parseSource - so if we're reading the Local state file,
|
||||
@@ -305,8 +302,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
return root;
|
||||
}
|
||||
|
||||
#undef COMMA
|
||||
|
||||
void ApplicationState::AppendPersistedWindowLayout(Model::WindowLayout layout)
|
||||
{
|
||||
{
|
||||
@@ -346,120 +341,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
return false;
|
||||
}
|
||||
|
||||
void ApplicationState::SaveWorkspace(const hstring& name, const Model::WindowLayout& layout)
|
||||
{
|
||||
{
|
||||
const auto state = _state.lock();
|
||||
if (!state->PersistedWorkspaces || !*state->PersistedWorkspaces)
|
||||
{
|
||||
state->PersistedWorkspaces = winrt::single_threaded_map<hstring, Model::WindowLayout>();
|
||||
}
|
||||
(*state->PersistedWorkspaces).Insert(name, layout);
|
||||
}
|
||||
_throttler();
|
||||
}
|
||||
|
||||
bool ApplicationState::RemoveWorkspace(const hstring& name)
|
||||
{
|
||||
bool removed{ false };
|
||||
{
|
||||
const auto state = _state.lock();
|
||||
if (state->PersistedWorkspaces && *state->PersistedWorkspaces)
|
||||
{
|
||||
auto map = *state->PersistedWorkspaces;
|
||||
if (map.HasKey(name))
|
||||
{
|
||||
map.Remove(name);
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (removed)
|
||||
{
|
||||
_throttler();
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Rename a persisted workspace entry from oldName to newName. If there
|
||||
// was no entry for oldName, this is a no-op. If an entry for newName
|
||||
// already exists, it will be overwritten with the layout from oldName.
|
||||
// - If newName is empty, the entry under oldName is simply removed (the
|
||||
// old name no longer points at a valid window, so the persisted layout
|
||||
// would otherwise be left stranded).
|
||||
// Return Value:
|
||||
// - true if the persisted state was modified, false otherwise.
|
||||
bool ApplicationState::RenameWorkspace(const hstring& oldName, const hstring& newName)
|
||||
{
|
||||
if (oldName == newName || oldName.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool changed{ false };
|
||||
{
|
||||
const auto state = _state.lock();
|
||||
if (state->PersistedWorkspaces && *state->PersistedWorkspaces)
|
||||
{
|
||||
auto map = *state->PersistedWorkspaces;
|
||||
if (map.HasKey(oldName))
|
||||
{
|
||||
if (!newName.empty())
|
||||
{
|
||||
const auto layout = map.Lookup(oldName);
|
||||
map.Insert(newName, layout);
|
||||
}
|
||||
map.Remove(oldName);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changed)
|
||||
{
|
||||
_throttler();
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Atomically remove and return a persisted workspace entry. This is the
|
||||
// intended API for the startup path that restores a named workspace,
|
||||
// because it guarantees only one caller can claim a given workspace.
|
||||
// Return Value:
|
||||
// - The layout that was stored under `name`, or nullptr if there was none.
|
||||
Model::WindowLayout ApplicationState::TakeWorkspace(const hstring& name)
|
||||
{
|
||||
Model::WindowLayout result{ nullptr };
|
||||
{
|
||||
const auto state = _state.lock();
|
||||
if (state->PersistedWorkspaces && *state->PersistedWorkspaces)
|
||||
{
|
||||
auto map = *state->PersistedWorkspaces;
|
||||
if (map.HasKey(name))
|
||||
{
|
||||
result = map.Lookup(name);
|
||||
map.Remove(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result)
|
||||
{
|
||||
_throttler();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Windows::Foundation::Collections::IMapView<hstring, Model::WindowLayout> ApplicationState::AllPersistedWorkspaces()
|
||||
{
|
||||
const auto state = _state.lock_shared();
|
||||
if (state->PersistedWorkspaces && *state->PersistedWorkspaces)
|
||||
{
|
||||
return (*state->PersistedWorkspaces).GetView();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Generate all getter/setters
|
||||
#define MTSM_APPLICATION_STATE_GEN(source, type, name, key, ...) \
|
||||
type ApplicationState::name() const noexcept \
|
||||
@@ -478,9 +359,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
\
|
||||
_throttler(); \
|
||||
}
|
||||
#define COMMA ,
|
||||
MTSM_APPLICATION_STATE_FIELDS(MTSM_APPLICATION_STATE_GEN)
|
||||
#undef COMMA
|
||||
#undef MTSM_APPLICATION_STATE_GEN
|
||||
|
||||
// Method Description:
|
||||
|
||||
@@ -16,7 +16,7 @@ Abstract:
|
||||
#include "WindowLayout.g.h"
|
||||
|
||||
#include <inc/cppwinrt_utils.h>
|
||||
#include "JsonUtils.h"
|
||||
#include <JsonUtils.h>
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
{
|
||||
@@ -34,7 +34,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
// This macro generates all getters and setters for ApplicationState.
|
||||
// It provides X with the following arguments:
|
||||
// (source, type, function name, JSON key, ...variadic construction arguments)
|
||||
// Note: we're using the COMMA macro hack for the template arguments as used elsewhere.
|
||||
#define MTSM_APPLICATION_STATE_FIELDS(X) \
|
||||
X(FileSource::Shared, winrt::hstring, SettingsHash, "settingsHash") \
|
||||
X(FileSource::Shared, std::unordered_set<winrt::guid>, GeneratedProfiles, "generatedProfiles") \
|
||||
@@ -43,7 +42,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
X(FileSource::Shared, Windows::Foundation::Collections::IVector<winrt::Microsoft::Terminal::Settings::Model::InfoBarMessage>, DismissedMessages, "dismissedMessages") \
|
||||
X(FileSource::Local, Windows::Foundation::Collections::IVector<hstring>, AllowedCommandlines, "allowedCommandlines") \
|
||||
X(FileSource::Local, std::unordered_set<hstring>, DismissedBadges, "dismissedBadges") \
|
||||
X(FileSource::Local, Windows::Foundation::Collections::IMap<hstring COMMA Model::WindowLayout>, PersistedWorkspaces, "persistedWorkspaces") \
|
||||
X(FileSource::Shared, bool, SSHFolderGenerated, "sshFolderGenerated", false)
|
||||
|
||||
struct WindowLayout : WindowLayoutT<WindowLayout>
|
||||
@@ -59,8 +57,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
friend ::Microsoft::Terminal::Settings::Model::JsonUtils::ConversionTrait<Model::WindowLayout>;
|
||||
};
|
||||
|
||||
#define COMMA ,
|
||||
|
||||
struct ApplicationState : public ApplicationStateT<ApplicationState>
|
||||
{
|
||||
static Microsoft::Terminal::Settings::Model::ApplicationState SharedInstance();
|
||||
@@ -79,12 +75,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
bool DismissBadge(const hstring& badgeId);
|
||||
bool BadgeDismissed(const hstring& badgeId) const;
|
||||
|
||||
void SaveWorkspace(const hstring& name, const Model::WindowLayout& layout);
|
||||
bool RemoveWorkspace(const hstring& name);
|
||||
bool RenameWorkspace(const hstring& oldName, const hstring& newName);
|
||||
Model::WindowLayout TakeWorkspace(const hstring& name);
|
||||
Windows::Foundation::Collections::IMapView<hstring, Model::WindowLayout> AllPersistedWorkspaces();
|
||||
|
||||
// State getters/setters
|
||||
#define MTSM_APPLICATION_STATE_GEN(source, type, name, key, ...) \
|
||||
type name() const noexcept; \
|
||||
@@ -114,7 +104,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
std::string _readLocalContents() const;
|
||||
void _writeLocalContents(const std::string_view content) const;
|
||||
};
|
||||
#undef COMMA
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
|
||||
|
||||
@@ -36,12 +36,6 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
Boolean DismissBadge(String badgeId);
|
||||
Boolean BadgeDismissed(String badgeId);
|
||||
|
||||
void SaveWorkspace(String name, WindowLayout layout);
|
||||
Boolean RemoveWorkspace(String name);
|
||||
Boolean RenameWorkspace(String oldName, String newName);
|
||||
WindowLayout TakeWorkspace(String name);
|
||||
Windows.Foundation.Collections.IMapView<String, WindowLayout> AllPersistedWorkspaces();
|
||||
|
||||
String SettingsHash;
|
||||
Windows.Foundation.Collections.IVector<WindowLayout> PersistedWindowLayouts;
|
||||
Windows.Foundation.Collections.IVector<String> RecentCommands;
|
||||
|
||||
@@ -162,8 +162,7 @@ Author(s):
|
||||
X(winrt::Microsoft::Terminal::Settings::Model::ThemeColor, Frame, "frame", nullptr) \
|
||||
X(winrt::Microsoft::Terminal::Settings::Model::ThemeColor, UnfocusedFrame, "unfocusedFrame", nullptr) \
|
||||
X(bool, RainbowFrame, "experimental.rainbowFrame", false) \
|
||||
X(bool, UseMica, "useMica", false) \
|
||||
X(bool, ShowWorkspacesButton, "showWorkspacesButton", true)
|
||||
X(bool, UseMica, "useMica", false)
|
||||
|
||||
#define MTSM_THEME_SETTINGS_SETTINGS(X) \
|
||||
X(winrt::Windows::UI::Xaml::ElementTheme, RequestedTheme, "theme", winrt::Windows::UI::Xaml::ElementTheme::Default)
|
||||
|
||||
@@ -518,13 +518,6 @@
|
||||
<data name="ResetWindowNameCommandKey" xml:space="preserve">
|
||||
<value>Reset window name</value>
|
||||
</data>
|
||||
<data name="OpenWorkspaceCommandKey" xml:space="preserve">
|
||||
<value>Open workspace "{0}"</value>
|
||||
<comment>{0} will be replaced with the workspace name</comment>
|
||||
</data>
|
||||
<data name="OpenWorkspaceDefaultCommandKey" xml:space="preserve">
|
||||
<value>Open workspace</value>
|
||||
</data>
|
||||
<data name="OpenWindowRenamerCommandKey" xml:space="preserve">
|
||||
<value>Rename window...</value>
|
||||
</data>
|
||||
@@ -747,9 +740,6 @@
|
||||
<data name="OpenCWDCommandKey" xml:space="preserve">
|
||||
<value>Open current working directory</value>
|
||||
</data>
|
||||
<data name="WorkspacesCommandKey" xml:space="preserve">
|
||||
<value>Workspaces...</value>
|
||||
</data>
|
||||
<data name="CloseTab" xml:space="preserve">
|
||||
<value>Close tab</value>
|
||||
</data>
|
||||
|
||||
@@ -62,7 +62,6 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
Windows.UI.Xaml.ElementTheme RequestedTheme { get; };
|
||||
Boolean UseMica { get; };
|
||||
Boolean RainbowFrame { get; };
|
||||
Boolean ShowWorkspacesButton { get; };
|
||||
ThemeColor Frame { get; };
|
||||
ThemeColor UnfocusedFrame { get; };
|
||||
}
|
||||
|
||||
@@ -542,7 +542,6 @@
|
||||
{ "command": "quickFix", "id": "Terminal.QuickFix" },
|
||||
{ "command": { "action": "showSuggestions", "source": "all"}, "id": "Terminal.Suggestions" },
|
||||
{ "command": "openCWD", "id": "Terminal.OpenCWD" },
|
||||
{ "command": "workspaces", "id": "Terminal.Workspaces" },
|
||||
|
||||
// Tab Management
|
||||
// "command": "closeTab" is unbound by default.
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "../TerminalSettingsModel/ApplicationState.h"
|
||||
|
||||
using namespace Microsoft::Console;
|
||||
using namespace WEX::Logging;
|
||||
using namespace WEX::TestExecution;
|
||||
using namespace WEX::Common;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
|
||||
namespace SettingsModelUnitTests
|
||||
{
|
||||
// Covers the workspace-persistence APIs added to ApplicationState:
|
||||
// SaveWorkspace / RemoveWorkspace / RenameWorkspace / TakeWorkspace /
|
||||
// AllPersistedWorkspaces.
|
||||
// All tests operate on a throw-away ApplicationState instance pointed at
|
||||
// a temp directory, so they don't touch the real user state.
|
||||
class ApplicationStateTests
|
||||
{
|
||||
TEST_CLASS(ApplicationStateTests);
|
||||
|
||||
TEST_METHOD(SaveAndLookupWorkspace);
|
||||
TEST_METHOD(RemoveWorkspaceReturnsFalseWhenMissing);
|
||||
TEST_METHOD(RenameWorkspaceMigratesEntry);
|
||||
TEST_METHOD(RenameWorkspaceNoOpForEmptyOrEqualNames);
|
||||
TEST_METHOD(RenameWorkspaceNoOpForMissingEntry);
|
||||
TEST_METHOD(TakeWorkspaceRemovesAndReturns);
|
||||
TEST_METHOD(TakeWorkspaceReturnsNullWhenMissing);
|
||||
|
||||
private:
|
||||
static std::filesystem::path _tempRoot()
|
||||
{
|
||||
auto root = std::filesystem::temp_directory_path() / L"WT_ApplicationStateTests";
|
||||
std::error_code ec;
|
||||
std::filesystem::create_directories(root, ec);
|
||||
// Best-effort clean of any leftover state.json from a prior run so
|
||||
// tests see an empty starting point.
|
||||
std::filesystem::remove(root / L"state.json", ec);
|
||||
std::filesystem::remove(root / L"elevated-state.json", ec);
|
||||
return root;
|
||||
}
|
||||
|
||||
static winrt::com_ptr<implementation::ApplicationState> _make()
|
||||
{
|
||||
return winrt::make_self<implementation::ApplicationState>(_tempRoot());
|
||||
}
|
||||
|
||||
static WindowLayout _makeLayout()
|
||||
{
|
||||
WindowLayout layout;
|
||||
layout.TabLayout(winrt::single_threaded_vector<ActionAndArgs>());
|
||||
return layout;
|
||||
}
|
||||
};
|
||||
|
||||
void ApplicationStateTests::SaveAndLookupWorkspace()
|
||||
{
|
||||
auto state = _make();
|
||||
const auto layout = _makeLayout();
|
||||
state->SaveWorkspace(L"win1", layout);
|
||||
|
||||
const auto all = state->AllPersistedWorkspaces();
|
||||
VERIFY_IS_NOT_NULL(all);
|
||||
VERIFY_IS_TRUE(all.HasKey(L"win1"));
|
||||
}
|
||||
|
||||
void ApplicationStateTests::RemoveWorkspaceReturnsFalseWhenMissing()
|
||||
{
|
||||
auto state = _make();
|
||||
VERIFY_IS_FALSE(state->RemoveWorkspace(L"does-not-exist"));
|
||||
|
||||
state->SaveWorkspace(L"win1", _makeLayout());
|
||||
VERIFY_IS_TRUE(state->RemoveWorkspace(L"win1"));
|
||||
VERIFY_IS_FALSE(state->RemoveWorkspace(L"win1"));
|
||||
}
|
||||
|
||||
void ApplicationStateTests::RenameWorkspaceMigratesEntry()
|
||||
{
|
||||
auto state = _make();
|
||||
state->SaveWorkspace(L"oldName", _makeLayout());
|
||||
|
||||
VERIFY_IS_TRUE(state->RenameWorkspace(L"oldName", L"newName"));
|
||||
|
||||
const auto all = state->AllPersistedWorkspaces();
|
||||
VERIFY_IS_NOT_NULL(all);
|
||||
VERIFY_IS_FALSE(all.HasKey(L"oldName"));
|
||||
VERIFY_IS_TRUE(all.HasKey(L"newName"));
|
||||
}
|
||||
|
||||
void ApplicationStateTests::RenameWorkspaceNoOpForEmptyOrEqualNames()
|
||||
{
|
||||
auto state = _make();
|
||||
state->SaveWorkspace(L"win1", _makeLayout());
|
||||
|
||||
VERIFY_IS_FALSE(state->RenameWorkspace(L"win1", L"win1"));
|
||||
VERIFY_IS_FALSE(state->RenameWorkspace(L"", L"win2"));
|
||||
|
||||
// Renaming to an empty name removes the stale entry under the old name.
|
||||
VERIFY_IS_TRUE(state->RenameWorkspace(L"win1", L""));
|
||||
const auto all = state->AllPersistedWorkspaces();
|
||||
if (all)
|
||||
{
|
||||
VERIFY_IS_FALSE(all.HasKey(L"win1"));
|
||||
VERIFY_IS_FALSE(all.HasKey(L""));
|
||||
}
|
||||
|
||||
// Calling again is now a no-op because the entry is gone.
|
||||
VERIFY_IS_FALSE(state->RenameWorkspace(L"win1", L""));
|
||||
}
|
||||
|
||||
void ApplicationStateTests::RenameWorkspaceNoOpForMissingEntry()
|
||||
{
|
||||
auto state = _make();
|
||||
VERIFY_IS_FALSE(state->RenameWorkspace(L"missing", L"newName"));
|
||||
}
|
||||
|
||||
void ApplicationStateTests::TakeWorkspaceRemovesAndReturns()
|
||||
{
|
||||
auto state = _make();
|
||||
state->SaveWorkspace(L"win1", _makeLayout());
|
||||
|
||||
const auto taken = state->TakeWorkspace(L"win1");
|
||||
VERIFY_IS_NOT_NULL(taken);
|
||||
|
||||
// Subsequent Take for the same name must return null — this is the
|
||||
// atomicity guarantee the startup path relies on.
|
||||
VERIFY_IS_NULL(state->TakeWorkspace(L"win1"));
|
||||
}
|
||||
|
||||
void ApplicationStateTests::TakeWorkspaceReturnsNullWhenMissing()
|
||||
{
|
||||
auto state = _make();
|
||||
VERIFY_IS_NULL(state->TakeWorkspace(L"missing"));
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,6 @@
|
||||
<ClCompile Include="TerminalSettingsTests.cpp" />
|
||||
<ClCompile Include="ThemeTests.cpp" />
|
||||
<ClCompile Include="MediaResourceTests.cpp" />
|
||||
<ClCompile Include="ApplicationStateTests.cpp" />
|
||||
<ClCompile Include="../TerminalSettingsAppAdapterLib/TerminalSettings.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
|
||||
@@ -66,8 +66,6 @@ Author(s):
|
||||
// Manually include til after we include Windows.Foundation to give it winrt superpowers
|
||||
#include "til.h"
|
||||
#include <til/winrt.h>
|
||||
#include <til/mutex.h>
|
||||
#include <til/throttled_func.h>
|
||||
|
||||
// Common includes for most tests:
|
||||
#include "../../inc/conattrs.hpp"
|
||||
|
||||
@@ -132,12 +132,7 @@ void AppHost::_HandleCommandlineArgs(const winrt::TerminalApp::WindowRequestedAr
|
||||
// We don't have XAML yet, but we do have other stuff.
|
||||
_windowLogic = _appLogic.CreateNewWindow();
|
||||
|
||||
if (const auto layout = windowArgs.PersistedLayout())
|
||||
{
|
||||
_windowLogic.SetPersistedLayout(layout);
|
||||
_launchShowWindowCommand = SW_NORMAL;
|
||||
}
|
||||
else if (const auto content = windowArgs.Content(); !content.empty())
|
||||
if (const auto content = windowArgs.Content(); !content.empty())
|
||||
{
|
||||
_windowLogic.SetStartupContent(content, windowArgs.InitialBounds());
|
||||
_launchShowWindowCommand = SW_NORMAL;
|
||||
@@ -270,14 +265,12 @@ void AppHost::Initialize()
|
||||
|
||||
_revokers.IsQuakeWindowChanged = _windowLogic.IsQuakeWindowChanged(winrt::auto_revoke, { this, &AppHost::_IsQuakeWindowChanged });
|
||||
_revokers.SummonWindowRequested = _windowLogic.SummonWindowRequested(winrt::auto_revoke, { this, &AppHost::_SummonWindowRequested });
|
||||
_revokers.SummonWindowByIdRequested = _windowLogic.SummonWindowByIdRequested(winrt::auto_revoke, { this, &AppHost::_SummonWindowByIdRequested });
|
||||
_revokers.FocusTabRequested = _windowLogic.FocusTabRequested(winrt::auto_revoke, { this, &AppHost::_FocusTabRequested });
|
||||
_revokers.OpenSystemMenu = _windowLogic.OpenSystemMenu(winrt::auto_revoke, { this, &AppHost::_OpenSystemMenu });
|
||||
_revokers.QuitRequested = _windowLogic.QuitRequested(winrt::auto_revoke, { this, &AppHost::_RequestQuitAll });
|
||||
_revokers.ShowWindowChanged = _windowLogic.ShowWindowChanged(winrt::auto_revoke, { this, &AppHost::_ShowWindowChanged });
|
||||
_revokers.RequestMoveContent = _windowLogic.RequestMoveContent(winrt::auto_revoke, { this, &AppHost::_handleMoveContent });
|
||||
_revokers.RequestReceiveContent = _windowLogic.RequestReceiveContent(winrt::auto_revoke, { this, &AppHost::_handleReceiveContent });
|
||||
_revokers.RequestWindowList = _windowLogic.RequestWindowList(winrt::auto_revoke, { this, &AppHost::_HandleRequestWindowList });
|
||||
|
||||
// BODGY
|
||||
// On certain builds of Windows, when Terminal is set as the default
|
||||
@@ -417,28 +410,6 @@ void AppHost::_HandleRequestLaunchPosition(const winrt::Windows::Foundation::IIn
|
||||
args.Position(_GetWindowLaunchPosition());
|
||||
}
|
||||
|
||||
void AppHost::_HandleRequestWindowList(const winrt::Windows::Foundation::IInspectable& /*sender*/,
|
||||
winrt::TerminalApp::WindowListRequest args)
|
||||
{
|
||||
// Ask the Emperor (on the main thread) for the current window list.
|
||||
// SendMessage blocks until the message is processed, so this is
|
||||
// synchronous and the results vector is filled in-place.
|
||||
std::vector<WindowEmperor::WindowListEntry> entries;
|
||||
SendMessage(_windowManager->GetMainWindow(),
|
||||
WindowEmperor::WM_GET_WINDOW_LIST,
|
||||
0,
|
||||
reinterpret_cast<LPARAM>(&entries));
|
||||
|
||||
auto windowEntries = args.Entries();
|
||||
for (const auto& entry : entries)
|
||||
{
|
||||
winrt::TerminalApp::WindowListEntry w;
|
||||
w.Id(entry.Id);
|
||||
w.Name(winrt::hstring{ entry.Name });
|
||||
windowEntries.Append(w);
|
||||
}
|
||||
}
|
||||
|
||||
LaunchPosition AppHost::_GetWindowLaunchPosition()
|
||||
{
|
||||
LaunchPosition pos{};
|
||||
@@ -1094,23 +1065,6 @@ void AppHost::_SummonWindowRequested(const winrt::Windows::Foundation::IInspecta
|
||||
HandleSummon(std::move(summonArgs));
|
||||
}
|
||||
|
||||
void AppHost::_SummonWindowByIdRequested(const winrt::Windows::Foundation::IInspectable&,
|
||||
const winrt::TerminalApp::SummonWindowByIdRequestedArgs& args)
|
||||
{
|
||||
// Summon the window by its ID without creating a new tab.
|
||||
// We look up the target window in WindowEmperor and call HandleSummon directly.
|
||||
const auto targetId = args.WindowId();
|
||||
if (auto* targetWindow = _windowManager->GetWindowById(targetId))
|
||||
{
|
||||
winrt::TerminalApp::SummonWindowBehavior summonBehavior;
|
||||
summonBehavior.MoveToCurrentDesktop(false);
|
||||
summonBehavior.DropdownDuration(0);
|
||||
summonBehavior.ToMonitor(winrt::TerminalApp::MonitorBehavior::InPlace);
|
||||
summonBehavior.ToggleVisibility(false); // Do not toggle, just make visible.
|
||||
targetWindow->HandleSummon(std::move(summonBehavior));
|
||||
}
|
||||
}
|
||||
|
||||
void AppHost::_FocusTabRequested(const winrt::Windows::Foundation::IInspectable&,
|
||||
const winrt::TerminalApp::Tab& tab)
|
||||
{
|
||||
|
||||
@@ -91,9 +91,6 @@ private:
|
||||
void _SummonWindowRequested(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Windows::Foundation::IInspectable& args);
|
||||
|
||||
void _SummonWindowByIdRequested(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::TerminalApp::SummonWindowByIdRequestedArgs& args);
|
||||
|
||||
void _FocusTabRequested(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::TerminalApp::Tab& tab);
|
||||
|
||||
@@ -136,8 +133,6 @@ private:
|
||||
void _AppTitleChanged(const winrt::Windows::Foundation::IInspectable&, const winrt::Windows::Foundation::IInspectable&);
|
||||
void _HandleRequestLaunchPosition(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
winrt::TerminalApp::LaunchPositionRequest args);
|
||||
void _HandleRequestWindowList(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
winrt::TerminalApp::WindowListRequest args);
|
||||
|
||||
// Helper struct. By putting these all into one struct, we can revoke them
|
||||
// all at once, by assigning _revokers to a fresh Revokers instance. That'll
|
||||
@@ -159,7 +154,6 @@ private:
|
||||
winrt::TerminalApp::TerminalWindow::IdentifyWindowsRequested_revoker IdentifyWindowsRequested;
|
||||
winrt::TerminalApp::TerminalWindow::IsQuakeWindowChanged_revoker IsQuakeWindowChanged;
|
||||
winrt::TerminalApp::TerminalWindow::SummonWindowRequested_revoker SummonWindowRequested;
|
||||
winrt::TerminalApp::TerminalWindow::SummonWindowByIdRequested_revoker SummonWindowByIdRequested;
|
||||
winrt::TerminalApp::TerminalWindow::FocusTabRequested_revoker FocusTabRequested;
|
||||
winrt::TerminalApp::TerminalWindow::OpenSystemMenu_revoker OpenSystemMenu;
|
||||
winrt::TerminalApp::TerminalWindow::QuitRequested_revoker QuitRequested;
|
||||
@@ -167,7 +161,6 @@ private:
|
||||
winrt::TerminalApp::TerminalWindow::RequestMoveContent_revoker RequestMoveContent;
|
||||
winrt::TerminalApp::TerminalWindow::RequestReceiveContent_revoker RequestReceiveContent;
|
||||
winrt::TerminalApp::TerminalWindow::RequestLaunchPosition_revoker RequestLaunchPosition;
|
||||
winrt::TerminalApp::TerminalWindow::RequestWindowList_revoker RequestWindowList;
|
||||
winrt::TerminalApp::TerminalWindow::PropertyChanged_revoker PropertyChanged;
|
||||
winrt::TerminalApp::TerminalWindow::SettingsChanged_revoker SettingsChanged;
|
||||
winrt::TerminalApp::TerminalWindow::WindowSizeChanged_revoker WindowSizeChanged;
|
||||
|
||||
@@ -803,19 +803,6 @@ void WindowEmperor::_dispatchCommandline(winrt::TerminalApp::CommandlineArgs arg
|
||||
{
|
||||
winrt::TerminalApp::WindowRequestedArgs request{ windowId, std::move(args) };
|
||||
request.WindowName(std::move(windowName));
|
||||
|
||||
// If we're opening a named window that doesn't exist yet, atomically
|
||||
// claim any persisted workspace with that name so we restore it here
|
||||
// and no subsequent window can pick up the same entry.
|
||||
const auto& reqName = request.WindowName();
|
||||
if (!reqName.empty())
|
||||
{
|
||||
if (const auto layout = ApplicationState::SharedInstance().TakeWorkspace(reqName))
|
||||
{
|
||||
request.PersistedLayout(layout);
|
||||
}
|
||||
}
|
||||
|
||||
CreateNewWindow(std::move(request));
|
||||
}
|
||||
}
|
||||
@@ -1100,22 +1087,6 @@ LRESULT WindowEmperor::_messageHandler(HWND window, UINT const message, WPARAM c
|
||||
// anyway (since we threw and exited this message handler) so this at least gives back our
|
||||
// deterministic window count management.
|
||||
const auto strong = *it;
|
||||
|
||||
// Before destroying a named window, persist its full
|
||||
// tab/buffer state as a workspace so it can be restored later.
|
||||
try
|
||||
{
|
||||
const auto windowName = strong->Logic().WindowProperties().WindowName();
|
||||
if (!windowName.empty())
|
||||
{
|
||||
if (const auto layout = strong->Logic().GetWindowLayout())
|
||||
{
|
||||
ApplicationState::SharedInstance().SaveWorkspace(windowName, layout);
|
||||
}
|
||||
}
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
_windows.erase(it);
|
||||
try
|
||||
{
|
||||
@@ -1143,19 +1114,6 @@ LRESULT WindowEmperor::_messageHandler(HWND window, UINT const message, WPARAM c
|
||||
host->Logic().IdentifyWindow();
|
||||
}
|
||||
return 0;
|
||||
case WM_GET_WINDOW_LIST:
|
||||
{
|
||||
auto* result = reinterpret_cast<std::vector<WindowListEntry>*>(lParam);
|
||||
if (result)
|
||||
{
|
||||
for (const auto& host : _windows)
|
||||
{
|
||||
const auto props = host->Logic().WindowProperties();
|
||||
result->emplace_back(WindowListEntry{ props.WindowId(), std::wstring{ props.WindowName() } });
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
case WM_NOTIFY_FROM_NOTIFICATION_AREA:
|
||||
switch (LOWORD(lParam))
|
||||
{
|
||||
|
||||
@@ -28,16 +28,6 @@ public:
|
||||
WM_MESSAGE_BOX_CLOSED,
|
||||
WM_IDENTIFY_ALL_WINDOWS,
|
||||
WM_NOTIFY_FROM_NOTIFICATION_AREA,
|
||||
WM_GET_WINDOW_LIST,
|
||||
};
|
||||
|
||||
// Used by WM_GET_WINDOW_LIST. Callers allocate a vector on their
|
||||
// stack and pass a pointer through LPARAM; the emperor fills it in
|
||||
// synchronously via SendMessage.
|
||||
struct WindowListEntry
|
||||
{
|
||||
uint64_t Id;
|
||||
std::wstring Name;
|
||||
};
|
||||
|
||||
HWND GetMainWindow() const noexcept;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace til
|
||||
{
|
||||
namespace details
|
||||
|
||||
@@ -416,7 +416,7 @@ function Invoke-CodeFormat() {
|
||||
[switch]$IgnoreXaml
|
||||
)
|
||||
|
||||
$clangFormatPath = & 'C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe' -latest -prerelease -find "**\x64\bin\clang-format.exe"
|
||||
$clangFormatPath = & 'C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe' -latest -find "**\x64\bin\clang-format.exe"
|
||||
If ([String]::IsNullOrEmpty($clangFormatPath)) {
|
||||
Write-Error "No Visual Studio-supplied version of clang-format could be found."
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
rem run clang-format on c++ files
|
||||
|
||||
pwsh -noprofile -c "import-module %OPENCON_TOOLS%\openconsole.psm1; Invoke-CodeFormat"
|
||||
powershell -noprofile "import-module %OPENCON_TOOLS%\openconsole.psm1; Invoke-CodeFormat"
|
||||
|
||||
Reference in New Issue
Block a user