mirror of
https://github.com/microsoft/terminal.git
synced 2026-05-20 13:57:43 +00:00
Compare commits
4 Commits
dev/migrie
...
dev/cazamo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
03dfed4d54 | ||
|
|
5a45c8d7e4 | ||
|
|
76f89bff04 | ||
|
|
a7aefad0ba |
@@ -479,7 +479,6 @@
|
||||
"toggleReadOnlyMode",
|
||||
"toggleShaderEffects",
|
||||
"toggleSplitOrientation",
|
||||
"workspaces",
|
||||
"wt",
|
||||
"unbound"
|
||||
],
|
||||
@@ -2041,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"
|
||||
},
|
||||
"showWindowsButton": {
|
||||
"description": "When set to true, the workspace/windows button will be shown in the tab row.",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2478,13 +2472,6 @@
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"safeUriSchemes": {
|
||||
"description": "Specifies a list of URI schemes that are considered safe. No confirmation will be required to open URIs with these schemes.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"rendering.graphicsAPI": {
|
||||
"description": "Direct3D 11 provides a more performant and feature-rich experience, whereas Direct2D is more stable. The default option \"Automatic\" will pick the API that best fits your graphics hardware. If you experience significant issues, consider using Direct2D.",
|
||||
"type": "string",
|
||||
|
||||
@@ -938,27 +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() };
|
||||
const auto cmdline = fmt::format(FMT_COMPILE(L"-w {}"), 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)
|
||||
{
|
||||
@@ -1079,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() })
|
||||
{
|
||||
@@ -1655,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,38 +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>{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>Are you sure you want to delete the workspace "{0}"?</value>
|
||||
<comment>{0} is the workspace name. Shown in a confirmation dialog 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>
|
||||
|
||||
@@ -450,21 +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)
|
||||
{
|
||||
const auto& windowName = _WindowProperties.WindowName();
|
||||
if (!windowName.empty())
|
||||
{
|
||||
if (const auto layout = GetWindowLayout())
|
||||
{
|
||||
ApplicationState::SharedInstance().SaveWorkspace(windowName, layout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tab.Close();
|
||||
}
|
||||
|
||||
@@ -486,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();
|
||||
@@ -820,28 +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)
|
||||
{
|
||||
const auto& windowName = _WindowProperties.WindowName();
|
||||
if (!windowName.empty())
|
||||
{
|
||||
if (const auto layout = GetWindowLayout())
|
||||
{
|
||||
ApplicationState::SharedInstance().SaveWorkspace(windowName, layout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If specified, detach before closing to directly update the pane structure
|
||||
pane->Close();
|
||||
}
|
||||
|
||||
@@ -25,15 +25,6 @@ namespace winrt::TerminalApp::implementation
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
void TabRowControl::WorkspaceName(const winrt::hstring& value)
|
||||
{
|
||||
if (_WorkspaceName != value)
|
||||
{
|
||||
_WorkspaceName = value;
|
||||
PropertyChanged.raise(*this, WUX::Data::PropertyChangedEventArgs{ L"WorkspaceName" });
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Bound in the Xaml editor to the [+] button.
|
||||
// Arguments:
|
||||
|
||||
@@ -19,14 +19,6 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
til::property_changed_event PropertyChanged;
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, ShowElevationShield, PropertyChanged.raise, false);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, ShowWindowsButton, PropertyChanged.raise, true);
|
||||
|
||||
public:
|
||||
winrt::hstring WorkspaceName() const noexcept { return _WorkspaceName; }
|
||||
void WorkspaceName(const winrt::hstring& value);
|
||||
|
||||
private:
|
||||
winrt::hstring _WorkspaceName{};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,5 @@ namespace TerminalApp
|
||||
TabRowControl();
|
||||
Microsoft.UI.Xaml.Controls.TabView TabView { get; };
|
||||
Boolean ShowElevationShield;
|
||||
Boolean ShowWindowsButton;
|
||||
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,44 +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"
|
||||
Margin="4,0,0,4"
|
||||
Padding="8,0,0,0"
|
||||
VerticalAlignment="Stretch"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
Visibility="{x:Bind ShowWindowsButton, 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 ShowWindowsButton theme setting.
|
||||
if (const auto theme = _settings.GlobalSettings().CurrentTheme())
|
||||
{
|
||||
_tabRow.ShowWindowsButton(theme.Window() ? theme.Window().ShowWindowsButton() : 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:
|
||||
@@ -3372,15 +3307,13 @@ namespace winrt::TerminalApp::implementation
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TerminalPage::_IsUriConsideredSomewhatSafe(const winrt::Windows::Foundation::Uri& parsedUri) const
|
||||
bool TerminalPage::_IsUriConsideredSomewhatSafe(const winrt::Windows::Foundation::Uri& parsedUri)
|
||||
{
|
||||
const auto& schemeName = parsedUri.SchemeName();
|
||||
|
||||
if (schemeName == L"http" || schemeName == L"https")
|
||||
if (parsedUri.SchemeName() == L"http" || parsedUri.SchemeName() == L"https")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (schemeName == L"file")
|
||||
if (parsedUri.SchemeName() == L"file")
|
||||
{
|
||||
static const auto pathext{ wil::TryGetEnvironmentVariableW<std::wstring>(L"PATHEXT") };
|
||||
const auto filename = parsedUri.Path();
|
||||
@@ -3394,16 +3327,6 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
return true;
|
||||
}
|
||||
if (const auto& safeSchemes = _settings.GlobalSettings().SafeUriSchemes())
|
||||
{
|
||||
for (const auto& scheme : safeSchemes)
|
||||
{
|
||||
if (til::equals_insensitive_ascii(schemeName, scheme))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -4122,12 +4045,6 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
_tabRow.ShowElevationShield(IsRunningElevated() && _settings.GlobalSettings().ShowAdminShield());
|
||||
|
||||
// Apply the ShowWindowsButton theme setting.
|
||||
if (const auto theme = _settings.GlobalSettings().CurrentTheme())
|
||||
{
|
||||
_tabRow.ShowWindowsButton(theme.Window() ? theme.Window().ShowWindowsButton() : true);
|
||||
}
|
||||
|
||||
Media::SolidColorBrush transparent{ Windows::UI::Colors::Transparent() };
|
||||
_tabView.Background(transparent);
|
||||
|
||||
@@ -5768,199 +5685,6 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
// Rebuild the workspace flyout contents. Called every time the flyout opens
|
||||
// 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.count(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"));
|
||||
|
||||
WUX::Controls::FontIcon trashIcon{};
|
||||
trashIcon.Glyph(L"\xE74D"); // Delete glyph
|
||||
trashIcon.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
|
||||
deleteItem.Icon(trashIcon);
|
||||
|
||||
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.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)
|
||||
@@ -5970,10 +5694,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);
|
||||
|
||||
@@ -475,7 +438,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
safe_void_coroutine _OpenHyperlinkHandler(const IInspectable sender, const Microsoft::Terminal::Control::OpenHyperlinkEventArgs eventArgs);
|
||||
static bool _IsUriSupported(const winrt::Windows::Foundation::Uri& parsedUri);
|
||||
bool _IsUriConsideredSomewhatSafe(const winrt::Windows::Foundation::Uri& parsedUri) const;
|
||||
static bool _IsUriConsideredSomewhatSafe(const winrt::Windows::Foundation::Uri& parsedUri);
|
||||
|
||||
void _ShowCouldNotOpenDialog(winrt::hstring reason, winrt::hstring uri);
|
||||
bool _CopyText(bool dismissSelection, bool singleLine, bool withControlSequences, Microsoft::Terminal::Control::CopyFormat formats);
|
||||
@@ -614,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);
|
||||
@@ -641,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()
|
||||
{
|
||||
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();
|
||||
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);
|
||||
|
||||
@@ -98,6 +98,7 @@ void Terminal::UpdateSettings(ICoreSettings settings)
|
||||
_answerbackMessage = settings.AnswerbackMessage();
|
||||
_wordDelimiters = settings.WordDelimiters();
|
||||
_suppressApplicationTitle = settings.SuppressApplicationTitle();
|
||||
_startingTitle = settings.StartingTitle();
|
||||
_trimBlockSelection = settings.TrimBlockSelection();
|
||||
_autoMarkPrompts = settings.AutoMarkPrompts();
|
||||
_rainbowSuggestions = settings.RainbowSuggestions();
|
||||
@@ -123,11 +124,6 @@ void Terminal::UpdateSettings(ICoreSettings settings)
|
||||
// Save the changes made above and in UpdateAppearance as the new default render settings.
|
||||
GetRenderSettings().SaveDefaultSettings();
|
||||
|
||||
if (!_startingTitle)
|
||||
{
|
||||
_startingTitle = settings.StartingTitle();
|
||||
}
|
||||
|
||||
if (!_startingTabColor && settings.StartingTabColor())
|
||||
{
|
||||
_startingTabColor = settings.StartingTabColor().Value();
|
||||
|
||||
@@ -349,7 +349,7 @@ private:
|
||||
::Microsoft::Console::VirtualTerminal::TerminalInput _terminalInput;
|
||||
|
||||
std::optional<std::wstring> _title;
|
||||
std::optional<std::wstring> _startingTitle;
|
||||
std::wstring _startingTitle;
|
||||
std::optional<til::color> _startingTabColor;
|
||||
|
||||
std::vector<til::point_span> _searchHighlights;
|
||||
|
||||
@@ -91,12 +91,8 @@ void Terminal::SetWindowTitle(const std::wstring_view title)
|
||||
_assertLocked();
|
||||
if (!_suppressApplicationTitle)
|
||||
{
|
||||
_title.reset();
|
||||
if (!title.empty())
|
||||
{
|
||||
_title.emplace(title);
|
||||
}
|
||||
_pfnTitleChanged(GetConsoleTitle());
|
||||
_title.emplace(title.empty() ? _startingTitle : title);
|
||||
_pfnTitleChanged(_title.value());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,13 +112,6 @@ bool Terminal::ResizeWindow(const til::CoordType width, const til::CoordType hei
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto currentDimensions = _GetMutableViewport().Dimensions();
|
||||
|
||||
if (width == currentDimensions.width && height == currentDimensions.height)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_pfnWindowSizeChanged)
|
||||
{
|
||||
_pfnWindowSizeChanged(width, height);
|
||||
|
||||
@@ -184,18 +184,11 @@ void Terminal::SelectNewRegion(const til::point coordStart, const til::point coo
|
||||
std::wstring_view Terminal::GetConsoleTitle() const noexcept
|
||||
{
|
||||
_assertLocked();
|
||||
|
||||
if (_title)
|
||||
if (_title.has_value())
|
||||
{
|
||||
return *_title;
|
||||
}
|
||||
|
||||
if (_startingTitle)
|
||||
{
|
||||
return *_startingTitle;
|
||||
}
|
||||
|
||||
return {};
|
||||
return _startingTitle;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
#include "LibraryResources.h"
|
||||
#include "../TerminalSettingsModel/AllShortcutActions.h"
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Controls;
|
||||
using namespace winrt::Windows::UI::Xaml::Navigation;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
@@ -42,4 +44,65 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
}
|
||||
|
||||
// Builds the "view all" flyout lazily on the first click of a
|
||||
// row's "..." button, then caches it on the button so subsequent clicks
|
||||
// just re-show it.
|
||||
void Actions::ViewAllKeyChordsButton_Click(const IInspectable& sender, const RoutedEventArgs& /*e*/)
|
||||
{
|
||||
const auto button = sender.try_as<Button>();
|
||||
if (!button)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Retrieve cached flyout, if possible
|
||||
if (const auto existing = button.Flyout())
|
||||
{
|
||||
existing.ShowAt(button);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto cmdVM = button.DataContext().try_as<Editor::CommandViewModel>();
|
||||
if (!cmdVM)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Flyout flyout;
|
||||
flyout.Placement(Primitives::FlyoutPlacementMode::Bottom);
|
||||
flyout.FlyoutPresenterStyle(Resources().Lookup(box_value(L"EdgeToEdgeFlyoutPresenterStyle")).as<winrt::Windows::UI::Xaml::Style>());
|
||||
|
||||
StackPanel content;
|
||||
content.Orientation(Orientation::Vertical);
|
||||
content.MinWidth(120.0);
|
||||
|
||||
if (cmdVM.HasNoKeyChords())
|
||||
{
|
||||
const auto emptyTemplate = Resources().Lookup(box_value(L"ViewAllKeyChordsFlyoutEmptyStateTemplate")).as<DataTemplate>();
|
||||
content.Children().Append(emptyTemplate.LoadContent().as<UIElement>());
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto separatorTemplate = Resources().Lookup(box_value(L"ViewAllKeyChordsFlyoutSeparatorTemplate")).as<DataTemplate>();
|
||||
const auto itemTemplate = Resources().Lookup(box_value(L"ViewAllKeyChordsFlyoutItemTemplate")).as<DataTemplate>();
|
||||
const auto chords = cmdVM.KeyChordList();
|
||||
const auto count = chords.Size();
|
||||
for (uint32_t i = 0; i < count; ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
content.Children().Append(separatorTemplate.LoadContent().as<UIElement>());
|
||||
}
|
||||
|
||||
auto chordVisual = itemTemplate.LoadContent().as<Editor::KeyChordVisual>();
|
||||
chordVisual.KeyChord(chords.GetAt(i).CurrentKeys());
|
||||
content.Children().Append(chordVisual);
|
||||
}
|
||||
}
|
||||
|
||||
flyout.Content(content);
|
||||
button.Flyout(flyout);
|
||||
flyout.ShowAt(button);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
void OnNavigatedTo(const winrt::Windows::UI::Xaml::Navigation::NavigationEventArgs& e);
|
||||
|
||||
void ViewAllKeyChordsButton_Click(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& e);
|
||||
|
||||
til::property_changed_event PropertyChanged;
|
||||
WINRT_OBSERVABLE_PROPERTY(Editor::ActionsViewModel, ViewModel, PropertyChanged.raise, nullptr);
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:mtu="using:Microsoft.Terminal.UI"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Page.Resources>
|
||||
@@ -17,182 +16,116 @@
|
||||
<ResourceDictionary Source="CommonResources.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<!-- Theme Dictionary -->
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<!-- TextBox colors ! -->
|
||||
<SolidColorBrush x:Key="TextControlBackground"
|
||||
Color="#333333" />
|
||||
<SolidColorBrush x:Key="TextBoxPlaceholderTextThemeBrush"
|
||||
Color="#B5B5B5" />
|
||||
<SolidColorBrush x:Key="TextControlForeground"
|
||||
Color="#B5B5B5" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrush"
|
||||
Color="#404040" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForeground"
|
||||
Color="#B5B5B5" />
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundPointerOver"
|
||||
Color="#404040" />
|
||||
<SolidColorBrush x:Key="TextControlForegroundPointerOver"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushPointerOver"
|
||||
Color="#404040" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPointerOver"
|
||||
Color="#FF4343" />
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundFocused"
|
||||
Color="#333333" />
|
||||
<SolidColorBrush x:Key="TextControlForegroundFocused"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushFocused"
|
||||
Color="#404040" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPressed"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="TextControlButtonBackgroundPressed"
|
||||
Color="#FF4343" />
|
||||
|
||||
<!-- KeyChordText styles -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="{StaticResource ControlCornerRadius}" />
|
||||
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<!-- TextBox colors ! -->
|
||||
<SolidColorBrush x:Key="TextControlBackground"
|
||||
Color="#CCCCCC" />
|
||||
<SolidColorBrush x:Key="TextBoxPlaceholderTextThemeBrush"
|
||||
Color="#636363" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrush"
|
||||
Color="#636363" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForeground"
|
||||
Color="#636363" />
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundPointerOver"
|
||||
Color="#DADADA" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushPointerOver"
|
||||
Color="#636363" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPointerOver"
|
||||
Color="#FF4343" />
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundFocused"
|
||||
Color="#CCCCCC" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushFocused"
|
||||
Color="#636363" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPressed"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="TextControlButtonBackgroundPressed"
|
||||
Color="#FF4343" />
|
||||
|
||||
<!-- KeyChordText styles -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="{StaticResource ControlCornerRadius}" />
|
||||
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
|
||||
<!-- KeyChordText styles (use XAML defaults for High Contrast theme) -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Border" />
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock" />
|
||||
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
<!-- Styles -->
|
||||
<Style x:Key="KeyBindingContainerStyle"
|
||||
<Style x:Key="ActionRowItemContainerStyle"
|
||||
BasedOn="{StaticResource DefaultListViewItemStyle}"
|
||||
TargetType="ListViewItem">
|
||||
<Setter Property="Padding" Value="12,4,4,4" />
|
||||
<Setter Property="Padding" Value="{StaticResource SettingsCardPadding}" />
|
||||
<Setter Property="MinHeight" Value="{StaticResource SettingsCardMinHeight}" />
|
||||
<Setter Property="Margin" Value="{StaticResource SettingsCardItemMargin}" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="XYFocusKeyboardNavigation" Value="Enabled" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource ExpanderHeaderBorderBrush}" />
|
||||
<Setter Property="BorderThickness" Value="{ThemeResource ExpanderHeaderBorderThickness}" />
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
</Style>
|
||||
<Style x:Key="KeyBindingNameTextBlockStyle"
|
||||
|
||||
<Style x:Key="ActionRowNameTextStyle"
|
||||
BasedOn="{StaticResource BaseTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="FontWeight" Value="Normal" />
|
||||
<Setter Property="TextWrapping" Value="WrapWholeWords" />
|
||||
</Style>
|
||||
<Style x:Key="KeyChordEditorStyle"
|
||||
TargetType="local:KeyChordListener">
|
||||
<Setter Property="HorizontalAlignment" Value="Right" />
|
||||
|
||||
<Style x:Key="ActionRowSubtleButtonStyle"
|
||||
BasedOn="{StaticResource DefaultButtonStyle}"
|
||||
TargetType="Button">
|
||||
<Setter Property="MinWidth" Value="32" />
|
||||
<Setter Property="Width" Value="32" />
|
||||
<Setter Property="Height" Value="32" />
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="BorderBrush" Value="Transparent" />
|
||||
</Style>
|
||||
|
||||
<!-- Converters & Misc. -->
|
||||
<SolidColorBrush x:Key="ActionContainerBackgroundEditing"
|
||||
Color="{ThemeResource SystemListMediumColor}" />
|
||||
<SolidColorBrush x:Key="ActionContainerBackground"
|
||||
Color="Transparent" />
|
||||
<!--
|
||||
FlyoutPresenter style with no internal padding so a full-width Border
|
||||
separator inside the flyout can reach the flyout's left/right edges.
|
||||
-->
|
||||
<Style x:Key="EdgeToEdgeFlyoutPresenterStyle"
|
||||
BasedOn="{StaticResource DefaultFlyoutPresenterStyle}"
|
||||
TargetType="FlyoutPresenter">
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled" />
|
||||
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
|
||||
</Style>
|
||||
|
||||
<!-- Templates -->
|
||||
<DataTemplate x:Key="ViewAllKeyChordsFlyoutSeparatorTemplate">
|
||||
<Border Height="1"
|
||||
Margin="0,4,0,4"
|
||||
Background="{ThemeResource DividerStrokeColorDefaultBrush}" />
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="ViewAllKeyChordsFlyoutEmptyStateTemplate">
|
||||
<TextBlock x:Uid="Actions_NoKeyBindings"
|
||||
Margin="12,8,12,8"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource SecondaryTextBlockStyle}" />
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="ViewAllKeyChordsFlyoutItemTemplate">
|
||||
<local:KeyChordVisual Margin="{ThemeResource MenuFlyoutItemThemePaddingNarrow}"
|
||||
HorizontalAlignment="Right" />
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="CommandTemplate"
|
||||
x:DataType="local:CommandViewModel">
|
||||
<ListViewItem AutomationProperties.Name="{x:Bind DisplayNameAndKeyChordAutomationPropName, Mode=OneWay}"
|
||||
Style="{StaticResource KeyBindingContainerStyle}">
|
||||
<Grid ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<!-- command name -->
|
||||
<ColumnDefinition Width="*" />
|
||||
<!-- key chord -->
|
||||
<ColumnDefinition Width="auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid AutomationProperties.Name="{x:Bind DisplayNameAndKeyChordAutomationPropName, Mode=OneWay}"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<!-- command name -->
|
||||
<ColumnDefinition Width="*" />
|
||||
<!-- key chord -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- edit button -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- "..." button -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Command Name -->
|
||||
<TextBlock Grid.Column="0"
|
||||
FontWeight="Normal"
|
||||
Style="{StaticResource KeyBindingNameTextBlockStyle}"
|
||||
Text="{x:Bind DisplayName, Mode=OneWay}" />
|
||||
<!-- Key Chord Text -->
|
||||
<Grid Grid.Column="1"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
ColumnSpacing="4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border Grid.Column="0"
|
||||
Padding="8,4,8,4"
|
||||
Style="{ThemeResource KeyChordBorderStyle}"
|
||||
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(FirstKeyChordText)}">
|
||||
<TextBlock FontSize="14"
|
||||
Style="{ThemeResource KeyChordTextBlockStyle}"
|
||||
Text="{x:Bind FirstKeyChordText, Mode=OneWay}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
</Border>
|
||||
<Border Grid.Column="1"
|
||||
Padding="8,4,8,4"
|
||||
Style="{ThemeResource KeyChordBorderStyle}"
|
||||
ToolTipService.ToolTip="{x:Bind AdditionalKeyChordTooltipText, Mode=OneWay}"
|
||||
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(AdditionalKeyChordCountText)}">
|
||||
<TextBlock FontSize="14"
|
||||
Style="{ThemeResource KeyChordTextBlockStyle}"
|
||||
Text="{x:Bind AdditionalKeyChordCountText, Mode=OneWay}" />
|
||||
</Border>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ListViewItem>
|
||||
<!-- Command Name -->
|
||||
<TextBlock Grid.Column="0"
|
||||
Style="{StaticResource ActionRowNameTextStyle}"
|
||||
Text="{x:Bind DisplayName, Mode=OneWay}" />
|
||||
|
||||
<!-- Key Chord -->
|
||||
<local:KeyChordVisual Grid.Column="1"
|
||||
HorizontalAlignment="Right"
|
||||
KeyChord="{x:Bind FirstKeyChord, Mode=OneWay}" />
|
||||
|
||||
<!-- Edit button -->
|
||||
<Button x:Uid="Actions_EditButton"
|
||||
Grid.Column="2"
|
||||
AutomationProperties.Name="{x:Bind DisplayName, Mode=OneWay}"
|
||||
Click="{x:Bind Edit_Click}"
|
||||
Style="{StaticResource ActionRowSubtleButtonStyle}">
|
||||
<FontIcon FontSize="14"
|
||||
Glyph="" />
|
||||
</Button>
|
||||
|
||||
<!-- "..." button + flyout -->
|
||||
<Button x:Uid="Actions_ViewAllKeyChordsButton"
|
||||
Grid.Column="3"
|
||||
Click="ViewAllKeyChordsButton_Click"
|
||||
Style="{StaticResource ActionRowSubtleButtonStyle}">
|
||||
<FontIcon FontSize="14"
|
||||
Glyph="" />
|
||||
</Button>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
||||
</Page.Resources>
|
||||
@@ -208,7 +141,8 @@
|
||||
<!-- Add New Button -->
|
||||
<Button x:Name="AddNewButton"
|
||||
Margin="0,12,0,0"
|
||||
Click="{x:Bind ViewModel.AddNewCommand}">
|
||||
Click="{x:Bind ViewModel.AddNewCommand}"
|
||||
Style="{StaticResource AccentButtonStyle}">
|
||||
<Button.Content>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
@@ -221,11 +155,42 @@
|
||||
|
||||
<!-- Commands -->
|
||||
<ListView x:Name="CommandsListView"
|
||||
Margin="-8,0,0,0"
|
||||
IsItemClickEnabled="True"
|
||||
ItemClick="{x:Bind ViewModel.CmdListItemClicked}"
|
||||
ItemContainerStyle="{StaticResource ActionRowItemContainerStyle}"
|
||||
ItemTemplate="{StaticResource CommandTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.CommandList, Mode=OneWay}" />
|
||||
ItemsSource="{x:Bind ViewModel.CommandList, Mode=OneWay}"
|
||||
SelectionMode="None">
|
||||
<!--
|
||||
The framework ListViewItemPresenter reads its per-state backgrounds
|
||||
from these theme resources (not from ListViewItem.Background), so we
|
||||
override them here to match the card chrome on ActionRowItemContainerStyle.
|
||||
-->
|
||||
<ListView.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Default">
|
||||
<StaticResource x:Key="ListViewItemBackground"
|
||||
ResourceKey="ExpanderHeaderBackground" />
|
||||
<StaticResource x:Key="ListViewItemBackgroundPointerOver"
|
||||
ResourceKey="ControlFillColorSecondaryBrush" />
|
||||
<StaticResource x:Key="ListViewItemBackgroundPressed"
|
||||
ResourceKey="ControlFillColorTertiaryBrush" />
|
||||
<StaticResource x:Key="ListViewItemBackgroundSelected"
|
||||
ResourceKey="ExpanderHeaderBackground" />
|
||||
<StaticResource x:Key="ListViewItemBackgroundSelectedPointerOver"
|
||||
ResourceKey="ControlFillColorSecondaryBrush" />
|
||||
<StaticResource x:Key="ListViewItemBackgroundSelectedPressed"
|
||||
ResourceKey="ControlFillColorTertiaryBrush" />
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<StaticResource x:Key="ListViewItemBackground"
|
||||
ResourceKey="SystemColorButtonFaceColorBrush" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
</ResourceDictionary>
|
||||
</ListView.Resources>
|
||||
</ListView>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Page>
|
||||
|
||||
@@ -57,13 +57,22 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return;
|
||||
}
|
||||
std::vector<Editor::KeyChordViewModel> keyChordVMs;
|
||||
int32_t idx = 1;
|
||||
for (const auto keys : _keyChordList)
|
||||
{
|
||||
auto kcVM{ make<KeyChordViewModel>(keys) };
|
||||
_RegisterKeyChordVMEvents(kcVM);
|
||||
keyChordVMs.push_back(kcVM);
|
||||
auto kcVM{ make_self<KeyChordViewModel>(keys) };
|
||||
kcVM->Index(idx++);
|
||||
_RegisterKeyChordVMEvents(*kcVM);
|
||||
keyChordVMs.push_back(*kcVM);
|
||||
}
|
||||
_KeyChordList = single_threaded_observable_vector(std::move(keyChordVMs));
|
||||
_KeyChordList.VectorChanged([weakThis{ get_weak() }](const auto& /*sender*/, const auto& /*args*/) {
|
||||
if (auto self{ weakThis.get() })
|
||||
{
|
||||
self->_ReindexKeyChordList();
|
||||
self->_NotifyChanges(L"FirstKeyChord", L"FirstKeyChordText", L"AdditionalKeyChordCountText", L"AdditionalKeyChordTooltipText", L"DisplayNameAndKeyChordAutomationPropName");
|
||||
}
|
||||
});
|
||||
|
||||
std::vector<hstring> shortcutActions;
|
||||
for (const auto [action, name] : _availableActionsAndNamesMap)
|
||||
@@ -119,7 +128,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return _cachedDisplayName;
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::Name()
|
||||
winrt::hstring CommandViewModel::Name() const noexcept
|
||||
{
|
||||
return _command.HasName() ? _command.Name() : L"";
|
||||
}
|
||||
@@ -145,7 +154,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return result;
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::FirstKeyChordText()
|
||||
winrt::hstring CommandViewModel::FirstKeyChordText() const
|
||||
{
|
||||
if (_KeyChordList.Size() != 0)
|
||||
{
|
||||
@@ -154,7 +163,21 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return L"";
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::AdditionalKeyChordCountText()
|
||||
Control::KeyChord CommandViewModel::FirstKeyChord() const noexcept
|
||||
{
|
||||
if (_KeyChordList.Size() != 0)
|
||||
{
|
||||
return _KeyChordList.GetAt(0).CurrentKeys();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool CommandViewModel::HasNoKeyChords() const noexcept
|
||||
{
|
||||
return _KeyChordList.Size() == 0;
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::AdditionalKeyChordCountText() const
|
||||
{
|
||||
const auto size = _KeyChordList.Size();
|
||||
if (size > 1)
|
||||
@@ -164,7 +187,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return L"";
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::AdditionalKeyChordTooltipText()
|
||||
winrt::hstring CommandViewModel::AdditionalKeyChordTooltipText() const
|
||||
{
|
||||
const auto size = _KeyChordList.Size();
|
||||
if (size <= 1)
|
||||
@@ -183,12 +206,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return winrt::hstring{ result };
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::ID()
|
||||
winrt::hstring CommandViewModel::ID() const noexcept
|
||||
{
|
||||
return _command.ID();
|
||||
}
|
||||
|
||||
bool CommandViewModel::IsUserAction()
|
||||
bool CommandViewModel::IsUserAction() const noexcept
|
||||
{
|
||||
return _command.Origin() == OriginTag::User;
|
||||
}
|
||||
@@ -206,23 +229,40 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
void CommandViewModel::AddKeybinding_Click()
|
||||
{
|
||||
auto kbdVM{ make_self<KeyChordViewModel>(nullptr) };
|
||||
kbdVM->Index(gsl::narrow_cast<int32_t>(_KeyChordList.Size()) + 1);
|
||||
kbdVM->IsInEditMode(true);
|
||||
_RegisterKeyChordVMEvents(*kbdVM);
|
||||
KeyChordList().Append(*kbdVM);
|
||||
FocusContainer.raise(*this, *kbdVM);
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::ActionNameTextBoxAutomationPropName()
|
||||
// Reassigns 1-based Index values for every KeyChordViewModel in the list. Called
|
||||
// whenever the list changes shape so the per-row "Key Binding #N" label stays in sync.
|
||||
void CommandViewModel::_ReindexKeyChordList()
|
||||
{
|
||||
const auto size = _KeyChordList.Size();
|
||||
for (uint32_t i = 0; i < size; ++i)
|
||||
{
|
||||
auto kcVM{ _KeyChordList.GetAt(i) };
|
||||
const auto newIdx = gsl::narrow_cast<int32_t>(i) + 1;
|
||||
if (kcVM.Index() != newIdx)
|
||||
{
|
||||
kcVM.Index(newIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::ActionNameTextBoxAutomationPropName() const
|
||||
{
|
||||
return RS_(L"Actions_Name/Text");
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::ShortcutActionComboBoxAutomationPropName()
|
||||
winrt::hstring CommandViewModel::ShortcutActionComboBoxAutomationPropName() const
|
||||
{
|
||||
return RS_(L"Actions_ShortcutAction/Text");
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::AdditionalArgumentsControlAutomationPropName()
|
||||
winrt::hstring CommandViewModel::AdditionalArgumentsControlAutomationPropName() const
|
||||
{
|
||||
return RS_(L"Actions_Arguments/Text");
|
||||
}
|
||||
@@ -273,6 +313,19 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
self->FocusContainer.raise(*self, senderVM);
|
||||
}
|
||||
}
|
||||
else if (propertyName == L"KeyChordText")
|
||||
{
|
||||
// The first chord of the list is what the row visual on the Actions page binds to,
|
||||
// so propagate the change up so the row updates.
|
||||
if (self->_KeyChordList.Size() > 0 && self->_KeyChordList.GetAt(0) == senderVM)
|
||||
{
|
||||
self->_NotifyChanges(L"FirstKeyChord", L"FirstKeyChordText", L"DisplayNameAndKeyChordAutomationPropName");
|
||||
}
|
||||
else
|
||||
{
|
||||
self->_NotifyChanges(L"AdditionalKeyChordTooltipText");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1065,12 +1118,21 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
KeyChordViewModel::KeyChordViewModel(Control::KeyChord currentKeys)
|
||||
{
|
||||
CurrentKeys(currentKeys);
|
||||
|
||||
// DisplayLabel is derived from Index, so re-fire the change for it whenever Index changes.
|
||||
PropertyChanged([this](const auto& /*sender*/, const Windows::UI::Xaml::Data::PropertyChangedEventArgs& args) {
|
||||
if (args.PropertyName() == L"Index")
|
||||
{
|
||||
_NotifyChanges(L"DisplayLabel");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void KeyChordViewModel::CurrentKeys(const Control::KeyChord& newKeys)
|
||||
{
|
||||
_currentKeys = newKeys;
|
||||
KeyChordText(Model::KeyChordSerialization::ToString(_currentKeys));
|
||||
_NotifyChanges(L"CurrentKeys");
|
||||
}
|
||||
|
||||
Control::KeyChord KeyChordViewModel::CurrentKeys() const noexcept
|
||||
@@ -1126,6 +1188,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
hstring KeyChordViewModel::CancelButtonName() const noexcept { return RS_(L"Actions_CancelButton/[using:Windows.UI.Xaml.Controls]ToolTipService/ToolTip"); }
|
||||
hstring KeyChordViewModel::AcceptButtonName() const noexcept { return RS_(L"Actions_AcceptButton/[using:Windows.UI.Xaml.Controls]ToolTipService/ToolTip"); }
|
||||
hstring KeyChordViewModel::DeleteButtonName() const noexcept { return RS_(L"Actions_DeleteButton/[using:Windows.UI.Xaml.Controls]ToolTipService/ToolTip"); }
|
||||
hstring KeyChordViewModel::EditButtonName() const noexcept { return RS_(L"Actions_EditButton/[using:Windows.UI.Xaml.Controls]ToolTipService/ToolTip"); }
|
||||
|
||||
winrt::hstring KeyChordViewModel::DisplayLabel() const
|
||||
{
|
||||
return hstring{ RS_fmt(L"EditAction_KeyBindingNumberFormat", _Index) };
|
||||
}
|
||||
|
||||
ActionsViewModel::ActionsViewModel(Model::CascadiaSettings settings) :
|
||||
_Settings{ settings }
|
||||
|
||||
@@ -69,16 +69,18 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
void Initialize();
|
||||
|
||||
winrt::hstring DisplayName();
|
||||
winrt::hstring Name();
|
||||
winrt::hstring Name() const noexcept;
|
||||
void Name(const winrt::hstring& newName);
|
||||
winrt::hstring DisplayNameAndKeyChordAutomationPropName();
|
||||
|
||||
winrt::hstring FirstKeyChordText();
|
||||
winrt::hstring AdditionalKeyChordCountText();
|
||||
winrt::hstring AdditionalKeyChordTooltipText();
|
||||
winrt::hstring FirstKeyChordText() const;
|
||||
Control::KeyChord FirstKeyChord() const noexcept;
|
||||
bool HasNoKeyChords() const noexcept;
|
||||
winrt::hstring AdditionalKeyChordCountText() const;
|
||||
winrt::hstring AdditionalKeyChordTooltipText() const;
|
||||
|
||||
winrt::hstring ID();
|
||||
bool IsUserAction();
|
||||
winrt::hstring ID() const noexcept;
|
||||
bool IsUserAction() const noexcept;
|
||||
|
||||
void Edit_Click();
|
||||
til::typed_event<Editor::CommandViewModel, IInspectable> EditRequested;
|
||||
@@ -89,9 +91,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
void AddKeybinding_Click();
|
||||
|
||||
// UIA text
|
||||
winrt::hstring ActionNameTextBoxAutomationPropName();
|
||||
winrt::hstring ShortcutActionComboBoxAutomationPropName();
|
||||
winrt::hstring AdditionalArgumentsControlAutomationPropName();
|
||||
winrt::hstring ActionNameTextBoxAutomationPropName() const;
|
||||
winrt::hstring ShortcutActionComboBoxAutomationPropName() const;
|
||||
winrt::hstring AdditionalArgumentsControlAutomationPropName() const;
|
||||
|
||||
til::typed_event<IInspectable, Editor::ArgWrapper> PropagateColorSchemeRequested;
|
||||
til::typed_event<IInspectable, Editor::ArgWrapper> PropagateColorSchemeNamesRequested;
|
||||
@@ -115,6 +117,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
void _RegisterActionArgsVMEvents(Editor::ActionArgsViewModel actionArgsVM);
|
||||
void _ReplaceCommandWithUserCopy(bool reinitialize);
|
||||
void _CreateAndInitializeActionArgsVMHelper();
|
||||
void _ReindexKeyChordList();
|
||||
};
|
||||
|
||||
struct ArgWrapper : ArgWrapperT<ArgWrapper>, ViewModelHelper<ArgWrapper>
|
||||
@@ -230,15 +233,19 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
void CancelChanges();
|
||||
void DeleteKeyChord();
|
||||
|
||||
winrt::hstring DisplayLabel() const;
|
||||
|
||||
// UIA Text
|
||||
hstring CancelButtonName() const noexcept;
|
||||
hstring AcceptButtonName() const noexcept;
|
||||
hstring DeleteButtonName() const noexcept;
|
||||
hstring EditButtonName() const noexcept;
|
||||
|
||||
VIEW_MODEL_OBSERVABLE_PROPERTY(bool, IsInEditMode, false);
|
||||
VIEW_MODEL_OBSERVABLE_PROPERTY(Control::KeyChord, ProposedKeys);
|
||||
VIEW_MODEL_OBSERVABLE_PROPERTY(winrt::hstring, KeyChordText);
|
||||
VIEW_MODEL_OBSERVABLE_PROPERTY(Windows::UI::Xaml::Controls::Flyout, AcceptChangesFlyout, nullptr);
|
||||
VIEW_MODEL_OBSERVABLE_PROPERTY(int32_t, Index, 0);
|
||||
|
||||
public:
|
||||
til::typed_event<Editor::KeyChordViewModel, Terminal::Control::KeyChord> AddKeyChordRequested;
|
||||
|
||||
@@ -55,6 +55,8 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
// View-model specific
|
||||
String DisplayName { get; };
|
||||
String FirstKeyChordText { get; };
|
||||
Microsoft.Terminal.Control.KeyChord FirstKeyChord { get; };
|
||||
Boolean HasNoKeyChords { get; };
|
||||
String AdditionalKeyChordCountText { get; };
|
||||
String AdditionalKeyChordTooltipText { get; };
|
||||
String DisplayNameAndKeyChordAutomationPropName { get; };
|
||||
@@ -138,9 +140,12 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
String KeyChordText { get; };
|
||||
|
||||
// UI side
|
||||
Microsoft.Terminal.Control.KeyChord CurrentKeys { get; };
|
||||
Microsoft.Terminal.Control.KeyChord ProposedKeys;
|
||||
Windows.UI.Xaml.Controls.Flyout AcceptChangesFlyout;
|
||||
Boolean IsInEditMode { get; };
|
||||
Int32 Index;
|
||||
String DisplayLabel { get; };
|
||||
void ToggleEditMode();
|
||||
void AcceptChanges();
|
||||
void CancelChanges();
|
||||
@@ -148,6 +153,7 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
String CancelButtonName { get; };
|
||||
String AcceptButtonName { get; };
|
||||
String DeleteButtonName { get; };
|
||||
String EditButtonName { get; };
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<KeyChordViewModel, Microsoft.Terminal.Control.KeyChord> AddKeyChordRequested;
|
||||
event Windows.Foundation.TypedEventHandler<KeyChordViewModel, ModifyKeyChordEventArgs> ModifyKeyChordRequested;
|
||||
|
||||
@@ -17,130 +17,11 @@
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="CommonResources.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
<!-- Theme Dictionary -->
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<!-- KeyChordText styles -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Button">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="1" />
|
||||
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
<!-- Override visual states -->
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Grid>
|
||||
<!-- Define the appearance of the button -->
|
||||
<Border x:Name="border"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}">
|
||||
<ContentPresenter HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</Border>
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="PointerOver">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="border"
|
||||
Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SystemControlHighlightAccentRevealBackgroundBrush}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Pressed" />
|
||||
<VisualState x:Name="Disabled" />
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<!-- KeyChordText styles -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Button">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="1" />
|
||||
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
<!-- Override visual states -->
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Grid>
|
||||
<!-- Define the appearance of the button -->
|
||||
<Border x:Name="border"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}">
|
||||
<ContentPresenter HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</Border>
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="PointerOver">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="border"
|
||||
Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SystemControlHighlightAccentRevealBackgroundBrush}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Pressed" />
|
||||
<VisualState x:Name="Disabled" />
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<!-- KeyChordText styles (use XAML defaults for High Contrast theme) -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Button" />
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
<GridLength x:Key="ArgumentNameWidth">148</GridLength>
|
||||
|
||||
<!-- Styles -->
|
||||
<Style x:Key="KeyBindingContainerStyle"
|
||||
BasedOn="{StaticResource DefaultListViewItemStyle}"
|
||||
TargetType="ListViewItem">
|
||||
<Setter Property="Padding" Value="4" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="XYFocusKeyboardNavigation" Value="Enabled" />
|
||||
</Style>
|
||||
<Style x:Key="KeyChordEditorStyle"
|
||||
TargetType="local:KeyChordListener">
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
</Style>
|
||||
<x:Int32 x:Key="EditButtonSize">32</x:Int32>
|
||||
<x:Double x:Key="EditButtonIconSize">14</x:Double>
|
||||
|
||||
<Style x:Key="EditButtonStyle"
|
||||
BasedOn="{StaticResource DefaultButtonStyle}"
|
||||
TargetType="Button">
|
||||
@@ -149,6 +30,7 @@
|
||||
<Setter Property="Height" Value="{StaticResource EditButtonSize}" />
|
||||
<Setter Property="Width" Value="{StaticResource EditButtonSize}" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="AccentEditButtonStyle"
|
||||
BasedOn="{StaticResource AccentButtonStyle}"
|
||||
TargetType="Button">
|
||||
@@ -157,42 +39,63 @@
|
||||
<Setter Property="Height" Value="{StaticResource EditButtonSize}" />
|
||||
<Setter Property="Width" Value="{StaticResource EditButtonSize}" />
|
||||
</Style>
|
||||
<Style x:Key="TextBlockGroupingStyle"
|
||||
BasedOn="{StaticResource BodyStrongTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="MaxWidth" Value="{StaticResource StandardControlMaxWidth}" />
|
||||
<Setter Property="Margin" Value="0,0,0,4" />
|
||||
<Setter Property="FontSize" Value="16" />
|
||||
|
||||
<Style x:Key="KeyChordEditorStyle"
|
||||
TargetType="local:KeyChordListener">
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="MinWidth" Value="160" />
|
||||
</Style>
|
||||
|
||||
<!-- Templates -->
|
||||
<!--
|
||||
Item container for the per-chord ListView. We're hosting a SettingContainer
|
||||
inside each item, so strip the default ListViewItem visuals (padding, border,
|
||||
hover/selection background) so they don't double up.
|
||||
-->
|
||||
<Style x:Key="KeyChordListViewItemStyle"
|
||||
BasedOn="{StaticResource DefaultListViewItemStyle}"
|
||||
TargetType="ListViewItem">
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="Margin" Value="0" />
|
||||
<Setter Property="MinHeight" Value="0" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
</Style>
|
||||
|
||||
<!-- "Key Binding #N" template -->
|
||||
<DataTemplate x:Key="KeyChordTemplate"
|
||||
x:DataType="local:KeyChordViewModel">
|
||||
<ListViewItem IsTabStop="False"
|
||||
Style="{StaticResource KeyBindingContainerStyle}">
|
||||
<Grid Padding="-4,0,0,0"
|
||||
VerticalAlignment="Center">
|
||||
<local:SettingContainer Header="{x:Bind DisplayLabel, Mode=OneWay}">
|
||||
<Grid VerticalAlignment="Center"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<!-- Key visual / key chord listener -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- Cancel button (visible only in edit mode) -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- Accept button (visible only in edit mode) -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- Edit (pencil) button (visible only NOT in edit mode) -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- Delete button -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Column="0"
|
||||
Background="{ThemeResource AppBarItemBackgroundThemeBrush}"
|
||||
Click="{x:Bind ToggleEditMode}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(IsInEditMode), Mode=OneWay}">
|
||||
<TextBlock FontSize="14"
|
||||
Text="{x:Bind KeyChordText, Mode=OneWay}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
</Button>
|
||||
|
||||
<!-- Read-only key chord visual -->
|
||||
<local:KeyChordVisual Grid.Column="0"
|
||||
KeyChord="{x:Bind CurrentKeys, Mode=OneWay}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(IsInEditMode), Mode=OneWay}" />
|
||||
|
||||
<!-- Editable key chord listener -->
|
||||
<local:KeyChordListener Grid.Column="0"
|
||||
Keys="{x:Bind ProposedKeys, Mode=TwoWay}"
|
||||
Style="{StaticResource KeyChordEditorStyle}"
|
||||
Visibility="{x:Bind IsInEditMode, Mode=OneWay}" />
|
||||
|
||||
<!-- Cancel changes (edit mode only) -->
|
||||
<Button x:Uid="Actions_CancelButton"
|
||||
Grid.Column="1"
|
||||
Margin="8,0,0,0"
|
||||
AutomationProperties.Name="{x:Bind CancelButtonName}"
|
||||
Click="{x:Bind CancelChanges}"
|
||||
Style="{StaticResource EditButtonStyle}"
|
||||
@@ -201,9 +104,9 @@
|
||||
Glyph="" />
|
||||
</Button>
|
||||
|
||||
<!-- Accept changes (edit mode only) -->
|
||||
<Button x:Uid="Actions_AcceptButton"
|
||||
Grid.Column="2"
|
||||
Margin="8,0,8,0"
|
||||
AutomationProperties.Name="{x:Bind AcceptButtonName}"
|
||||
Click="{x:Bind AcceptChanges}"
|
||||
Flyout="{x:Bind AcceptChangesFlyout, Mode=OneWay}"
|
||||
@@ -213,8 +116,19 @@
|
||||
Glyph="" />
|
||||
</Button>
|
||||
|
||||
<Button Grid.Column="3"
|
||||
HorizontalAlignment="Left"
|
||||
<!-- Edit button -->
|
||||
<Button x:Uid="Actions_EditButton"
|
||||
Grid.Column="3"
|
||||
AutomationProperties.Name="{x:Bind EditButtonName}"
|
||||
Click="{x:Bind ToggleEditMode}"
|
||||
Style="{StaticResource EditButtonStyle}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(IsInEditMode), Mode=OneWay}">
|
||||
<FontIcon FontSize="{StaticResource EditButtonIconSize}"
|
||||
Glyph="" />
|
||||
</Button>
|
||||
|
||||
<!-- Delete button -->
|
||||
<Button Grid.Column="4"
|
||||
AutomationProperties.Name="{x:Bind DeleteButtonName}"
|
||||
Style="{StaticResource DeleteSmallButtonStyle}">
|
||||
<Button.Content>
|
||||
@@ -233,25 +147,23 @@
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</Grid>
|
||||
</ListViewItem>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!--
|
||||
BODGY: Each ArgWrapper DataTemplate below wraps its editor control
|
||||
in a <local:SettingContainer Header="{x:Bind Name}"> rather than sharing a
|
||||
single outer template. This is because a bug in WinUI 2 prevents a
|
||||
ContentPresenter + ContentTemplateSelector pattern from working correctly,
|
||||
resulting in "Microsoft.Terminal.Settings.Editor.ArgWrapper" being shown.
|
||||
-->
|
||||
|
||||
<!-- Example shortcut action to test this template: Adjust Opacity -->
|
||||
<!-- Currently that is the only Int32 arg, so just clamp the min/max values according to that -->
|
||||
<DataTemplate x:Key="Int32Template"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<muxc:NumberBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<muxc:NumberBox MinWidth="160"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
LargeChange="1"
|
||||
Maximum="100"
|
||||
@@ -259,24 +171,14 @@
|
||||
SmallChange="10"
|
||||
Style="{StaticResource NumberBoxSettingStyle}"
|
||||
Value="{x:Bind UnboxInt32(Value), Mode=TwoWay, BindBack=Int32BindBack}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Switch To Tab -->
|
||||
<DataTemplate x:Key="UInt32Template"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<muxc:NumberBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<muxc:NumberBox MinWidth="160"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
LargeChange="1"
|
||||
Maximum="999"
|
||||
@@ -284,24 +186,14 @@
|
||||
SmallChange="1"
|
||||
Style="{StaticResource NumberBoxSettingStyle}"
|
||||
Value="{x:Bind UnboxUInt32(Value), Mode=TwoWay, BindBack=UInt32BindBack}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Close Other Tabs -->
|
||||
<DataTemplate x:Key="UInt32OptionalTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<muxc:NumberBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<muxc:NumberBox MinWidth="160"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
LargeChange="1"
|
||||
Maximum="999"
|
||||
@@ -309,24 +201,14 @@
|
||||
SmallChange="1"
|
||||
Style="{StaticResource NumberBoxSettingStyle}"
|
||||
Value="{x:Bind UnboxUInt32Optional(Value), Mode=TwoWay, BindBack=UInt32OptionalBindBack}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Split Pane -->
|
||||
<DataTemplate x:Key="Int32OptionalTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<muxc:NumberBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<muxc:NumberBox MinWidth="160"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
LargeChange="1"
|
||||
Maximum="999"
|
||||
@@ -334,24 +216,14 @@
|
||||
SmallChange="1"
|
||||
Style="{StaticResource NumberBoxSettingStyle}"
|
||||
Value="{x:Bind UnboxInt32Optional(Value), Mode=TwoWay, BindBack=Int32OptionalBindBack}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Adjust Font Size -->
|
||||
<DataTemplate x:Key="FloatTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<muxc:NumberBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<muxc:NumberBox MinWidth="160"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
LargeChange="1"
|
||||
Maximum="999"
|
||||
@@ -359,24 +231,14 @@
|
||||
SmallChange="1"
|
||||
Style="{StaticResource NumberBoxSettingStyle}"
|
||||
Value="{x:Bind UnboxFloat(Value), Mode=TwoWay, BindBack=FloatBindBack}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Split Pane -->
|
||||
<DataTemplate x:Key="SplitSizeTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<muxc:NumberBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<muxc:NumberBox MinWidth="160"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
LargeChange="0.2"
|
||||
Maximum="1"
|
||||
@@ -384,144 +246,95 @@
|
||||
SmallChange="0.1"
|
||||
Style="{StaticResource NumberBoxSettingStyle}"
|
||||
Value="{x:Bind UnboxFloat(Value), Mode=TwoWay, BindBack=FloatBindBack}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Send Input -->
|
||||
<DataTemplate x:Key="StringTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*"
|
||||
MinWidth="196" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<TextBox Grid.Column="1"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<TextBox MinWidth="248"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
Text="{x:Bind UnboxString(Value), Mode=TwoWay, BindBack=StringBindBack}"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Set Color Scheme -->
|
||||
<DataTemplate x:Key="ColorSchemeTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<ComboBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<ComboBox MinWidth="248"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind EnumList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind EnumValue, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Export Buffer -->
|
||||
<DataTemplate x:Key="FilePickerTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*"
|
||||
MinWidth="196" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<TextBox Grid.Column="1"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
Text="{x:Bind UnboxString(Value), Mode=TwoWay, BindBack=StringBindBack}"
|
||||
TextWrapping="Wrap" />
|
||||
<Button x:Uid="Actions_Browse"
|
||||
Grid.Column="2"
|
||||
Click="{x:Bind BrowseForFile_Click}"
|
||||
Style="{StaticResource BrowseButtonStyle}" />
|
||||
</Grid>
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<Grid ColumnSpacing="4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"
|
||||
MinWidth="196" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox Grid.Column="0"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
Text="{x:Bind UnboxString(Value), Mode=TwoWay, BindBack=StringBindBack}"
|
||||
TextWrapping="Wrap" />
|
||||
<Button x:Uid="Actions_Browse"
|
||||
Grid.Column="1"
|
||||
Click="{x:Bind BrowseForFile_Click}"
|
||||
Style="{StaticResource BrowseButtonStyle}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: New Tab -->
|
||||
<DataTemplate x:Key="FolderPickerTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*"
|
||||
MinWidth="196" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<TextBox Grid.Column="1"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
Text="{x:Bind UnboxString(Value), Mode=TwoWay, BindBack=StringBindBack}"
|
||||
TextWrapping="Wrap" />
|
||||
<Button x:Uid="Actions_Browse"
|
||||
Grid.Column="2"
|
||||
Click="{x:Bind BrowseForFolder_Click}"
|
||||
Style="{StaticResource BrowseButtonStyle}" />
|
||||
</Grid>
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<Grid ColumnSpacing="4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"
|
||||
MinWidth="196" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox Grid.Column="0"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
Text="{x:Bind UnboxString(Value), Mode=TwoWay, BindBack=StringBindBack}"
|
||||
TextWrapping="Wrap" />
|
||||
<Button x:Uid="Actions_Browse"
|
||||
Grid.Column="1"
|
||||
Click="{x:Bind BrowseForFolder_Click}"
|
||||
Style="{StaticResource BrowseButtonStyle}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Set Focus Mode -->
|
||||
<DataTemplate x:Key="BoolTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<ToggleSwitch Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
IsOn="{x:Bind UnboxBool(Value), Mode=TwoWay, BindBack=BoolOptionalBindBack}" />
|
||||
</Grid>
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<ToggleSwitch AutomationProperties.Name="{x:Bind Name}"
|
||||
IsOn="{x:Bind UnboxBool(Value), Mode=TwoWay, BindBack=BoolOptionalBindBack}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Split Pane -->
|
||||
<DataTemplate x:Key="BoolOptionalTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<CheckBox Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<CheckBox AutomationProperties.Name="{x:Bind Name}"
|
||||
IsChecked="{x:Bind UnboxBoolOptional(Value), Mode=TwoWay, BindBack=BoolOptionalBindBack}"
|
||||
IsThreeState="True" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Resize Pane -->
|
||||
@@ -532,24 +345,14 @@
|
||||
|
||||
<DataTemplate x:Key="EnumTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<ComboBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<ComboBox MinWidth="248"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind EnumList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind EnumValue, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Copy Text -->
|
||||
@@ -572,66 +375,35 @@
|
||||
|
||||
<DataTemplate x:Key="FlagTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<ItemsControl Grid.Column="1"
|
||||
Margin="0"
|
||||
HorizontalAlignment="Left"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<ItemsControl AutomationProperties.Name="{x:Bind Name}"
|
||||
ItemTemplate="{StaticResource FlagItemTemplate}"
|
||||
ItemsSource="{x:Bind FlagList, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Add Mark -->
|
||||
<DataTemplate x:Key="TerminalCoreColorOptionalTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<local:NullableColorPicker x:Uid="Actions_NullableColorPicker"
|
||||
Grid.Column="1"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
ColorSchemeVM="{x:Bind DefaultColorScheme, Mode=OneWay}"
|
||||
CurrentColor="{x:Bind UnboxTerminalCoreColorOptional(Value), Mode=TwoWay, BindBack=TerminalCoreColorBindBack}"
|
||||
NullColorPreview="{x:Bind DefaultColorScheme.ForegroundColor.Color, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Set Tab Color -->
|
||||
<DataTemplate x:Key="WindowsUIColorOptionalTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<local:NullableColorPicker x:Uid="Actions_NullableColorPicker"
|
||||
Grid.Column="1"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
ColorSchemeVM="{x:Bind DefaultColorScheme, Mode=OneWay}"
|
||||
CurrentColor="{x:Bind UnboxWindowsUIColorOptional(Value), Mode=TwoWay, BindBack=WindowsUIColorBindBack}"
|
||||
NullColorPreview="{x:Bind DefaultColorScheme.ForegroundColor.Color, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<local:ArgsTemplateSelectors x:Key="ArgsTemplateSelector"
|
||||
@@ -655,122 +427,106 @@
|
||||
</ResourceDictionary>
|
||||
</Page.Resources>
|
||||
|
||||
<Border MaxWidth="{StaticResource StandardControlMaxWidth}"
|
||||
Margin="{StaticResource SettingStackMargin}">
|
||||
<Grid Margin="{StaticResource SettingStackMargin}"
|
||||
HorizontalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock x:Uid="Actions_CommandDetails"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Margin="0,0,0,12"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource TextBlockGroupingStyle}" />
|
||||
<TextBlock x:Uid="Actions_Name"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="0,0,0,8"
|
||||
VerticalAlignment="Center" />
|
||||
<TextBox x:Name="CommandNameTextBox"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,8"
|
||||
HorizontalAlignment="Stretch"
|
||||
AutomationProperties.Name="{x:Bind ViewModel.ActionNameTextBoxAutomationPropName}"
|
||||
PlaceholderText="{x:Bind ViewModel.DisplayName, Mode=OneWay}"
|
||||
Text="{x:Bind ViewModel.Name, Mode=TwoWay}" />
|
||||
<TextBlock x:Uid="Actions_ShortcutAction"
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="0,0,0,12"
|
||||
VerticalAlignment="Center" />
|
||||
<AutoSuggestBox x:Name="ShortcutActionBox"
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,12"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.Name="{x:Bind ViewModel.ShortcutActionComboBoxAutomationPropName}"
|
||||
GotFocus="ShortcutActionBox_GotFocus"
|
||||
LostFocus="ShortcutActionBox_LostFocus"
|
||||
QuerySubmitted="ShortcutActionBox_QuerySubmitted"
|
||||
TextChanged="ShortcutActionBox_TextChanged" />
|
||||
<TextBlock x:Uid="Actions_Keybindings"
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Margin="0,0,0,12"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource TextBlockGroupingStyle}" />
|
||||
<ListView x:Name="KeyChordListView"
|
||||
x:Uid="Actions_KeyBindingsListView"
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Margin="0,0,0,12"
|
||||
ItemTemplate="{StaticResource KeyChordTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.KeyChordList, Mode=OneWay}"
|
||||
SelectionMode="None">
|
||||
<ListView.Footer>
|
||||
<Button Margin="0,4,0,0"
|
||||
Click="{x:Bind ViewModel.AddKeybinding_Click}">
|
||||
<TextBlock x:Uid="Actions_AddKeyChord" />
|
||||
</Button>
|
||||
</ListView.Footer>
|
||||
</ListView>
|
||||
<TextBlock x:Uid="Actions_Arguments"
|
||||
Grid.Row="5"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Margin="0,0,0,12"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource TextBlockGroupingStyle}"
|
||||
Visibility="{x:Bind ViewModel.ActionArgsVM.HasArgs, Mode=OneWay}" />
|
||||
<ItemsControl Grid.Row="6"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Margin="0,0,0,12"
|
||||
HorizontalAlignment="Stretch"
|
||||
AutomationProperties.Name="{x:Bind ViewModel.AdditionalArgumentsControlAutomationPropName}"
|
||||
IsTabStop="False"
|
||||
ItemTemplateSelector="{StaticResource ArgsTemplateSelector}"
|
||||
ItemsSource="{x:Bind ViewModel.ActionArgsVM.ArgValues, Mode=OneWay}" />
|
||||
<Button Grid.Row="7"
|
||||
Grid.Column="0"
|
||||
IsEnabled="{x:Bind ViewModel.IsUserAction, Mode=OneWay}"
|
||||
Style="{StaticResource DeleteButtonStyle}">
|
||||
<Button.Content>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="Actions_DeleteButton2"
|
||||
Style="{StaticResource IconButtonTextBlockStyle}" />
|
||||
</StackPanel>
|
||||
</Button.Content>
|
||||
<Button.Flyout>
|
||||
<Flyout>
|
||||
<StackPanel>
|
||||
<TextBlock x:Uid="Actions_CommandDeleteConfirmationMessage"
|
||||
Style="{StaticResource CustomFlyoutTextStyle}" />
|
||||
<Button x:Uid="Actions_CommandDeleteConfirmationButton"
|
||||
Click="{x:Bind ViewModel.Delete_Click}" />
|
||||
<Border MaxWidth="{StaticResource StandardControlMaxWidth}">
|
||||
<StackPanel HorizontalAlignment="Stretch"
|
||||
Style="{StaticResource SettingsStackStyle}">
|
||||
|
||||
<!-- Action type (top-most setting on the page) -->
|
||||
<local:SettingContainer x:Name="ActionType"
|
||||
x:Uid="EditAction_ActionType">
|
||||
<AutoSuggestBox x:Name="ShortcutActionBox"
|
||||
MinWidth="248"
|
||||
AutomationProperties.Name="{x:Bind ViewModel.ShortcutActionComboBoxAutomationPropName}"
|
||||
GotFocus="ShortcutActionBox_GotFocus"
|
||||
LostFocus="ShortcutActionBox_LostFocus"
|
||||
QuerySubmitted="ShortcutActionBox_QuerySubmitted"
|
||||
TextChanged="ShortcutActionBox_TextChanged" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Key bindings expander -->
|
||||
<local:SettingContainer x:Name="KeyBindingsContainer"
|
||||
x:Uid="EditAction_KeyBindings"
|
||||
StartExpanded="{x:Bind mtu:Converters.InvertBoolean(ViewModel.HasNoKeyChords), Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<StackPanel>
|
||||
<!-- "New key binding" button -->
|
||||
<local:SettingContainer x:Name="NewKeyBinding"
|
||||
x:Uid="EditAction_NewKeyBinding">
|
||||
<Button x:Uid="EditAction_AddKeyBinding"
|
||||
Click="{x:Bind ViewModel.AddKeybinding_Click}"
|
||||
Style="{StaticResource AccentButtonStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Existing key bindings, one container per chord -->
|
||||
<ListView x:Name="KeyChordListView"
|
||||
x:Uid="Actions_KeyBindingsListView"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
IsItemClickEnabled="False"
|
||||
ItemContainerStyle="{StaticResource KeyChordListViewItemStyle}"
|
||||
ItemTemplate="{StaticResource KeyChordTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.KeyChordList, Mode=OneWay}"
|
||||
SelectionMode="None" />
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Additional customizations expander -->
|
||||
<local:SettingContainer x:Name="AdditionalCustomizations"
|
||||
x:Uid="EditAction_AdditionalCustomizations"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<StackPanel>
|
||||
<!-- Action name -->
|
||||
<local:SettingContainer x:Name="ActionName"
|
||||
x:Uid="EditAction_ActionName">
|
||||
<TextBox x:Name="CommandNameTextBox"
|
||||
MinWidth="248"
|
||||
AutomationProperties.Name="{x:Bind ViewModel.ActionNameTextBoxAutomationPropName}"
|
||||
PlaceholderText="{x:Bind ViewModel.DisplayName, Mode=OneWay}"
|
||||
Text="{x:Bind ViewModel.Name, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Action argument controls -->
|
||||
<ItemsControl HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
AutomationProperties.Name="{x:Bind ViewModel.AdditionalArgumentsControlAutomationPropName}"
|
||||
IsTabStop="False"
|
||||
ItemTemplateSelector="{StaticResource ArgsTemplateSelector}"
|
||||
ItemsSource="{x:Bind ViewModel.ActionArgsVM.ArgValues, Mode=OneWay}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel HorizontalAlignment="Stretch" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Delete command button -->
|
||||
<local:SettingContainer x:Name="DeleteCommand"
|
||||
x:Uid="EditAction_DeleteCommand">
|
||||
<Button IsEnabled="{x:Bind ViewModel.IsUserAction, Mode=OneWay}"
|
||||
Style="{StaticResource DeleteButtonStyle}">
|
||||
<Button.Content>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="Actions_DeleteButton2"
|
||||
Style="{StaticResource IconButtonTextBlockStyle}" />
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Button.Content>
|
||||
<Button.Flyout>
|
||||
<Flyout>
|
||||
<StackPanel>
|
||||
<TextBlock x:Uid="Actions_CommandDeleteConfirmationMessage"
|
||||
Style="{StaticResource CustomFlyoutTextStyle}" />
|
||||
<Button x:Uid="Actions_CommandDeleteConfirmationButton"
|
||||
Click="{x:Bind ViewModel.Delete_Click}" />
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</local:SettingContainer>
|
||||
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Page>
|
||||
|
||||
131
src/cascadia/TerminalSettingsEditor/KeyChordVisual.cpp
Normal file
131
src/cascadia/TerminalSettingsEditor/KeyChordVisual.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "KeyChordVisual.h"
|
||||
#include "KeyChordVisual.g.cpp"
|
||||
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Controls;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
DependencyProperty KeyChordVisual::_KeyChordProperty{ nullptr };
|
||||
|
||||
KeyChordVisual::KeyChordVisual()
|
||||
{
|
||||
InitializeComponent();
|
||||
_InitializeProperties();
|
||||
}
|
||||
|
||||
void KeyChordVisual::_InitializeProperties()
|
||||
{
|
||||
if (!_KeyChordProperty)
|
||||
{
|
||||
_KeyChordProperty =
|
||||
DependencyProperty::Register(
|
||||
L"KeyChord",
|
||||
xaml_typename<Control::KeyChord>(),
|
||||
xaml_typename<Editor::KeyChordVisual>(),
|
||||
PropertyMetadata{ nullptr, PropertyChangedCallback{ &KeyChordVisual::_OnKeyChordChanged } });
|
||||
}
|
||||
}
|
||||
|
||||
void KeyChordVisual::_OnKeyChordChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
|
||||
{
|
||||
if (const auto control{ d.try_as<Editor::KeyChordVisual>() })
|
||||
{
|
||||
const auto controlImpl{ get_self<KeyChordVisual>(control) };
|
||||
controlImpl->_UpdateKeyVisuals();
|
||||
}
|
||||
}
|
||||
|
||||
// Capitalizes the first character of the provided string.
|
||||
// Examples: "enter" -> "Enter", "f1" -> "F1", "v" -> "V"
|
||||
static winrt::hstring _formatMainKeyName(std::wstring_view part)
|
||||
{
|
||||
if (part.empty())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
std::wstring buffer{ part };
|
||||
buffer[0] = til::toupper_ascii(buffer[0]);
|
||||
return winrt::hstring{ buffer };
|
||||
}
|
||||
|
||||
void KeyChordVisual::_UpdateKeyVisuals()
|
||||
{
|
||||
auto panel{ KeysPanel() };
|
||||
if (!panel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
panel.Children().Clear();
|
||||
|
||||
const auto kc{ KeyChord() };
|
||||
if (!kc)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Reuse the canonical serialization so the key naming stays in sync with the
|
||||
// rest of the app. Then split on '+' (no key name in the table contains a literal
|
||||
// '+'; VK_OEM_PLUS serializes as "plus") and render each part as its own visual.
|
||||
const auto serialized{ Model::KeyChordSerialization::ToString(kc) };
|
||||
if (serialized.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const std::wstring_view full{ serialized };
|
||||
for (const auto part : til::split_iterator{ full, L'+' })
|
||||
{
|
||||
if (til::equals_insensitive_ascii(part, L"win"))
|
||||
{
|
||||
_AddGlyphKey();
|
||||
}
|
||||
else if (til::equals_insensitive_ascii(part, L"ctrl"))
|
||||
{
|
||||
_AddTextKey(L"Ctrl");
|
||||
}
|
||||
else if (til::equals_insensitive_ascii(part, L"alt"))
|
||||
{
|
||||
_AddTextKey(L"Alt");
|
||||
}
|
||||
else if (til::equals_insensitive_ascii(part, L"shift"))
|
||||
{
|
||||
_AddTextKey(L"Shift");
|
||||
}
|
||||
else
|
||||
{
|
||||
_AddTextKey(_formatMainKeyName(part));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KeyChordVisual::_AddTextKey(const winrt::hstring& text)
|
||||
{
|
||||
const auto tmpl{ Resources().Lookup(box_value(L"KeyChordVisualTextKeyTemplate")).as<DataTemplate>() };
|
||||
const auto border{ tmpl.LoadContent().as<Border>() };
|
||||
if (const auto tb{ border.Child().try_as<TextBlock>() })
|
||||
{
|
||||
tb.Text(text);
|
||||
}
|
||||
KeysPanel().Children().Append(border);
|
||||
}
|
||||
|
||||
void KeyChordVisual::_AddGlyphKey()
|
||||
{
|
||||
const auto tmpl{ Resources().Lookup(box_value(L"KeyChordVisualWindowsKeyTemplate")).as<DataTemplate>() };
|
||||
const auto border{ tmpl.LoadContent().as<Border>() };
|
||||
|
||||
// Provide an accessible name for the glyph since it has no text fallback.
|
||||
if (const auto path{ border.Child() })
|
||||
{
|
||||
Automation::AutomationProperties::SetName(path, L"Win");
|
||||
}
|
||||
KeysPanel().Children().Append(border);
|
||||
}
|
||||
}
|
||||
31
src/cascadia/TerminalSettingsEditor/KeyChordVisual.h
Normal file
31
src/cascadia/TerminalSettingsEditor/KeyChordVisual.h
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "KeyChordVisual.g.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
struct KeyChordVisual : KeyChordVisualT<KeyChordVisual>
|
||||
{
|
||||
public:
|
||||
KeyChordVisual();
|
||||
|
||||
DEPENDENCY_PROPERTY(Control::KeyChord, KeyChord);
|
||||
|
||||
private:
|
||||
static void _InitializeProperties();
|
||||
static void _OnKeyChordChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
|
||||
void _UpdateKeyVisuals();
|
||||
void _AddTextKey(const winrt::hstring& text);
|
||||
void _AddGlyphKey();
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(KeyChordVisual);
|
||||
}
|
||||
13
src/cascadia/TerminalSettingsEditor/KeyChordVisual.idl
Normal file
13
src/cascadia/TerminalSettingsEditor/KeyChordVisual.idl
Normal file
@@ -0,0 +1,13 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
[default_interface] runtimeclass KeyChordVisual : Windows.UI.Xaml.Controls.UserControl
|
||||
{
|
||||
KeyChordVisual();
|
||||
|
||||
Microsoft.Terminal.Control.KeyChord KeyChord;
|
||||
static Windows.UI.Xaml.DependencyProperty KeyChordProperty { get; };
|
||||
}
|
||||
}
|
||||
82
src/cascadia/TerminalSettingsEditor/KeyChordVisual.xaml
Normal file
82
src/cascadia/TerminalSettingsEditor/KeyChordVisual.xaml
Normal file
@@ -0,0 +1,82 @@
|
||||
<!--
|
||||
Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information.
|
||||
-->
|
||||
<UserControl x:Class="Microsoft.Terminal.Settings.Editor.KeyChordVisual"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
IsTabStop="False"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Default">
|
||||
<StaticResource x:Key="KeyChordVisualKeyBackground"
|
||||
ResourceKey="AccentFillColorDefaultBrush" />
|
||||
<StaticResource x:Key="KeyChordVisualKeyForeground"
|
||||
ResourceKey="TextOnAccentFillColorPrimaryBrush" />
|
||||
<StaticResource x:Key="KeyChordVisualKeyBorderBrush"
|
||||
ResourceKey="AccentControlElevationBorderBrush" />
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<StaticResource x:Key="KeyChordVisualKeyBackground"
|
||||
ResourceKey="SystemColorButtonFaceColorBrush" />
|
||||
<StaticResource x:Key="KeyChordVisualKeyForeground"
|
||||
ResourceKey="SystemColorButtonTextColorBrush" />
|
||||
<StaticResource x:Key="KeyChordVisualKeyBorderBrush"
|
||||
ResourceKey="SystemColorButtonTextColorBrush" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
<Style x:Key="KeyChordVisualKeyBorderStyle"
|
||||
TargetType="Border">
|
||||
<Setter Property="MinWidth" Value="32" />
|
||||
<Setter Property="MinHeight" Value="28" />
|
||||
<Setter Property="Padding" Value="8,2,8,2" />
|
||||
<Setter Property="HorizontalAlignment" Value="Center" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="Background" Value="{ThemeResource KeyChordVisualKeyBackground}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource KeyChordVisualKeyBorderBrush}" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
</Style>
|
||||
<Style x:Key="KeyChordVisualKeyTextStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="13" />
|
||||
<Setter Property="HorizontalAlignment" Value="Center" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="TextAlignment" Value="Center" />
|
||||
<Setter Property="Foreground" Value="{ThemeResource KeyChordVisualKeyForeground}" />
|
||||
</Style>
|
||||
|
||||
<DataTemplate x:Key="KeyChordVisualTextKeyTemplate">
|
||||
<Border Style="{StaticResource KeyChordVisualKeyBorderStyle}">
|
||||
<TextBlock Style="{StaticResource KeyChordVisualKeyTextStyle}" />
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="KeyChordVisualWindowsKeyTemplate">
|
||||
<Border Style="{StaticResource KeyChordVisualKeyBorderStyle}">
|
||||
<Path Width="11"
|
||||
Height="11"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Data="M9 20H0V11H9V20ZM20 20H11V11H20V20ZM9 9H0V0H9V9ZM20 9H11V0H20V9Z"
|
||||
Fill="{ThemeResource KeyChordVisualKeyForeground}"
|
||||
Stretch="Uniform" />
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
<StackPanel x:Name="KeysPanel"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Horizontal"
|
||||
Spacing="2" />
|
||||
</UserControl>
|
||||
@@ -86,6 +86,9 @@
|
||||
<ClInclude Include="KeyChordListener.h">
|
||||
<DependentUpon>KeyChordListener.xaml</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="KeyChordVisual.h">
|
||||
<DependentUpon>KeyChordVisual.xaml</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Launch.h">
|
||||
<DependentUpon>Launch.xaml</DependentUpon>
|
||||
</ClInclude>
|
||||
@@ -216,6 +219,9 @@
|
||||
<Page Include="KeyChordListener.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="KeyChordVisual.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Launch.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
@@ -297,6 +303,9 @@
|
||||
<ClCompile Include="KeyChordListener.cpp">
|
||||
<DependentUpon>KeyChordListener.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="KeyChordVisual.cpp">
|
||||
<DependentUpon>KeyChordVisual.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Launch.cpp">
|
||||
<DependentUpon>Launch.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
@@ -427,6 +436,10 @@
|
||||
<DependentUpon>KeyChordListener.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="KeyChordVisual.idl">
|
||||
<DependentUpon>KeyChordVisual.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="Launch.idl">
|
||||
<DependentUpon>Launch.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
<Page Include="SettingContainerStyle.xaml" />
|
||||
<Page Include="AddProfile.xaml" />
|
||||
<Page Include="KeyChordListener.xaml" />
|
||||
<Page Include="KeyChordVisual.xaml" />
|
||||
<Page Include="NullableColorPicker.xaml" />
|
||||
<Page Include="IconPicker.xaml" />
|
||||
<Page Include="NewTabMenu.xaml" />
|
||||
|
||||
@@ -289,8 +289,8 @@
|
||||
<comment>Header for a control to toggle whether the terminal should automatically detect URLs and make them clickable, or not.</comment>
|
||||
</data>
|
||||
<data name="Globals_SearchWebDefaultQueryUrl.Header" xml:space="preserve">
|
||||
<value>Default URL to use for the "Search web" action</value>
|
||||
<comment>Header for a control to set the query URL when using the "search web" action.</comment>
|
||||
<value>Default URL to use for the "Search web" shortcut</value>
|
||||
<comment>Header for a control to set the query URL when using the "search web" shortcut.</comment>
|
||||
</data>
|
||||
<data name="Globals_SearchWebDefaultQueryUrl.HelpText" xml:space="preserve">
|
||||
<value>The placeholder "%s" will be replaced with the search query.</value>
|
||||
@@ -590,7 +590,7 @@
|
||||
<comment>Additional description for what the "force vt input" setting does. Presented near "Globals_ForceVTInput.Header".</comment>
|
||||
</data>
|
||||
<data name="Globals_AllowHeadless.HelpText" xml:space="preserve">
|
||||
<value>This allows actions such as Global Summon and Quake Mode actions to work even when no windows are open.</value>
|
||||
<value>This allows shortcuts such as Global Summon and Quake Mode shortcuts to work even when no windows are open.</value>
|
||||
<comment>Additional description for what the "allow headless" setting does. Presented near "Globals_AllowHeadless.Header".</comment>
|
||||
</data>
|
||||
<data name="Globals_TabWidthMode.Header" xml:space="preserve">
|
||||
@@ -682,12 +682,12 @@
|
||||
<comment>Header for the "rendering" menu item. This navigates to a page that lets you see and modify settings related to the app's rendering of text in the terminal.</comment>
|
||||
</data>
|
||||
<data name="Nav_Actions.Content" xml:space="preserve">
|
||||
<value>Actions</value>
|
||||
<comment>Header for the "actions" menu item. This navigates to a page that lets you see the available commands in the app.</comment>
|
||||
<value>Shortcuts</value>
|
||||
<comment>Header for the "shortcuts" menu item. This navigates to a page that lets you see the available keyboard shortcuts in the app. (Resource key kept as "Nav_Actions" for stability.)</comment>
|
||||
</data>
|
||||
<data name="Nav_EditAction.Content" xml:space="preserve">
|
||||
<value>Edit Action...</value>
|
||||
<comment>Header for the "edit action" page. This is the page that lets you modify a specific command and its key bindings.</comment>
|
||||
<value>Edit Shortcut...</value>
|
||||
<comment>Header for the "edit shortcut" page. This is the page that lets you modify a specific command and its key bindings. (Resource key kept as "Nav_EditAction" for stability.)</comment>
|
||||
</data>
|
||||
<data name="Nav_Extensions.Content" xml:space="preserve">
|
||||
<value>Extensions</value>
|
||||
@@ -1766,28 +1766,28 @@
|
||||
<comment>A description for what the delete unfocused appearance button does.</comment>
|
||||
</data>
|
||||
<data name="Actions_Disclaimer.Content" xml:space="preserve">
|
||||
<value>Learn more about actions</value>
|
||||
<comment>Disclaimer presented at the top of the actions page to redirect the user to documentation regarding actions.</comment>
|
||||
<value>Learn more about shortcuts</value>
|
||||
<comment>Disclaimer presented at the top of the shortcuts page to redirect the user to documentation regarding keyboard shortcuts.</comment>
|
||||
</data>
|
||||
<data name="Actions_DeleteButton2.Text" xml:space="preserve">
|
||||
<value>Delete action</value>
|
||||
<comment>Button label that deletes the selected action.</comment>
|
||||
<value>Delete shortcut</value>
|
||||
<comment>Button label that deletes the selected shortcut.</comment>
|
||||
</data>
|
||||
<data name="Actions_Name.Text" xml:space="preserve">
|
||||
<value>Action name</value>
|
||||
<comment>Label for the text box that edits the action name.</comment>
|
||||
<value>Shortcut name</value>
|
||||
<comment>Label for the text box that edits the shortcut name.</comment>
|
||||
</data>
|
||||
<data name="Actions_NameEntryBox.PlaceholderText" xml:space="preserve">
|
||||
<value>Action name</value>
|
||||
<comment>Placeholder text for the text box where the user can edit the action name.</comment>
|
||||
<value>Shortcut name</value>
|
||||
<comment>Placeholder text for the text box where the user can edit the shortcut name.</comment>
|
||||
</data>
|
||||
<data name="Actions_ShortcutAction.Text" xml:space="preserve">
|
||||
<value>Action type</value>
|
||||
<comment>Label for the combo box that edits the action type.</comment>
|
||||
<value>Shortcut type</value>
|
||||
<comment>Label for the combo box that edits the shortcut type (which action runs when this shortcut is invoked).</comment>
|
||||
</data>
|
||||
<data name="Actions_KeyBindingsListView.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Keybindings</value>
|
||||
<comment>Name for a control which contains the list of keybindings for the current command.</comment>
|
||||
<value>Shortcuts</value>
|
||||
<comment>Name for a control which contains the list of keyboard shortcuts for the current command.</comment>
|
||||
</data>
|
||||
<data name="Actions_CommandDetails.Text" xml:space="preserve">
|
||||
<value>Command details</value>
|
||||
@@ -1798,44 +1798,44 @@
|
||||
<comment>Label for the list of editable arguments for the currently selected action.</comment>
|
||||
</data>
|
||||
<data name="Actions_Keybindings.Text" xml:space="preserve">
|
||||
<value>Keybindings</value>
|
||||
<comment>Label for the list of editable keybindings for the current command.</comment>
|
||||
<value>Shortcuts</value>
|
||||
<comment>Label for the list of editable keyboard shortcuts for the current command.</comment>
|
||||
</data>
|
||||
<data name="Actions_AddKeyChord.Text" xml:space="preserve">
|
||||
<value>Add keybinding</value>
|
||||
<comment>Button label that adds a keybinding to the current action.</comment>
|
||||
<value>Add shortcut</value>
|
||||
<comment>Button label that adds a keyboard shortcut to the current action.</comment>
|
||||
</data>
|
||||
<data name="Actions_AdditionalKeyChords" xml:space="preserve">
|
||||
<value>and {} more</value>
|
||||
<comment>Text that will be read out by a screen reader indicating that additional keybindings exist for this command. {} will be replaced by the number of additional keybindings.</comment>
|
||||
</data>
|
||||
<data name="Actions_DeleteConfirmationButton.Content" xml:space="preserve">
|
||||
<value>Yes, delete key binding</value>
|
||||
<comment>Button label that confirms deletion of a key binding entry.</comment>
|
||||
<value>Yes, delete shortcut</value>
|
||||
<comment>Button label that confirms deletion of a keyboard shortcut entry.</comment>
|
||||
</data>
|
||||
<data name="Actions_DeleteConfirmationMessage.Text" xml:space="preserve">
|
||||
<value>Are you sure you want to delete this key binding?</value>
|
||||
<comment>Confirmation message displayed when the user attempts to delete a key binding entry.</comment>
|
||||
<value>Are you sure you want to delete this shortcut?</value>
|
||||
<comment>Confirmation message displayed when the user attempts to delete a keyboard shortcut entry.</comment>
|
||||
</data>
|
||||
<data name="Actions_CommandDeleteConfirmationButton.Content" xml:space="preserve">
|
||||
<value>Yes, delete action</value>
|
||||
<comment>Button label that confirms deletion of an action.</comment>
|
||||
<value>Yes, delete shortcut</value>
|
||||
<comment>Button label that confirms deletion of a shortcut entry.</comment>
|
||||
</data>
|
||||
<data name="Actions_CommandDeleteConfirmationMessage.Text" xml:space="preserve">
|
||||
<value>Are you sure you want to delete this action?</value>
|
||||
<comment>Confirmation message displayed when the user attempts to delete an action.</comment>
|
||||
<value>Are you sure you want to delete this shortcut?</value>
|
||||
<comment>Confirmation message displayed when the user attempts to delete a shortcut entry.</comment>
|
||||
</data>
|
||||
<data name="Actions_InvalidKeyChordMessage" xml:space="preserve">
|
||||
<value>Invalid key chord. Please enter a valid key chord.</value>
|
||||
<comment>Error message displayed when an invalid key chord is input by the user.</comment>
|
||||
<value>Invalid shortcut. Please enter a valid keyboard shortcut.</value>
|
||||
<comment>Error message displayed when an invalid keyboard shortcut is input by the user.</comment>
|
||||
</data>
|
||||
<data name="Actions_RenameConflictConfirmationAcceptButton" xml:space="preserve">
|
||||
<value>Yes</value>
|
||||
<comment>Button label that confirms the deletion of a conflicting key binding to allow the current key binding to be registered.</comment>
|
||||
</data>
|
||||
<data name="Actions_RenameConflictConfirmationMessage" xml:space="preserve">
|
||||
<value>The provided key chord is already being used by the following action:</value>
|
||||
<comment>Error message displayed when a key chord that is already in use is input by the user. The name of the conflicting key chord is displayed after this message.</comment>
|
||||
<value>The provided shortcut is already being used by the following action:</value>
|
||||
<comment>Error message displayed when a keyboard shortcut that is already in use is input by the user. The name of the conflicting shortcut is displayed after this message.</comment>
|
||||
</data>
|
||||
<data name="Actions_RenameConflictConfirmationQuestion" xml:space="preserve">
|
||||
<value>Would you like to overwrite it?</value>
|
||||
@@ -1862,12 +1862,60 @@
|
||||
<comment>Text label for a button that can be used to begin making changes to a key binding entry.</comment>
|
||||
</data>
|
||||
<data name="Actions_AddNewTextBlock.Text" xml:space="preserve">
|
||||
<value>Add new</value>
|
||||
<comment>Button label that creates a new action on the actions page.</comment>
|
||||
<value>Add new shortcut</value>
|
||||
<comment>Button label that creates a new keyboard shortcut on the shortcuts page.</comment>
|
||||
</data>
|
||||
<data name="Actions_ActionComboBox.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Action</value>
|
||||
<comment>Label for a control that sets the action of a key binding.</comment>
|
||||
<data name="Actions_ViewAllKeyChordsButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>View all shortcuts</value>
|
||||
<comment>Tooltip for a button on each row of the Shortcuts page that opens a flyout listing every keyboard shortcut registered for that action.</comment>
|
||||
</data>
|
||||
<data name="Actions_NoKeyBindings.Text" xml:space="preserve">
|
||||
<value>No shortcuts</value>
|
||||
<comment>Empty-state message shown inside the "view all shortcuts" flyout (opened from each row's "..." button on the Shortcuts page) when the action has no keyboard shortcuts registered.</comment>
|
||||
</data>
|
||||
<data name="EditAction_ActionType.Header" xml:space="preserve">
|
||||
<value>Shortcut type</value>
|
||||
<comment>Header for the shortcut-type setting on the Edit Shortcut page (lets the user pick which action runs when this shortcut is invoked).</comment>
|
||||
</data>
|
||||
<data name="EditAction_ActionName.Header" xml:space="preserve">
|
||||
<value>Shortcut name</value>
|
||||
<comment>Header for the shortcut-name setting on the Edit Shortcut page (lets the user provide a friendly name for this shortcut).</comment>
|
||||
</data>
|
||||
<data name="EditAction_KeyBindings.Header" xml:space="preserve">
|
||||
<value>Shortcuts</value>
|
||||
<comment>Header for the shortcuts expander on the Edit Shortcut page.</comment>
|
||||
</data>
|
||||
<data name="EditAction_KeyBindings.HelpText" xml:space="preserve">
|
||||
<value>Customize keyboard shortcuts to speed up common actions and workflows.</value>
|
||||
<comment>Help text shown under the "Shortcuts" header on the Edit Shortcut page.</comment>
|
||||
</data>
|
||||
<data name="EditAction_NewKeyBinding.Header" xml:space="preserve">
|
||||
<value>New shortcut</value>
|
||||
<comment>Header for the "add a new shortcut" row on the Edit Shortcut page.</comment>
|
||||
</data>
|
||||
<data name="EditAction_AddKeyBinding.Content" xml:space="preserve">
|
||||
<value>Add shortcut</value>
|
||||
<comment>Label for the accent button that appends a new keyboard shortcut to the current action.</comment>
|
||||
</data>
|
||||
<data name="EditAction_AdditionalCustomizations.Header" xml:space="preserve">
|
||||
<value>Additional customizations</value>
|
||||
<comment>Header for the additional customizations expander on the Edit Action page (contains action name and per-action argument settings).</comment>
|
||||
</data>
|
||||
<data name="EditAction_AdditionalCustomizations.HelpText" xml:space="preserve">
|
||||
<value>Fine tune how shortcuts behave.</value>
|
||||
<comment>Help text shown under the "Additional customizations" header on the Edit Shortcut page.</comment>
|
||||
</data>
|
||||
<data name="EditAction_KeyBindingNumberFormat" xml:space="preserve">
|
||||
<value>Shortcut #{}</value>
|
||||
<comment>{Locked="#{}"} Header label for an individual keyboard shortcut inside the "Shortcuts" expander on the Edit Shortcut page. {} is replaced with the 1-based index of the shortcut (e.g. "Shortcut #1").</comment>
|
||||
</data>
|
||||
<data name="EditAction_DeleteCommand.Header" xml:space="preserve">
|
||||
<value>Delete this shortcut</value>
|
||||
<comment>Header for the setting container that holds the "Delete shortcut" button at the bottom of the Edit Shortcut page.</comment>
|
||||
</data>
|
||||
<data name="EditAction_DeleteCommand.HelpText" xml:space="preserve">
|
||||
<value>This shortcut will be removed and any shortcuts associated with it will no longer work.</value>
|
||||
<comment>Help text shown under the "Delete this shortcut" setting container on the Edit Shortcut page.</comment>
|
||||
</data>
|
||||
<data name="Actions_NullEnumValue" xml:space="preserve">
|
||||
<value>Use global setting</value>
|
||||
|
||||
@@ -121,6 +121,11 @@
|
||||
<Thickness x:Key="SettingContainerIconMargin">0,4,8,4</Thickness>
|
||||
<x:Double x:Key="SettingContainerIconFontSize">16</x:Double>
|
||||
|
||||
<!-- Shared sizing for SettingContainer-style "card" rows (used by SettingsCardStyle and Actions page rows). -->
|
||||
<Thickness x:Key="SettingsCardPadding">16,8,8,8</Thickness>
|
||||
<x:Double x:Key="SettingsCardMinHeight">64</x:Double>
|
||||
<Thickness x:Key="SettingsCardItemMargin">0,4,0,0</Thickness>
|
||||
|
||||
<Style x:Key="StackPanelInExpanderStyle"
|
||||
TargetType="StackPanel">
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
@@ -157,6 +162,21 @@
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
</Style>
|
||||
|
||||
<!--
|
||||
Similar to a local:SettingContainer without actually being one.
|
||||
Used by data-templated rows (i.e. Actions page).
|
||||
-->
|
||||
<Style x:Key="SettingsCardStyle"
|
||||
TargetType="Grid">
|
||||
<Setter Property="MinHeight" Value="{StaticResource SettingsCardMinHeight}" />
|
||||
<Setter Property="Padding" Value="{StaticResource SettingsCardPadding}" />
|
||||
<Setter Property="Background" Value="{ThemeResource ExpanderHeaderBackground}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource ExpanderHeaderBorderBrush}" />
|
||||
<Setter Property="BorderThickness" Value="{ThemeResource ExpanderHeaderBorderThickness}" />
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SettingsPageItemHeaderStyle"
|
||||
BasedOn="{StaticResource BodyTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
|
||||
@@ -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; };
|
||||
|
||||
@@ -162,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") },
|
||||
};
|
||||
}();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -20,7 +20,6 @@ static constexpr std::string_view TabLayoutKey{ "tabLayout" };
|
||||
static constexpr std::string_view InitialPositionKey{ "initialPosition" };
|
||||
static constexpr std::string_view InitialSizeKey{ "initialSize" };
|
||||
static constexpr std::string_view LaunchModeKey{ "launchMode" };
|
||||
static constexpr std::string_view PersistedWorkspacesKey{ "persistedWorkspaces" };
|
||||
|
||||
namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||
{
|
||||
@@ -277,10 +276,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
|
||||
MTSM_APPLICATION_STATE_FIELDS(MTSM_APPLICATION_STATE_GEN)
|
||||
#undef MTSM_APPLICATION_STATE_GEN
|
||||
|
||||
// Manually handled because IMap<K,V> has a comma that breaks the X-macro.
|
||||
if (WI_IsFlagSet(parseSource, FileSource::Local))
|
||||
state->PersistedWorkspaces = JsonUtils::GetValueForKey<std::optional<Windows::Foundation::Collections::IMap<hstring, Model::WindowLayout>>>(root, PersistedWorkspacesKey);
|
||||
}
|
||||
|
||||
Json::Value ApplicationState::ToJson(FileSource parseSource) const noexcept
|
||||
@@ -303,10 +298,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
|
||||
MTSM_APPLICATION_STATE_FIELDS(MTSM_APPLICATION_STATE_GEN)
|
||||
#undef MTSM_APPLICATION_STATE_GEN
|
||||
|
||||
// Manually handled because IMap<K,V> has a comma that breaks the X-macro.
|
||||
if (WI_IsFlagSet(parseSource, FileSource::Local))
|
||||
JsonUtils::SetValueForKey(root, PersistedWorkspacesKey, state->PersistedWorkspaces);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
@@ -350,114 +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.
|
||||
// Return Value:
|
||||
// - true if an entry was renamed, false otherwise.
|
||||
bool ApplicationState::RenameWorkspace(const hstring& oldName, const hstring& newName)
|
||||
{
|
||||
if (oldName == newName || oldName.empty() || newName.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool renamed{ false };
|
||||
{
|
||||
const auto state = _state.lock();
|
||||
if (state->PersistedWorkspaces && *state->PersistedWorkspaces)
|
||||
{
|
||||
auto map = *state->PersistedWorkspaces;
|
||||
if (map.HasKey(oldName))
|
||||
{
|
||||
const auto layout = map.Lookup(oldName);
|
||||
map.Insert(newName, layout);
|
||||
map.Remove(oldName);
|
||||
renamed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (renamed)
|
||||
{
|
||||
_throttler();
|
||||
}
|
||||
return renamed;
|
||||
}
|
||||
|
||||
// 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 \
|
||||
|
||||
@@ -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
|
||||
{
|
||||
@@ -75,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; \
|
||||
@@ -94,8 +88,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
#define MTSM_APPLICATION_STATE_GEN(source, type, name, key, ...) std::optional<type> name{ __VA_ARGS__ };
|
||||
MTSM_APPLICATION_STATE_FIELDS(MTSM_APPLICATION_STATE_GEN)
|
||||
#undef MTSM_APPLICATION_STATE_GEN
|
||||
// Manually declared because IMap<K,V> has a comma that breaks the macro.
|
||||
std::optional<Windows::Foundation::Collections::IMap<hstring, Model::WindowLayout>> PersistedWorkspaces;
|
||||
};
|
||||
til::shared_mutex<state_t> _state;
|
||||
std::filesystem::path _sharedPath;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -102,14 +102,6 @@ winrt::com_ptr<GlobalAppSettings> GlobalAppSettings::Copy() const
|
||||
globals->_DisabledProfileSources->Append(src);
|
||||
}
|
||||
}
|
||||
if (_SafeUriSchemes)
|
||||
{
|
||||
globals->_SafeUriSchemes = winrt::single_threaded_vector<hstring>();
|
||||
for (const auto& src : *_SafeUriSchemes)
|
||||
{
|
||||
globals->_SafeUriSchemes->Append(src);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& parent : _parents)
|
||||
{
|
||||
|
||||
@@ -114,7 +114,6 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
INHERITABLE_SETTING(Boolean, EnableUnfocusedAcrylic);
|
||||
INHERITABLE_SETTING(Boolean, AllowHeadless);
|
||||
INHERITABLE_SETTING(String, SearchWebDefaultQueryUrl);
|
||||
INHERITABLE_SETTING(IVector<String>, SafeUriSchemes);
|
||||
|
||||
Windows.Foundation.Collections.IMapView<String, ColorScheme> ColorSchemes();
|
||||
void AddColorScheme(ColorScheme scheme);
|
||||
|
||||
@@ -136,7 +136,7 @@ private: \
|
||||
return std::nullopt; \
|
||||
} \
|
||||
\
|
||||
auto _get##name##OverrideSourceImpl() -> decltype(get_strong()) \
|
||||
auto _get##name##OverrideSourceImpl()->decltype(get_strong()) \
|
||||
{ \
|
||||
/*we have a value*/ \
|
||||
if (_##name) \
|
||||
@@ -159,7 +159,7 @@ private: \
|
||||
} \
|
||||
\
|
||||
auto _get##name##OverrideSourceAndValueImpl() \
|
||||
-> std::pair<decltype(get_strong()), storageType> \
|
||||
->std::pair<decltype(get_strong()), storageType> \
|
||||
{ \
|
||||
/*we have a value*/ \
|
||||
if (_##name) \
|
||||
|
||||
@@ -63,7 +63,6 @@ Author(s):
|
||||
X(bool, MinimizeToNotificationArea, "minimizeToNotificationArea", false) \
|
||||
X(bool, AlwaysShowNotificationIcon, "alwaysShowNotificationIcon", false) \
|
||||
X(winrt::Windows::Foundation::Collections::IVector<winrt::hstring>, DisabledProfileSources, "disabledProfileSources", nullptr) \
|
||||
X(winrt::Windows::Foundation::Collections::IVector<winrt::hstring>, SafeUriSchemes, "safeUriSchemes", nullptr) \
|
||||
X(bool, ShowAdminShield, "showAdminShield", true) \
|
||||
X(bool, TrimPaste, "trimPaste", true) \
|
||||
X(bool, EnableColorSelection, "experimental.enableColorSelection", false) \
|
||||
@@ -161,8 +160,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, ShowWindowsButton, "showWindowsButton", 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 ShowWindowsButton { 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,127 +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"));
|
||||
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"));
|
||||
}
|
||||
}
|
||||
@@ -467,7 +467,6 @@ namespace SettingsModelUnitTests
|
||||
"$schema" : "https://aka.ms/terminal-profiles-schema",
|
||||
"defaultProfile": "{61c54bbd-1111-5271-96e7-009a87ff44bf}",
|
||||
"disabledProfileSources": [ "Windows.Terminal.Wsl" ],
|
||||
"safeUriSchemes": [ "vscode" ],
|
||||
"newTabMenu":
|
||||
[
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -123,7 +123,6 @@ class ScreenBufferTests
|
||||
TEST_METHOD(VtResizePreservingAttributes);
|
||||
|
||||
TEST_METHOD(VtSoftResetCursorPosition);
|
||||
TEST_METHOD(VtSoftResetAltBufferCursorState);
|
||||
|
||||
TEST_METHOD(VtScrollMarginsNewlineColor);
|
||||
|
||||
@@ -1511,30 +1510,6 @@ void ScreenBufferTests::VtSoftResetCursorPosition()
|
||||
VERIFY_ARE_EQUAL(til::point(1, 1), cursor.GetPosition());
|
||||
}
|
||||
|
||||
void ScreenBufferTests::VtSoftResetAltBufferCursorState()
|
||||
{
|
||||
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||
gci.LockConsole(); // Lock must be taken to manipulate buffer.
|
||||
auto unlock = wil::scope_exit([&] { gci.UnlockConsole(); });
|
||||
|
||||
auto& si = gci.GetActiveOutputBuffer();
|
||||
auto& stateMachine = si.GetStateMachine();
|
||||
|
||||
Log::Comment(L"Move cursor on the main buffer.");
|
||||
stateMachine.ProcessString(L"\x1b[4;7H");
|
||||
VERIFY_ARE_EQUAL(til::point(6, 3), si.GetTextBuffer().GetCursor().GetPosition());
|
||||
|
||||
Log::Comment(L"Enter alt buffer, soft reset, and return to main buffer.");
|
||||
stateMachine.ProcessString(L"\x1b[?1049h");
|
||||
VERIFY_IS_TRUE(gci.GetActiveOutputBuffer()._IsAltBuffer());
|
||||
stateMachine.ProcessString(L"\x1b[!p");
|
||||
stateMachine.ProcessString(L"\x1b[?1049l");
|
||||
VERIFY_IS_FALSE(gci.GetActiveOutputBuffer()._IsAltBuffer());
|
||||
|
||||
Log::Comment(L"Returning from alt buffer should restore the main cursor position.");
|
||||
VERIFY_ARE_EQUAL(til::point(6, 3), gci.GetActiveOutputBuffer().GetTextBuffer().GetCursor().GetPosition());
|
||||
}
|
||||
|
||||
void ScreenBufferTests::VtScrollMarginsNewlineColor()
|
||||
{
|
||||
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace til
|
||||
{
|
||||
namespace details
|
||||
|
||||
@@ -90,15 +90,7 @@ std::function<bool(wchar_t)> SixelParser::DefineImage(const VTInt macroParameter
|
||||
_state = States::Normal;
|
||||
_parameters.clear();
|
||||
return [&](const auto ch) {
|
||||
try
|
||||
{
|
||||
_parseCommandChar(ch);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Ignore all further content.
|
||||
return false;
|
||||
}
|
||||
_parseCommandChar(ch);
|
||||
return true;
|
||||
};
|
||||
}
|
||||
@@ -242,18 +234,10 @@ void SixelParser::_executeNextLine()
|
||||
_executeCarriageReturn();
|
||||
_imageLineCount++;
|
||||
_maybeFlushImageBuffer();
|
||||
// If we don't have any available pixel height, that means the image has
|
||||
// extended beyond the bottom of the display and we haven't triggered a
|
||||
// a scroll (because sixel display mode is enabled). In this state, there
|
||||
// is no point in extending the image any further, because the additional
|
||||
// content will never be seen, so we'll just be wasting memory.
|
||||
if (_availablePixelHeight > 0)
|
||||
{
|
||||
_imageCursor.y += _sixelHeight;
|
||||
_availablePixelHeight -= _sixelHeight;
|
||||
_resizeImageBuffer(_sixelHeight);
|
||||
_fillImageBackgroundWhenScrolled();
|
||||
}
|
||||
_imageCursor.y += _sixelHeight;
|
||||
_availablePixelHeight -= _sixelHeight;
|
||||
_resizeImageBuffer(_sixelHeight);
|
||||
_fillImageBackgroundWhenScrolled();
|
||||
}
|
||||
|
||||
void SixelParser::_executeMoveToHome()
|
||||
|
||||
@@ -3002,15 +3002,17 @@ void AdaptDispatch::SoftReset()
|
||||
SetGraphicsRendition({}); // Normal rendition.
|
||||
SetCharacterProtectionAttribute({}); // Default (unprotected)
|
||||
|
||||
// Reset only the active saved cursor state.
|
||||
// This matches xterm behavior when DECSTR is processed while using
|
||||
// the alternate screen buffer (GH#19918).
|
||||
_savedCursorState.at(_usingAltBuffer ? 1 : 0) = {};
|
||||
// Reset the saved cursor state.
|
||||
// Note that XTerm only resets the main buffer state, but that
|
||||
// seems likely to be a bug. Most other terminals reset both.
|
||||
_savedCursorState.at(0) = {}; // Main buffer
|
||||
_savedCursorState.at(1) = {}; // Alt buffer
|
||||
|
||||
// The TerminalOutput state in this buffer must be reset to
|
||||
// The TerminalOutput state in these buffers must be reset to
|
||||
// the same state as the _termOutput instance, which is not
|
||||
// necessarily equivalent to a full reset.
|
||||
_savedCursorState.at(_usingAltBuffer ? 1 : 0).TermOutput = _termOutput;
|
||||
_savedCursorState.at(0).TermOutput = _termOutput;
|
||||
_savedCursorState.at(1).TermOutput = _termOutput;
|
||||
|
||||
// Soft reset the Sixel parser if in use.
|
||||
if (_sixelParser)
|
||||
|
||||
@@ -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