Compare commits

..

55 Commits

Author SHA1 Message Date
Carlos Zamora
fe5dc94979 PRE-MERGE #20068 Add per-pane title header for split panes (#4717) 2026-05-04 20:55:47 -07:00
Carlos Zamora
8cd99a82cf PRE-MERGE #20059 Show terminal size overlay (COLSxROWS) during resize (#2833) 2026-05-04 20:55:33 -07:00
Carlos Zamora
e19a70e501 PRE-MERGE #20098 Fix settings error text legibility in High Contrast mode 2026-05-04 20:55:20 -07:00
Carlos Zamora
c161d34dd5 PRE-MERGE #20105 Clear scroll marks when clearing the buffer 2026-05-04 20:55:14 -07:00
Carlos Zamora
fbb24a949f PRE-MERGE #20155 TermControl: Remove the "hairpin" paste handler, consolidate string writers 2026-05-04 20:54:51 -07:00
Carlos Zamora
d2efaefde0 PRE-MERGE #20014 Add settings for "notifying" on "activity" 2026-05-04 20:53:20 -07:00
Carlos Zamora
3e898dd696 PRE-MERGE #20012 Add support for OSC777 (Send Notification) 2026-05-04 20:21:30 -07:00
Carlos Zamora
071963420e {0} --> ::None; remove _restoring 2026-05-04 19:04:13 -07:00
Carlos Zamora
07a4f3acfc remove .leading from throttledTaskbarProgressChanged 2026-05-04 17:57:55 -07:00
Carlos Zamora
042eb5b1a9 autoDetectRunningCommand --> bool; _autoDetectEnabled --> _autoDetectCommandActivity 2026-05-04 17:55:03 -07:00
Carlos Zamora
611f5a31b4 remove redefinition 2026-05-04 16:57:32 -07:00
Carlos Zamora
cdb99bbe8b remove duplicate NotificationEventArgs 2026-05-04 15:52:34 -07:00
Carlos Zamora
fbec4ee41f Merge branch 'main' into dev/cazamor/toast/osc777 2026-05-04 14:52:27 -07:00
Carlos Zamora
cab78edde0 address feedback 2026-05-04 14:49:03 -07:00
Carlos Zamora
b044fd661d psychically debug failed formatter 2026-05-04 12:30:00 -07:00
Carlos Zamora
234838075f notifyOnInactiveOutput --> notifyOnActivity 2026-05-04 12:18:49 -07:00
Carlos Zamora
4e6209247f Merge branch 'main' into dev/cazamor/toast/activity 2026-05-04 11:27:58 -07:00
Dustin L. Howett
441ec83514 Clarify hasAnyUnbracketed comment 2026-04-30 10:40:19 -05:00
Dustin L. Howett
39316fb266 Ah, RawWriteString was load bearing; return it as a stopgap 2026-04-30 10:12:47 -05:00
Carlos Zamora
a07dba52ef fix build 2026-04-29 19:07:09 -07:00
Carlos Zamora
fcaf3daa8d run code formatter 2026-04-29 18:24:59 -07:00
Carlos Zamora
68fccb5efb Merge branch 'main' into dev/cazamor/toast/activity 2026-04-29 18:22:19 -07:00
Carlos Zamora
6c2b796253 Address Leonard's feedback 2026-04-29 17:23:14 -07:00
Dustin L. Howett
ed93677edf Remove PasteFromClipboardEventArgs entirely 2026-04-29 19:13:31 -05:00
Dustin L. Howett
d6d3be40cc Remove the paste backflow event handler, and use WriteInputString directly 2026-04-29 19:12:25 -05:00
Dustin L. Howett
39822d1a5e Control: make bubbled events use the Control's identity as sender
I've audited all the events, and the only one that tried to use IControlInteractivity or similar was Paste
2026-04-29 19:12:24 -05:00
Dustin L. Howett
1395d17e07 TermControl: replace SendInput/PasteText with WriteInputString(Type)
and Port the rest of the app to WriteInputString
2026-04-29 19:12:22 -05:00
Carlos Zamora
d4ff09f82e use split_iterator 2026-04-29 16:32:35 -07:00
Carlos Zamora
19286b7043 spell fight 2: electric boogaloo 2026-04-29 16:32:35 -07:00
Carlos Zamora
8868dfa6ee include everything after the semicolon for body 2026-04-29 16:32:35 -07:00
Carlos Zamora
04f6273e4b 🥊spell checker🥊 2026-04-29 16:32:35 -07:00
Carlos Zamora
f483eae7a9 spell 2026-04-29 16:32:35 -07:00
Carlos Zamora
0856bce421 DesktopNotification -> UrxvtAction; add _api.UnknownSequence() call 2026-04-29 16:32:35 -07:00
Carlos Zamora
582ffb615e Add support for OSC777 (Send Notification) 2026-04-29 16:32:34 -07:00
Carlos Zamora
da00f8863b Fix settings UI 2026-04-29 14:56:21 -07:00
Carlos Zamora
62727bf6d1 minor cleanup 2026-04-29 14:56:21 -07:00
Carlos Zamora
15ce2fd513 Add settings for "notifying" on "activity" 2026-04-29 14:56:20 -07:00
Carlos Zamora
6c88741e26 Merge branch 'main' into dev/cazamor/toast/base 2026-04-29 14:47:38 -07:00
Carlos Zamora
54009e1305 --from-toast & GetTickCount64() 2026-04-29 14:40:33 -07:00
sagarbhure-msft
fe650d0c27 Address review: fix timer lambda leak and stale font-size overlay
- Fix Tick handler lambda leak: initialize the timer and register the
  Tick handler only once on first use, then just restart the timer on
  subsequent calls (lhecker, DHowett)
- Use std::optional<SafeDispatcherTimer> to defer initialization until
  first use (lhecker)
- Remove _ShowResizeOverlay from _coreFontSizeChanged: the viewport
  dimensions are stale at that point because ControlCore still holds
  the write lock. The overlay will be shown by _SwapChainSizeChanged
  which fires after the resize completes with correct values (DHowett)
2026-04-19 13:28:32 +05:30
Carlos Zamora
b53ccb853e Suppress notification if focused; add pane data 2026-04-16 17:58:58 -07:00
SushaanthSrinivasan
ac400756e8 Add ClearMarksInRange to _EraseAll for clear/cls path 2026-04-14 19:30:01 -07:00
sagarbhure-msft
7378b8ac8c Show overlay on font-size zoom, skip in Settings preview
Show the resize overlay when Ctrl+Scroll changes font size and alters
the grid dimensions. Extract overlay logic into _ShowResizeOverlay()
helper called from both _SwapChainSizeChanged and _coreFontSizeChanged.

Skip the overlay when the control is disabled (IsEnabled() == false),
which is the case for the Settings page terminal preview.
2026-04-14 09:20:10 +05:30
sagarbhure-msft
9f2dcfd5ee Fix spell-check: replace COLSxROWS with plain text in comments 2026-04-13 23:03:26 +05:30
sagarbhure-msft
ab2514b9cc Fix code formatting in TermControl.xaml
Run Invoke-CodeFormat: reorder XAML attributes alphabetically
and normalize comment spacing per project style.
2026-04-13 22:33:04 +05:30
SushaanthSrinivasan
b21ba2b053 Clear scroll marks when clearing the buffer (#20086) 2026-04-11 13:44:19 -07:00
SushaanthSrinivasan
1ecb08351b Skip error text color override in High Contrast mode (#18147)
SystemErrorTextColor doesn't adapt to High Contrast themes, making
the settings error text illegible. In HC mode, let the text inherit
the system foreground from its parent element instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 22:19:40 -07:00
sagarbhure-msft
5279226646 Add showPaneHeaders global appearance setting
Adds a 'showPaneHeaders' boolean setting (default: true) to control
whether per-pane title headers are displayed when multiple panes are
open. The setting is available in Settings > Appearance as a toggle
and persists via settings.json.

Headers are refreshed live when the setting is changed — toggling off
hides headers on all existing panes immediately.
2026-04-07 22:12:09 +05:30
sagarbhure-msft
c7a51c978c Show terminal size overlay (COLSxROWS) during resize (#2833)
Display a centered overlay showing columns x rows when the terminal
control is resized. The overlay auto-hides after 750ms of inactivity.

- Add ResizeOverlay Border element to TermControl.xaml
- Add ViewWidth() to ControlCore (matches existing ViewHeight())
- Show overlay in _SwapChainSizeChanged using SafeDispatcherTimer
- Use fmt::format for string formatting

Closes #2833
2026-04-04 10:10:47 +05:30
sagarbhure-msft
44456be4eb Add per-pane title header for split panes (#4717)
Shows a thin title bar above each pane when multiple panes are open.
Headers display the pane title, update dynamically via Dispatcher when
the shell changes the title (e.g. via escape sequences), and use the
focus-state border color as background. Hidden when only one pane exists.

The header is placed directly in the pane root Grid (row 0, auto-sized)
with the content border in row 1 (star-sized), keeping the TermControl
as the direct child of the border so SwapChainPanel renders correctly.
2026-04-04 09:34:49 +05:30
Carlos Zamora
5f3db13e5f fix extra window and reorder/glom scenarios 2026-03-26 18:12:08 -07:00
Carlos Zamora
9df166efec Send notifications even when we're unpackaged (#20013)
## Summary of the Pull Request
Targets #20010 

Manually assign an AUMID to our process when we're running unpackaged.
Main difference from #19937 is what AUMID we use. Before, it was per
branding, but the `WindowEmperor` already appends an exe path hash for
unpackaged instances to prevent crosstalk. Here, we're just using the
same pattern: `Microsoft.WindowsTerminal.<hash>`.

Heavily based on #19937
Co-authored by @zadjii-msft
2026-03-25 13:27:12 -07:00
Carlos Zamora
aeb531f666 spell; prefer AppDisplayName; use C++20 designated init 2026-03-25 10:29:06 -07:00
Carlos Zamora
c23e507c20 spell 2026-03-25 10:29:06 -07:00
Carlos Zamora
c49bc1a789 Add toast notification infrastructure 2026-03-25 10:29:06 -07:00
152 changed files with 2150 additions and 4750 deletions

View File

@@ -1755,6 +1755,7 @@ UPKEY
upss
uregex
URegular
urxvt
usebackq
USECALLBACK
USECOLOR

View File

@@ -2472,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",
@@ -2794,6 +2787,11 @@
"description": "When set to true, VT applications will be allowed to set the contents of the local clipboard using OSC 52 (Manipulate Selection Data).",
"type": "boolean"
},
"compatibility.allowOSC777": {
"default": true,
"description": "When set to true, applications can send OSC 777 escape sequences to trigger desktop toast notifications with a custom title and body.",
"type": "boolean"
},
"unfocusedAppearance": {
"$ref": "#/$defs/AppearanceConfig",
"description": "Sets the appearance of the terminal when it is unfocused.",
@@ -2869,6 +2867,73 @@
"description": "Sets the sound played when the application emits a BEL. When set to an array, the terminal will pick one of those sounds at random.",
"$ref": "#/$defs/BellSound"
},
"notifyOnActivity": {
"oneOf": [
{
"type": "boolean"
},
{
"type": "array",
"items": {
"type": "string",
"enum": [
"taskbar",
"audible",
"tab",
"notification"
]
}
},
{
"type": "string",
"enum": [
"taskbar",
"audible",
"tab",
"notification",
"all",
"none"
]
}
],
"description": "Controls how you are notified when an inactive tab produces new output."
},
"notifyOnNextPrompt": {
"oneOf": [
{
"type": "boolean"
},
{
"type": "array",
"items": {
"type": "string",
"enum": [
"taskbar",
"audible",
"tab",
"notification"
]
}
},
{
"type": "string",
"enum": [
"taskbar",
"audible",
"tab",
"notification",
"all",
"none"
]
}
],
"description": "Controls how you are notified when a new shell prompt is detected. Requires shell integration."
},
"autoDetectRunningCommand": {
"default": false,
"description": "Automatically detect when a command is running and show a progress indicator in the tab and taskbar.",
"type": "boolean"
},
"closeOnExit": {
"default": "automatic",
"description": "Sets how the profile reacts to termination or failure to launch. Possible values:\n -\"graceful\" (close when exit is typed or the process exits normally)\n -\"always\" (always close)\n -\"automatic\" (behave as \"graceful\" only for processes launched by terminal, behave as \"always\" otherwise)\n -\"never\" (never close).\ntrue and false are accepted as synonyms for \"graceful\" and \"never\" respectively.",

View File

@@ -185,7 +185,7 @@ namespace winrt::TerminalApp::implementation
{
if (const auto termControl{ _senderOrActiveControl(sender) })
{
termControl.SendInput(realArgs.Input());
termControl.WriteInputString(realArgs.Input(), WriteInputStringType::Raw);
args.Handled(true);
}
}
@@ -452,8 +452,11 @@ namespace winrt::TerminalApp::implementation
void TerminalPage::_HandlePasteText(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
_PasteText();
args.Handled(true);
if (const auto& control{ _GetActiveControl() })
{
_PasteFromClipboardHandler(control, nullptr);
args.Handled(true);
}
}
void TerminalPage::_HandleNewTab(const IInspectable& /*sender*/,
@@ -499,8 +502,8 @@ namespace winrt::TerminalApp::implementation
}
else
{
const auto resizeSucceeded = _ResizePane(realArgs.ResizeDirection());
args.Handled(resizeSucceeded);
_ResizePane(realArgs.ResizeDirection());
args.Handled(true);
}
}
}

View File

@@ -4,8 +4,6 @@
#include "pch.h"
#include "DesktopNotification.h"
#include <WtExeUtils.h>
using namespace winrt::Windows::UI::Notifications;
using namespace winrt::Windows::Data::Xml::Dom;
@@ -91,32 +89,25 @@ namespace winrt::TerminalApp::implementation
// When the user activates (clicks) the toast, fire the callback.
if (activatedFunc)
{
toast.Activated([activatedFunc](const auto& /*sender*/, const auto& /*eventArgs*/) {
toast.Activated([activatedFunc = std::move(activatedFunc)](const auto& /*sender*/, const auto& /*eventArgs*/) {
activatedFunc();
});
}
// For packaged apps, CreateToastNotifier() uses the package identity automatically.
// For unpackaged apps, we must pass the explicit AUMID that was registered
// at startup via SetCurrentProcessExplicitAppUserModelID.
winrt::Windows::UI::Notifications::ToastNotifier notifier{ nullptr };
if (IsPackaged())
// Get the AUMID for the current process. For packaged apps this is
// the AUMID set by the package manifest (PackageFamilyName!AppId).
// For unpackaged apps this is the AUMID registered at startup via
// SetCurrentProcessExplicitAppUserModelID in WindowEmperor.
// Calling CreateToastNotifier with the app's own AUMID is permitted
// in both cases, so we can use a single code path.
wil::unique_cotaskmem_string aumid;
if (FAILED(GetCurrentProcessExplicitAppUserModelID(&aumid)))
{
notifier = ToastNotificationManager::CreateToastNotifier();
}
else
{
// Retrieve the AUMID that was set by WindowEmperor at startup.
wil::unique_cotaskmem_string aumid;
if (SUCCEEDED(GetCurrentProcessExplicitAppUserModelID(&aumid)))
{
notifier = ToastNotificationManager::CreateToastNotifier(aumid.get());
}
}
if (notifier)
{
notifier.Show(toast);
return;
}
const auto notifier = ToastNotificationManager::CreateToastNotifier(aumid.get());
notifier.Show(toast);
}
catch (...)
{

View File

@@ -21,6 +21,8 @@ namespace TerminalApp
{
String Title { get; };
String Body { get; };
Microsoft.Terminal.Control.OutputNotificationStyle Style { get; };
Boolean OnlyWhenInactive { get; };
};
interface IPaneContent
@@ -31,7 +33,7 @@ namespace TerminalApp
Windows.Foundation.Size MinimumSize { get; };
String Title { get; };
UInt64 TaskbarState { get; };
Microsoft.Terminal.Control.TaskbarState TaskbarState { get; };
UInt64 TaskbarProgress { get; };
Boolean ReadOnly { get; };
String Icon { get; };

View File

@@ -33,7 +33,7 @@ namespace winrt::TerminalApp::implementation
winrt::Microsoft::Terminal::Settings::Model::INewContentArgs GetNewTerminalArgs(BuildStartupKind kind) const;
winrt::hstring Title() { return _filePath; }
uint64_t TaskbarState() { return 0; }
winrt::Microsoft::Terminal::Control::TaskbarState TaskbarState() { return winrt::Microsoft::Terminal::Control::TaskbarState::Clear; }
uint64_t TaskbarProgress() { return 0; }
bool ReadOnly() { return false; }
winrt::hstring Icon() const;

View File

@@ -31,10 +31,14 @@ Pane::Pane(IPaneContent content, const bool lastFocused) :
_lastActive{ lastFocused }
{
_setPaneContent(std::move(content));
_root.Children().Append(_borderFirst);
_CreatePaneHeader();
const auto& control{ _content.GetRoot() };
_borderFirst.Child(control);
// Set up leaf layout: header in _root row 0, content in _borderFirst row 1.
// The TermControl stays as the direct child of _borderFirst (no Grid wrapper)
// so the SwapChainPanel renders correctly.
_SetupLeafLayout(control);
// Register an event with the control to have it inform us when it gains focus.
if (control)
@@ -1228,6 +1232,12 @@ void Pane::UpdateVisuals()
const auto& brush{ _ComputeBorderColor() };
_borderFirst.BorderBrush(brush);
_borderSecond.BorderBrush(brush);
// Update pane header color to match focus state
if (_paneHeaderBorder && _paneHeaderBorder.Visibility() == winrt::Windows::UI::Xaml::Visibility::Visible)
{
_paneHeaderBorder.Background(brush);
}
}
// Method Description:
@@ -1450,9 +1460,9 @@ void Pane::_CloseChild(const bool closeFirst)
_root.RowDefinitions().Clear();
// Reattach the TermControl to our grid.
_root.Children().Append(_borderFirst);
_CreatePaneHeader();
const auto& control{ _content.GetRoot() };
_borderFirst.Child(control);
_SetupLeafLayout(control);
// Make sure to set our _splitState before focusing the control. If you
// fail to do this, when the tab handles the GotFocus event and asks us
@@ -1755,7 +1765,92 @@ void Pane::_setPaneContent(IPaneContent content)
}
// Method Description:
// - Sets up row/column definitions for this pane. There are three total
// - Creates the pane header UI elements (title bar shown above the content).
// The header is initially collapsed and only shown via ShowPaneHeaders().
void Pane::_CreatePaneHeader()
{
namespace WUX = winrt::Windows::UI::Xaml;
_paneHeaderText = Controls::TextBlock{};
_paneHeaderText.FontSize(12);
_paneHeaderText.Padding({ 8, 2, 8, 2 });
_paneHeaderText.IsTextSelectionEnabled(false);
_paneHeaderText.TextTrimming(WUX::TextTrimming::CharacterEllipsis);
if (_content)
{
_paneHeaderText.Text(_content.Title());
_titleChangedRevoker = _content.TitleChanged(winrt::auto_revoke, [this](auto&&, auto&&) {
_paneHeaderBorder.Dispatcher().RunAsync(
winrt::Windows::UI::Core::CoreDispatcherPriority::Normal,
[this]() {
if (_content && _paneHeaderText)
{
_paneHeaderText.Text(_content.Title());
}
});
});
}
_paneHeaderBorder = Controls::Border{};
_paneHeaderBorder.Padding({ 0, 0, 0, 0 });
_paneHeaderBorder.Child(_paneHeaderText);
_paneHeaderBorder.Visibility(WUX::Visibility::Collapsed);
}
// Method Description:
// - Sets up the leaf pane layout in _root: a header row (auto-sized) and a
// content row (star-sized). The TermControl stays as the direct child of
// _borderFirst so the SwapChainPanel renders correctly.
void Pane::_SetupLeafLayout(const winrt::Windows::UI::Xaml::UIElement& control)
{
auto headerRow = Controls::RowDefinition{};
headerRow.Height(GridLengthHelper::Auto());
auto contentRow = Controls::RowDefinition{};
contentRow.Height(GridLengthHelper::FromValueAndType(1, GridUnitType::Star));
_root.RowDefinitions().Append(headerRow);
_root.RowDefinitions().Append(contentRow);
Controls::Grid::SetRow(_paneHeaderBorder, 0);
Controls::Grid::SetRow(_borderFirst, 1);
_root.Children().Append(_paneHeaderBorder);
_root.Children().Append(_borderFirst);
if (control)
{
_borderFirst.Child(control);
}
}
// Method Description:
// - Show or hide the pane header title bar on all leaf panes in the tree.
// Called by Tab when the number of panes changes.
void Pane::ShowPaneHeaders(bool show)
{
if (_IsLeaf())
{
if (_paneHeaderBorder)
{
namespace WUX = winrt::Windows::UI::Xaml;
_paneHeaderBorder.Visibility(show ? WUX::Visibility::Visible : WUX::Visibility::Collapsed);
if (show)
{
const auto& brush = _ComputeBorderColor();
_paneHeaderBorder.Background(brush);
_paneHeaderText.Foreground(winrt::Windows::UI::Xaml::Media::SolidColorBrush(winrt::Windows::UI::Colors::White()));
}
}
}
else
{
_firstChild->ShowPaneHeaders(show);
_secondChild->ShowPaneHeaders(show);
}
}
// Method Description:
// - Sets up row/column definitions for this pane.There are three total
// row/cols. The middle one is for the separator. The first and third are for
// each of the child panes, and are given a size in pixels, based off the
// available space, and the percent of the space they respectively consume,
@@ -2321,6 +2416,10 @@ std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Pane::_Split(SplitDirect
_root.RowDefinitions().Clear();
_CreateRowColDefinitions();
// Reset Grid.Row on _borderFirst — it may have been set to row 1 in the
// leaf layout (header=row0, content=row1).
Controls::Grid::SetRow(_borderFirst, 0);
_borderFirst.Child(_firstChild->GetRootElement());
_borderSecond.Child(_secondChild->GetRootElement());
@@ -3044,14 +3143,15 @@ void Pane::BroadcastChar(const winrt::Microsoft::Terminal::Control::TermControl&
}
void Pane::BroadcastString(const winrt::Microsoft::Terminal::Control::TermControl& sourceControl,
const winrt::hstring& text)
const winrt::hstring& text,
const winrt::Microsoft::Terminal::Control::WriteInputStringType type)
{
WalkTree([&](const auto& pane) {
if (const auto& termControl{ pane->GetTerminalControl() })
{
if (termControl != sourceControl && !termControl.ReadOnly())
{
termControl.RawWriteString(text);
termControl.WriteInputStringWithoutBroadcast(text, type);
}
}
});

View File

@@ -150,9 +150,10 @@ public:
bool ContainsReadOnly() const;
void EnableBroadcast(bool enabled);
void ShowPaneHeaders(bool show);
void BroadcastKey(const winrt::Microsoft::Terminal::Control::TermControl& sourceControl, const WORD vkey, const WORD scanCode, const winrt::Microsoft::Terminal::Core::ControlKeyStates modifiers, const bool keyDown);
void BroadcastChar(const winrt::Microsoft::Terminal::Control::TermControl& sourceControl, const wchar_t vkey, const WORD scanCode, const winrt::Microsoft::Terminal::Core::ControlKeyStates modifiers);
void BroadcastString(const winrt::Microsoft::Terminal::Control::TermControl& sourceControl, const winrt::hstring& text);
void BroadcastString(const winrt::Microsoft::Terminal::Control::TermControl& sourceControl, const winrt::hstring& text, const winrt::Microsoft::Terminal::Control::WriteInputStringType type);
void UpdateResources(const PaneResources& resources);
@@ -235,6 +236,11 @@ private:
winrt::Windows::UI::Xaml::Controls::Border _borderFirst{};
winrt::Windows::UI::Xaml::Controls::Border _borderSecond{};
// Per-pane title header (visible when there are split panes)
winrt::Windows::UI::Xaml::Controls::Border _paneHeaderBorder{ nullptr };
winrt::Windows::UI::Xaml::Controls::TextBlock _paneHeaderText{ nullptr };
winrt::TerminalApp::IPaneContent::TitleChanged_revoker _titleChangedRevoker;
PaneResources _themeResources;
#pragma region Properties that need to be transferred between child / parent panes upon splitting / closing
@@ -266,6 +272,8 @@ private:
void _SetupChildCloseHandlers();
winrt::TerminalApp::IPaneContent _takePaneContent();
void _setPaneContent(winrt::TerminalApp::IPaneContent content);
void _CreatePaneHeader();
void _SetupLeafLayout(const winrt::Windows::UI::Xaml::UIElement& control);
bool _HasChild(const std::shared_ptr<Pane> child);
winrt::TerminalApp::TerminalPaneContent _getTerminalContent() const;

View File

@@ -499,48 +499,24 @@
<value>Hinweise von Drittanbietern</value>
<comment>A hyperlink name for the Terminal's third-party notices</comment>
</data>
<data name="ConfirmCloseDialog_Cancel" xml:space="preserve">
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
<value>Abbrechen</value>
</data>
<data name="ConfirmCloseDialog_CloseAllTitle" xml:space="preserve">
<data name="QuitDialog.PrimaryButtonText" xml:space="preserve">
<value>Alle schließen</value>
</data>
<data name="QuitDialog.Title" xml:space="preserve">
<value>Möchten Sie alle Fenster schließen?</value>
</data>
<data name="ConfirmCloseDialog_CloseAllPrimary" xml:space="preserve">
<data name="CloseAllDialog.CloseButtonText" xml:space="preserve">
<value>Abbrechen</value>
</data>
<data name="CloseAllDialog.PrimaryButtonText" xml:space="preserve">
<value>Alle schließen</value>
</data>
<data name="ConfirmCloseDialog_WindowTitle" xml:space="preserve">
<data name="CloseAllDialog.Title" xml:space="preserve">
<value>Möchten Sie alle Registerkarten schließen?</value>
</data>
<data name="ConfirmCloseDialog_WindowPrimary" xml:space="preserve">
<value>Alle schließen</value>
</data>
<data name="ConfirmCloseDialog_TabTitle" xml:space="preserve">
<value>Möchten Sie diese Registerkarte schließen?</value>
</data>
<data name="ConfirmCloseDialog_TabPrimary" xml:space="preserve">
<value>Registerkarte schließen</value>
</data>
<data name="ConfirmCloseDialog_PaneTitle" xml:space="preserve">
<value>Möchten Sie diesen Bereich schließen?</value>
</data>
<data name="ConfirmCloseDialog_PanePrimary" xml:space="preserve">
<value>Bereich schließen</value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsTitle" xml:space="preserve">
<value>Möchten Sie diese Registerkarten schließen?</value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsPrimary" xml:space="preserve">
<value>Registerkarten schließen</value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesTitle" xml:space="preserve">
<value>Möchten Sie diese Bereiche schließen?</value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesPrimary" xml:space="preserve">
<value>Bereiche schließen</value>
</data>
<data name="DontAskAgainCheckBox.Content" xml:space="preserve">
<value>Nicht mehr fragen</value>
</data>
<data name="CloseReadOnlyDialog.CloseButtonText" xml:space="preserve">
<value>Abbrechen</value>
</data>
@@ -772,14 +748,6 @@
<value>Windows</value>
<comment>This is displayed as a label for the context menu item that holds the submenu of available windows.</comment>
</data>
<data name="NotificationMessage_TabActivity" xml:space="preserve">
<value>Aktivität auf der Registerkarte „{0}“</value>
<comment>{0} is the tab title. Shown as the body of a desktop notification when tab activity is detected.</comment>
</data>
<data name="NotificationMessage_TabActivityInWindow" xml:space="preserve">
<value>Aktivität auf der Registerkarte „{0}“ (Fenster „{1}“)</value>
<comment>{0} is the tab title, {1} is the window name. Shown as the body of a desktop notification when tab activity is detected and the window has a name.</comment>
</data>
<data name="DropPathTabRun.Text" xml:space="preserve">
<value>Eine neue Registerkarte im angegebenen Startverzeichnis öffnen</value>
</data>
@@ -916,10 +884,10 @@
<value>Wenn diese Option festgelegt ist, wird der Befehl an den Standardbefehl des Profils angefügt, anstatt ihn zu ersetzen.</value>
</data>
<data name="RestartConnectionText" xml:space="preserve">
<value>Sitzung neu starten</value>
<value>Verbindung neu starten</value>
</data>
<data name="RestartConnectionToolTip" xml:space="preserve">
<value>Sitzung im aktiven Bereich neu starten</value>
<value>Verbindung mit aktivem Bereich neu starten</value>
</data>
<data name="SnippetPaneTitle.Text" xml:space="preserve">
<value>Schnipsel</value>

View File

@@ -496,48 +496,24 @@
<value>Avisos de terceros</value>
<comment>A hyperlink name for the Terminal's third-party notices</comment>
</data>
<data name="ConfirmCloseDialog_Cancel" xml:space="preserve">
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
<value>Cancelar</value>
</data>
<data name="ConfirmCloseDialog_CloseAllTitle" xml:space="preserve">
<data name="QuitDialog.PrimaryButtonText" xml:space="preserve">
<value>Cerrar todo</value>
</data>
<data name="QuitDialog.Title" xml:space="preserve">
<value>¿Quiere cerrar todas las ventanas?</value>
</data>
<data name="ConfirmCloseDialog_CloseAllPrimary" xml:space="preserve">
<data name="CloseAllDialog.CloseButtonText" xml:space="preserve">
<value>Cancelar</value>
</data>
<data name="CloseAllDialog.PrimaryButtonText" xml:space="preserve">
<value>Cerrar todo</value>
</data>
<data name="ConfirmCloseDialog_WindowTitle" xml:space="preserve">
<data name="CloseAllDialog.Title" xml:space="preserve">
<value>¿Quieres cerrar todas las pestañas?</value>
</data>
<data name="ConfirmCloseDialog_WindowPrimary" xml:space="preserve">
<value>Cerrar todo</value>
</data>
<data name="ConfirmCloseDialog_TabTitle" xml:space="preserve">
<value>¿Desea cerrar esta pestaña?</value>
</data>
<data name="ConfirmCloseDialog_TabPrimary" xml:space="preserve">
<value>Cerrar pestaña</value>
</data>
<data name="ConfirmCloseDialog_PaneTitle" xml:space="preserve">
<value>¿Desea cerrar este panel?</value>
</data>
<data name="ConfirmCloseDialog_PanePrimary" xml:space="preserve">
<value>Cerrar panel</value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsTitle" xml:space="preserve">
<value>¿Desea cerrar estas pestañas?</value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsPrimary" xml:space="preserve">
<value>Cerrar pestañas</value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesTitle" xml:space="preserve">
<value>¿Desea cerrar estos paneles?</value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesPrimary" xml:space="preserve">
<value>Cerrar paneles</value>
</data>
<data name="DontAskAgainCheckBox.Content" xml:space="preserve">
<value>No volver a preguntarme</value>
</data>
<data name="CloseReadOnlyDialog.CloseButtonText" xml:space="preserve">
<value>Cancelar</value>
</data>
@@ -769,14 +745,6 @@
<value>Windows</value>
<comment>This is displayed as a label for the context menu item that holds the submenu of available windows.</comment>
</data>
<data name="NotificationMessage_TabActivity" xml:space="preserve">
<value>Actividad en la pestaña "{0}"</value>
<comment>{0} is the tab title. Shown as the body of a desktop notification when tab activity is detected.</comment>
</data>
<data name="NotificationMessage_TabActivityInWindow" xml:space="preserve">
<value>Actividad en la pestaña "{0}" (ventana "{1}")</value>
<comment>{0} is the tab title, {1} is the window name. Shown as the body of a desktop notification when tab activity is detected and the window has a name.</comment>
</data>
<data name="DropPathTabRun.Text" xml:space="preserve">
<value>Abrir una nueva pestaña en un directorio de inicio determinado</value>
</data>
@@ -913,10 +881,10 @@
<value>Si se establece, el comando se anexará al comando predeterminado del perfil en lugar de reemplazarlo.</value>
</data>
<data name="RestartConnectionText" xml:space="preserve">
<value>Reiniciar sesión</value>
<value>Reiniciar conexión</value>
</data>
<data name="RestartConnectionToolTip" xml:space="preserve">
<value>Reiniciar la sesión en el panel activo</value>
<value>Reiniciar la conexión del panel activo</value>
</data>
<data name="SnippetPaneTitle.Text" xml:space="preserve">
<value>Fragmentos</value>

View File

@@ -496,48 +496,24 @@
<value>Mentions tierces</value>
<comment>A hyperlink name for the Terminal's third-party notices</comment>
</data>
<data name="ConfirmCloseDialog_Cancel" xml:space="preserve">
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
<value>Annuler</value>
</data>
<data name="ConfirmCloseDialog_CloseAllTitle" xml:space="preserve">
<data name="QuitDialog.PrimaryButtonText" xml:space="preserve">
<value>Fermer tout</value>
</data>
<data name="QuitDialog.Title" xml:space="preserve">
<value>Voulez-vous fermer toutes les fenêtres ?</value>
</data>
<data name="ConfirmCloseDialog_CloseAllPrimary" xml:space="preserve">
<data name="CloseAllDialog.CloseButtonText" xml:space="preserve">
<value>Annuler</value>
</data>
<data name="CloseAllDialog.PrimaryButtonText" xml:space="preserve">
<value>Fermer tout</value>
</data>
<data name="ConfirmCloseDialog_WindowTitle" xml:space="preserve">
<data name="CloseAllDialog.Title" xml:space="preserve">
<value>Voulez-vous fermer tous les onglets ?</value>
</data>
<data name="ConfirmCloseDialog_WindowPrimary" xml:space="preserve">
<value>Fermer tout</value>
</data>
<data name="ConfirmCloseDialog_TabTitle" xml:space="preserve">
<value>Voulez-vous fermer cet onglet ?</value>
</data>
<data name="ConfirmCloseDialog_TabPrimary" xml:space="preserve">
<value>Fermer l'onglet</value>
</data>
<data name="ConfirmCloseDialog_PaneTitle" xml:space="preserve">
<value>Voulez-vous fermer ce volet ?</value>
</data>
<data name="ConfirmCloseDialog_PanePrimary" xml:space="preserve">
<value>Fermer le volet</value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsTitle" xml:space="preserve">
<value>Voulez-vous fermer ces onglets ?</value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsPrimary" xml:space="preserve">
<value>Fermer les onglets</value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesTitle" xml:space="preserve">
<value>Voulez-vous fermer ces volets ?</value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesPrimary" xml:space="preserve">
<value>Fermer les panneaux</value>
</data>
<data name="DontAskAgainCheckBox.Content" xml:space="preserve">
<value>Ne plus me le demander</value>
</data>
<data name="CloseReadOnlyDialog.CloseButtonText" xml:space="preserve">
<value>Annuler</value>
</data>
@@ -769,14 +745,6 @@
<value>Windows</value>
<comment>This is displayed as a label for the context menu item that holds the submenu of available windows.</comment>
</data>
<data name="NotificationMessage_TabActivity" xml:space="preserve">
<value>Activité sous longlet « {0} »</value>
<comment>{0} is the tab title. Shown as the body of a desktop notification when tab activity is detected.</comment>
</data>
<data name="NotificationMessage_TabActivityInWindow" xml:space="preserve">
<value>Activité sous longlet « {0} » (fenêtre « {1} »)</value>
<comment>{0} is the tab title, {1} is the window name. Shown as the body of a desktop notification when tab activity is detected and the window has a name.</comment>
</data>
<data name="DropPathTabRun.Text" xml:space="preserve">
<value>Ouvrez un nouvel onglet dans le répertoire correspondant</value>
</data>
@@ -913,10 +881,10 @@
<value>Si elle est définie, la commande sera ajoutée à la commande par défaut du profil au lieu de la remplacer.</value>
</data>
<data name="RestartConnectionText" xml:space="preserve">
<value>Redémarrer la session</value>
<value>Redémarrer la connexion</value>
</data>
<data name="RestartConnectionToolTip" xml:space="preserve">
<value>Redémarrez la session dans le volet actif</value>
<value>Redémarrer la connexion du volet actif</value>
</data>
<data name="SnippetPaneTitle.Text" xml:space="preserve">
<value>Extraits</value>

View File

@@ -496,48 +496,24 @@
<value>Comunicazioni di terze parti</value>
<comment>A hyperlink name for the Terminal's third-party notices</comment>
</data>
<data name="ConfirmCloseDialog_Cancel" xml:space="preserve">
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
<value>Annulla</value>
</data>
<data name="ConfirmCloseDialog_CloseAllTitle" xml:space="preserve">
<data name="QuitDialog.PrimaryButtonText" xml:space="preserve">
<value>Chiudi tutto</value>
</data>
<data name="QuitDialog.Title" xml:space="preserve">
<value>Vuoi chiudere tutte le finestre?</value>
</data>
<data name="ConfirmCloseDialog_CloseAllPrimary" xml:space="preserve">
<data name="CloseAllDialog.CloseButtonText" xml:space="preserve">
<value>Annulla</value>
</data>
<data name="CloseAllDialog.PrimaryButtonText" xml:space="preserve">
<value>Chiudi tutto</value>
</data>
<data name="ConfirmCloseDialog_WindowTitle" xml:space="preserve">
<data name="CloseAllDialog.Title" xml:space="preserve">
<value>Vuoi chiudere tutte le schede?</value>
</data>
<data name="ConfirmCloseDialog_WindowPrimary" xml:space="preserve">
<value>Chiudi tutto</value>
</data>
<data name="ConfirmCloseDialog_TabTitle" xml:space="preserve">
<value>Vuoi chiudere questa scheda?</value>
</data>
<data name="ConfirmCloseDialog_TabPrimary" xml:space="preserve">
<value>Chiudi scheda</value>
</data>
<data name="ConfirmCloseDialog_PaneTitle" xml:space="preserve">
<value>Vuoi chiudere questo riquadro?</value>
</data>
<data name="ConfirmCloseDialog_PanePrimary" xml:space="preserve">
<value>Chiudi riquadro</value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsTitle" xml:space="preserve">
<value>Vuoi chiudere queste schede?</value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsPrimary" xml:space="preserve">
<value>Chiudi schede</value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesTitle" xml:space="preserve">
<value>Vuoi chiudere questi riquadri?</value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesPrimary" xml:space="preserve">
<value>Chiudi riquadri</value>
</data>
<data name="DontAskAgainCheckBox.Content" xml:space="preserve">
<value>Non chiedermelo più</value>
</data>
<data name="CloseReadOnlyDialog.CloseButtonText" xml:space="preserve">
<value>Annulla</value>
</data>
@@ -769,14 +745,6 @@
<value>Windows</value>
<comment>This is displayed as a label for the context menu item that holds the submenu of available windows.</comment>
</data>
<data name="NotificationMessage_TabActivity" xml:space="preserve">
<value>Attività nella scheda "{0}"</value>
<comment>{0} is the tab title. Shown as the body of a desktop notification when tab activity is detected.</comment>
</data>
<data name="NotificationMessage_TabActivityInWindow" xml:space="preserve">
<value>Attività nella scheda "{0}" (finestra "{1}")</value>
<comment>{0} is the tab title, {1} is the window name. Shown as the body of a desktop notification when tab activity is detected and the window has a name.</comment>
</data>
<data name="DropPathTabRun.Text" xml:space="preserve">
<value>Apri una nuova scheda nella directory di avvio specificata</value>
</data>
@@ -913,10 +881,10 @@
<value>Se impostato, il comando verrà aggiunto al comando predefinito del profilo invece di sostituirlo.</value>
</data>
<data name="RestartConnectionText" xml:space="preserve">
<value>Riavvia la sessione</value>
<value>Riavvia connessione</value>
</data>
<data name="RestartConnectionToolTip" xml:space="preserve">
<value>Riavvia la sessione nel riquadro attivo</value>
<value>Riavvia la connessione al riquadro attivo</value>
</data>
<data name="SnippetPaneTitle.Text" xml:space="preserve">
<value>Frammenti</value>

View File

@@ -497,48 +497,24 @@
<value>サード パーティ通知</value>
<comment>A hyperlink name for the Terminal's third-party notices</comment>
</data>
<data name="ConfirmCloseDialog_Cancel" xml:space="preserve">
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
<value>キャンセル</value>
</data>
<data name="ConfirmCloseDialog_CloseAllTitle" xml:space="preserve">
<data name="QuitDialog.PrimaryButtonText" xml:space="preserve">
<value>すべて閉じる</value>
</data>
<data name="QuitDialog.Title" xml:space="preserve">
<value>すべてのウィンドウを閉じますか?</value>
</data>
<data name="ConfirmCloseDialog_CloseAllPrimary" xml:space="preserve">
<data name="CloseAllDialog.CloseButtonText" xml:space="preserve">
<value>キャンセル</value>
</data>
<data name="CloseAllDialog.PrimaryButtonText" xml:space="preserve">
<value>すべて閉じる</value>
</data>
<data name="ConfirmCloseDialog_WindowTitle" xml:space="preserve">
<data name="CloseAllDialog.Title" xml:space="preserve">
<value>すべてのタブを閉じますか?</value>
</data>
<data name="ConfirmCloseDialog_WindowPrimary" xml:space="preserve">
<value>すべて閉じる</value>
</data>
<data name="ConfirmCloseDialog_TabTitle" xml:space="preserve">
<value>このタブを閉じますか?</value>
</data>
<data name="ConfirmCloseDialog_TabPrimary" xml:space="preserve">
<value>タブを閉じる</value>
</data>
<data name="ConfirmCloseDialog_PaneTitle" xml:space="preserve">
<value>このウィンドウを閉じますか?</value>
</data>
<data name="ConfirmCloseDialog_PanePrimary" xml:space="preserve">
<value>ウィンドウを閉じる</value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsTitle" xml:space="preserve">
<value>これらのタブを閉じますか?</value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsPrimary" xml:space="preserve">
<value>タブを閉じる</value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesTitle" xml:space="preserve">
<value>これらのウィンドウを閉じますか?</value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesPrimary" xml:space="preserve">
<value>ウィンドウを閉じる</value>
</data>
<data name="DontAskAgainCheckBox.Content" xml:space="preserve">
<value>今後、このメッセージを表示しない</value>
</data>
<data name="CloseReadOnlyDialog.CloseButtonText" xml:space="preserve">
<value>キャンセル</value>
</data>
@@ -770,14 +746,6 @@
<value>Windows</value>
<comment>This is displayed as a label for the context menu item that holds the submenu of available windows.</comment>
</data>
<data name="NotificationMessage_TabActivity" xml:space="preserve">
<value>タブ "{0}" のアクティビティ</value>
<comment>{0} is the tab title. Shown as the body of a desktop notification when tab activity is detected.</comment>
</data>
<data name="NotificationMessage_TabActivityInWindow" xml:space="preserve">
<value>タブ "{0}" のアクティビティ (ウィンドウ "{1}")</value>
<comment>{0} is the tab title, {1} is the window name. Shown as the body of a desktop notification when tab activity is detected and the window has a name.</comment>
</data>
<data name="DropPathTabRun.Text" xml:space="preserve">
<value>指定された開始ディレクトリで新しいタブを開きます</value>
</data>
@@ -914,10 +882,10 @@
<value>設定されている場合、コマンドはプロファイルの既定のコマンドを置き換えるのではなく、追加されます。</value>
</data>
<data name="RestartConnectionText" xml:space="preserve">
<value>セッションの再開</value>
<value>接続の再起動</value>
</data>
<data name="RestartConnectionToolTip" xml:space="preserve">
<value>アクティブなウィンドウでセッションを再起動します</value>
<value>アクティブ ペイン接続を再起動します</value>
</data>
<data name="SnippetPaneTitle.Text" xml:space="preserve">
<value>抜粋</value>

View File

@@ -496,48 +496,24 @@
<value>타사 통지</value>
<comment>A hyperlink name for the Terminal's third-party notices</comment>
</data>
<data name="ConfirmCloseDialog_Cancel" xml:space="preserve">
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
<value>취소</value>
</data>
<data name="ConfirmCloseDialog_CloseAllTitle" xml:space="preserve">
<data name="QuitDialog.PrimaryButtonText" xml:space="preserve">
<value>모두 닫기</value>
</data>
<data name="QuitDialog.Title" xml:space="preserve">
<value>모든 창을 닫으시겠습니까?</value>
</data>
<data name="ConfirmCloseDialog_CloseAllPrimary" xml:space="preserve">
<data name="CloseAllDialog.CloseButtonText" xml:space="preserve">
<value>취소</value>
</data>
<data name="CloseAllDialog.PrimaryButtonText" xml:space="preserve">
<value>모두 닫기</value>
</data>
<data name="ConfirmCloseDialog_WindowTitle" xml:space="preserve">
<data name="CloseAllDialog.Title" xml:space="preserve">
<value>모든 탭을 닫으시겠습니까?</value>
</data>
<data name="ConfirmCloseDialog_WindowPrimary" xml:space="preserve">
<value>모두 닫기</value>
</data>
<data name="ConfirmCloseDialog_TabTitle" xml:space="preserve">
<value>이 탭을 닫으시겠습니까?</value>
</data>
<data name="ConfirmCloseDialog_TabPrimary" xml:space="preserve">
<value>탭 닫기</value>
</data>
<data name="ConfirmCloseDialog_PaneTitle" xml:space="preserve">
<value>이 창을 닫으시겠습니까?</value>
</data>
<data name="ConfirmCloseDialog_PanePrimary" xml:space="preserve">
<value>창 닫기</value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsTitle" xml:space="preserve">
<value>이러한 탭을 닫으시겠습니까?</value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsPrimary" xml:space="preserve">
<value>탭 닫기</value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesTitle" xml:space="preserve">
<value>이 창을 닫으시겠습니까?</value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesPrimary" xml:space="preserve">
<value>창 닫기</value>
</data>
<data name="DontAskAgainCheckBox.Content" xml:space="preserve">
<value>다시 묻지 않기</value>
</data>
<data name="CloseReadOnlyDialog.CloseButtonText" xml:space="preserve">
<value>취소</value>
</data>
@@ -769,14 +745,6 @@
<value>Windows</value>
<comment>This is displayed as a label for the context menu item that holds the submenu of available windows.</comment>
</data>
<data name="NotificationMessage_TabActivity" xml:space="preserve">
<value>"{0}" 탭의 활동</value>
<comment>{0} is the tab title. Shown as the body of a desktop notification when tab activity is detected.</comment>
</data>
<data name="NotificationMessage_TabActivityInWindow" xml:space="preserve">
<value>"{0}" 탭의 활동(창 "{1}")</value>
<comment>{0} is the tab title, {1} is the window name. Shown as the body of a desktop notification when tab activity is detected and the window has a name.</comment>
</data>
<data name="DropPathTabRun.Text" xml:space="preserve">
<value>지정된 시작 디렉터리에서 새 탭 열기</value>
</data>
@@ -913,10 +881,10 @@
<value>설정하면 이 명령은 프로필의 기본 명령 대신 프로필의 기본 명령에 추가됩니다.</value>
</data>
<data name="RestartConnectionText" xml:space="preserve">
<value>세션 다시 시작</value>
<value>연결 다시 시작</value>
</data>
<data name="RestartConnectionToolTip" xml:space="preserve">
<value>활성 창에서 세션을 다시 시작하세요.</value>
<value>활성 창 연결 다시 시작</value>
</data>
<data name="SnippetPaneTitle.Text" xml:space="preserve">
<value>짧은 요약</value>

View File

@@ -496,48 +496,24 @@
<value>Avisos de Terceiros</value>
<comment>A hyperlink name for the Terminal's third-party notices</comment>
</data>
<data name="ConfirmCloseDialog_Cancel" xml:space="preserve">
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
<value>Cancelar</value>
</data>
<data name="ConfirmCloseDialog_CloseAllTitle" xml:space="preserve">
<data name="QuitDialog.PrimaryButtonText" xml:space="preserve">
<value>Fechar tudo</value>
</data>
<data name="QuitDialog.Title" xml:space="preserve">
<value>Deseja fechar todas as janelas?</value>
</data>
<data name="ConfirmCloseDialog_CloseAllPrimary" xml:space="preserve">
<data name="CloseAllDialog.CloseButtonText" xml:space="preserve">
<value>Cancelar</value>
</data>
<data name="CloseAllDialog.PrimaryButtonText" xml:space="preserve">
<value>Fechar tudo</value>
</data>
<data name="ConfirmCloseDialog_WindowTitle" xml:space="preserve">
<data name="CloseAllDialog.Title" xml:space="preserve">
<value>Deseja fechar todas as guias?</value>
</data>
<data name="ConfirmCloseDialog_WindowPrimary" xml:space="preserve">
<value>Fechar tudo</value>
</data>
<data name="ConfirmCloseDialog_TabTitle" xml:space="preserve">
<value>Deseja fechar esta guia?</value>
</data>
<data name="ConfirmCloseDialog_TabPrimary" xml:space="preserve">
<value>Fechar guia</value>
</data>
<data name="ConfirmCloseDialog_PaneTitle" xml:space="preserve">
<value>Deseja fechar este painel?</value>
</data>
<data name="ConfirmCloseDialog_PanePrimary" xml:space="preserve">
<value>Fechar painel</value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsTitle" xml:space="preserve">
<value>Deseja fechar estas guias?</value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsPrimary" xml:space="preserve">
<value>Fechar guias</value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesTitle" xml:space="preserve">
<value>Deseja fechar estes painéis?</value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesPrimary" xml:space="preserve">
<value>Fechar painéis</value>
</data>
<data name="DontAskAgainCheckBox.Content" xml:space="preserve">
<value>Não me pergunte novamente</value>
</data>
<data name="CloseReadOnlyDialog.CloseButtonText" xml:space="preserve">
<value>Cancelar</value>
</data>
@@ -769,14 +745,6 @@
<value>Windows</value>
<comment>This is displayed as a label for the context menu item that holds the submenu of available windows.</comment>
</data>
<data name="NotificationMessage_TabActivity" xml:space="preserve">
<value>Atividade na aba "{0}"</value>
<comment>{0} is the tab title. Shown as the body of a desktop notification when tab activity is detected.</comment>
</data>
<data name="NotificationMessage_TabActivityInWindow" xml:space="preserve">
<value>Atividade na aba "{0}" (janela "{1}")</value>
<comment>{0} is the tab title, {1} is the window name. Shown as the body of a desktop notification when tab activity is detected and the window has a name.</comment>
</data>
<data name="DropPathTabRun.Text" xml:space="preserve">
<value>Abrir uma nova guia no diretório inicial fornecido</value>
</data>
@@ -913,10 +881,10 @@
<value>Se definido, o comando será acrescentado ao comando padrão do perfil em vez de substituí-lo.</value>
</data>
<data name="RestartConnectionText" xml:space="preserve">
<value>Reiniciar sessão</value>
<value>Reiniciar conexão</value>
</data>
<data name="RestartConnectionToolTip" xml:space="preserve">
<value>Reinicie a sessão no painel ativo</value>
<value>Reiniciar a conexão do painel ativo</value>
</data>
<data name="SnippetPaneTitle.Text" xml:space="preserve">
<value>Trechos</value>

View File

@@ -496,47 +496,23 @@
<value>Ţћĩřð-Ρářŧγ ñοŧīĉęŝ !!! !!!</value>
<comment>A hyperlink name for the Terminal's third-party notices</comment>
</data>
<data name="ConfirmCloseDialog_Cancel" xml:space="preserve">
<value>Ĉάйçэļ !</value>
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
<value>Ċдйĉέł !</value>
</data>
<data name="ConfirmCloseDialog_CloseAllTitle" xml:space="preserve">
<value>Ďő убυ ẅåήт ţø ¢ľöѕē äľľ ẃιⁿðŏŵş? !!! !!! !!! </value>
<data name="QuitDialog.PrimaryButtonText" xml:space="preserve">
<value>€ļőşε áļľ !!!</value>
</data>
<data name="ConfirmCloseDialog_CloseAllPrimary" xml:space="preserve">
<value>Ċľóѕε ªĺĺ !!!</value>
<data name="QuitDialog.Title" xml:space="preserve">
<value>Ďõ γбű ẁāŋţ ťó ςℓσśĕ äℓℓ шîйđбẁś? !!! !!! !!! </value>
</data>
<data name="ConfirmCloseDialog_WindowTitle" xml:space="preserve">
<value>Ďō γőű шдπŧ ŧò ςłοѕз āĺℓ ţäьš? !!! !!! !!!</value>
<data name="CloseAllDialog.CloseButtonText" xml:space="preserve">
<value>Ćăʼnċęℓ !</value>
</data>
<data name="ConfirmCloseDialog_WindowPrimary" xml:space="preserve">
<value>Ĉŀõśê āłĺ !!!</value>
<data name="CloseAllDialog.PrimaryButtonText" xml:space="preserve">
<value>Ćļõѕέ аłℓ !!!</value>
</data>
<data name="ConfirmCloseDialog_TabTitle" xml:space="preserve">
<value>Đó уøυ ẅāńť тο çŀǿśę ŧĥíš τάъ? !!! !!! !!!</value>
</data>
<data name="ConfirmCloseDialog_TabPrimary" xml:space="preserve">
<value>Ċℓοѕē ţαъ !!!</value>
</data>
<data name="ConfirmCloseDialog_PaneTitle" xml:space="preserve">
<value>Đò γθũ ώăńт ťǿ ¢ℓσŝę ŧħîŝ ρаńе? !!! !!! !!!</value>
</data>
<data name="ConfirmCloseDialog_PanePrimary" xml:space="preserve">
<value>Ĉŀбśз φдŋё !!!</value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsTitle" xml:space="preserve">
<value>Đó ўоú ŵąňτ ŧò çŀσѕė ŧћěśé ţдьş? !!! !!! !!! </value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsPrimary" xml:space="preserve">
<value>Ćŀöśé ŧãвś !!!</value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesTitle" xml:space="preserve">
<value>Ðǿ ỳбū ŵáήť ŧо ćļόśě τнέšê φăñєš? !!! !!! !!! </value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesPrimary" xml:space="preserve">
<value>€łǿśē рāⁿęѕ !!!</value>
</data>
<data name="DontAskAgainCheckBox.Content" xml:space="preserve">
<value>Đòñ'ť ªѕķ мë àĝáîⁿ !!! !!</value>
<data name="CloseAllDialog.Title" xml:space="preserve">
<value>Đσ ŷőū шдиŧ тò čļòŝз αŀľ ţâвŝ? !!! !!! !!!</value>
</data>
<data name="CloseReadOnlyDialog.CloseButtonText" xml:space="preserve">
<value>Čǻñčėŀ !</value>
@@ -769,14 +745,6 @@
<value>Ẃϊйδοŵš !!</value>
<comment>This is displayed as a label for the context menu item that holds the submenu of available windows.</comment>
</data>
<data name="NotificationMessage_TabActivity" xml:space="preserve">
<value>Δćţíνïŧý īй τаь "{0}" !!! !!!</value>
<comment>{0} is the tab title. Shown as the body of a desktop notification when tab activity is detected.</comment>
</data>
<data name="NotificationMessage_TabActivityInWindow" xml:space="preserve">
<value>Δсŧìνιŧý įņ ţªь "{0}" (ŵϊņδόώ "{1}") !!! !!! !!! !</value>
<comment>{0} is the tab title, {1} is the window name. Shown as the body of a desktop notification when tab activity is detected and the window has a name.</comment>
</data>
<data name="DropPathTabRun.Text" xml:space="preserve">
<value>Фφĕń ª пёẅ ţâь ίи ğīνęņ ѕŧāятĩлğ δįŗęćтŏяγ !!! !!! !!! !!! </value>
</data>
@@ -913,10 +881,10 @@
<value>Ĩƒ šęţ, ŧнĕ ¢ömmдлδ ŵîĺł ьέ åφрєйδĕđ τσ ŧђė рřŏƒїłє'ş đзƒªūľţ ¢οmмăńδ іñѕţέáđ øƒ ѓēρļąċĭлĝ їţ. !!! !!! !!! !!! !!! !!! !!! !!! !!! !</value>
</data>
<data name="RestartConnectionText" xml:space="preserve">
<value>Γēѕŧâяŧ ŝєѕѕïσⁿ !!! !</value>
<value>Γēѕŧâяŧ ćǿńńēčťїöл !!! !!</value>
</data>
<data name="RestartConnectionToolTip" xml:space="preserve">
<value>Γėşťáгţ ŧħ℮ ŝёšŝīőń įй τђ℮ ăċţΐνе φǻñē !!! !!! !!! !!</value>
<value>Γėşťáгţ ŧħ℮ ãčтĩνέ ρăйё сǿηńëςтιóņ !!! !!! !!! !</value>
</data>
<data name="SnippetPaneTitle.Text" xml:space="preserve">
<value>Šņíрρēťş !!</value>

View File

@@ -496,47 +496,23 @@
<value>Ţћĩřð-Ρářŧγ ñοŧīĉęŝ !!! !!!</value>
<comment>A hyperlink name for the Terminal's third-party notices</comment>
</data>
<data name="ConfirmCloseDialog_Cancel" xml:space="preserve">
<value>Ĉάйçэļ !</value>
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
<value>Ċдйĉέł !</value>
</data>
<data name="ConfirmCloseDialog_CloseAllTitle" xml:space="preserve">
<value>Ďő убυ ẅåήт ţø ¢ľöѕē äľľ ẃιⁿðŏŵş? !!! !!! !!! </value>
<data name="QuitDialog.PrimaryButtonText" xml:space="preserve">
<value>€ļőşε áļľ !!!</value>
</data>
<data name="ConfirmCloseDialog_CloseAllPrimary" xml:space="preserve">
<value>Ċľóѕε ªĺĺ !!!</value>
<data name="QuitDialog.Title" xml:space="preserve">
<value>Ďõ γбű ẁāŋţ ťó ςℓσśĕ äℓℓ шîйđбẁś? !!! !!! !!! </value>
</data>
<data name="ConfirmCloseDialog_WindowTitle" xml:space="preserve">
<value>Ďō γőű шдπŧ ŧò ςłοѕз āĺℓ ţäьš? !!! !!! !!!</value>
<data name="CloseAllDialog.CloseButtonText" xml:space="preserve">
<value>Ćăʼnċęℓ !</value>
</data>
<data name="ConfirmCloseDialog_WindowPrimary" xml:space="preserve">
<value>Ĉŀõśê āłĺ !!!</value>
<data name="CloseAllDialog.PrimaryButtonText" xml:space="preserve">
<value>Ćļõѕέ аłℓ !!!</value>
</data>
<data name="ConfirmCloseDialog_TabTitle" xml:space="preserve">
<value>Đó уøυ ẅāńť тο çŀǿśę ŧĥíš τάъ? !!! !!! !!!</value>
</data>
<data name="ConfirmCloseDialog_TabPrimary" xml:space="preserve">
<value>Ċℓοѕē ţαъ !!!</value>
</data>
<data name="ConfirmCloseDialog_PaneTitle" xml:space="preserve">
<value>Đò γθũ ώăńт ťǿ ¢ℓσŝę ŧħîŝ ρаńе? !!! !!! !!!</value>
</data>
<data name="ConfirmCloseDialog_PanePrimary" xml:space="preserve">
<value>Ĉŀбśз φдŋё !!!</value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsTitle" xml:space="preserve">
<value>Đó ўоú ŵąňτ ŧò çŀσѕė ŧћěśé ţдьş? !!! !!! !!! </value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsPrimary" xml:space="preserve">
<value>Ćŀöśé ŧãвś !!!</value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesTitle" xml:space="preserve">
<value>Ðǿ ỳбū ŵáήť ŧо ćļόśě τнέšê φăñєš? !!! !!! !!! </value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesPrimary" xml:space="preserve">
<value>€łǿśē рāⁿęѕ !!!</value>
</data>
<data name="DontAskAgainCheckBox.Content" xml:space="preserve">
<value>Đòñ'ť ªѕķ мë àĝáîⁿ !!! !!</value>
<data name="CloseAllDialog.Title" xml:space="preserve">
<value>Đσ ŷőū шдиŧ тò čļòŝз αŀľ ţâвŝ? !!! !!! !!!</value>
</data>
<data name="CloseReadOnlyDialog.CloseButtonText" xml:space="preserve">
<value>Čǻñčėŀ !</value>
@@ -769,14 +745,6 @@
<value>Ẃϊйδοŵš !!</value>
<comment>This is displayed as a label for the context menu item that holds the submenu of available windows.</comment>
</data>
<data name="NotificationMessage_TabActivity" xml:space="preserve">
<value>Δćţíνïŧý īй τаь "{0}" !!! !!!</value>
<comment>{0} is the tab title. Shown as the body of a desktop notification when tab activity is detected.</comment>
</data>
<data name="NotificationMessage_TabActivityInWindow" xml:space="preserve">
<value>Δсŧìνιŧý įņ ţªь "{0}" (ŵϊņδόώ "{1}") !!! !!! !!! !</value>
<comment>{0} is the tab title, {1} is the window name. Shown as the body of a desktop notification when tab activity is detected and the window has a name.</comment>
</data>
<data name="DropPathTabRun.Text" xml:space="preserve">
<value>Фφĕń ª пёẅ ţâь ίи ğīνęņ ѕŧāятĩлğ δįŗęćтŏяγ !!! !!! !!! !!! </value>
</data>
@@ -913,10 +881,10 @@
<value>Ĩƒ šęţ, ŧнĕ ¢ömmдлδ ŵîĺł ьέ åφрєйδĕđ τσ ŧђė рřŏƒїłє'ş đзƒªūľţ ¢οmмăńδ іñѕţέáđ øƒ ѓēρļąċĭлĝ їţ. !!! !!! !!! !!! !!! !!! !!! !!! !!! !</value>
</data>
<data name="RestartConnectionText" xml:space="preserve">
<value>Γēѕŧâяŧ ŝєѕѕïσⁿ !!! !</value>
<value>Γēѕŧâяŧ ćǿńńēčťїöл !!! !!</value>
</data>
<data name="RestartConnectionToolTip" xml:space="preserve">
<value>Γėşťáгţ ŧħ℮ ŝёšŝīőń įй τђ℮ ăċţΐνе φǻñē !!! !!! !!! !!</value>
<value>Γėşťáгţ ŧħ℮ ãčтĩνέ ρăйё сǿηńëςтιóņ !!! !!! !!! !</value>
</data>
<data name="SnippetPaneTitle.Text" xml:space="preserve">
<value>Šņíрρēťş !!</value>

View File

@@ -496,47 +496,23 @@
<value>Ţћĩřð-Ρářŧγ ñοŧīĉęŝ !!! !!!</value>
<comment>A hyperlink name for the Terminal's third-party notices</comment>
</data>
<data name="ConfirmCloseDialog_Cancel" xml:space="preserve">
<value>Ĉάйçэļ !</value>
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
<value>Ċдйĉέł !</value>
</data>
<data name="ConfirmCloseDialog_CloseAllTitle" xml:space="preserve">
<value>Ďő убυ ẅåήт ţø ¢ľöѕē äľľ ẃιⁿðŏŵş? !!! !!! !!! </value>
<data name="QuitDialog.PrimaryButtonText" xml:space="preserve">
<value>€ļőşε áļľ !!!</value>
</data>
<data name="ConfirmCloseDialog_CloseAllPrimary" xml:space="preserve">
<value>Ċľóѕε ªĺĺ !!!</value>
<data name="QuitDialog.Title" xml:space="preserve">
<value>Ďõ γбű ẁāŋţ ťó ςℓσśĕ äℓℓ шîйđбẁś? !!! !!! !!! </value>
</data>
<data name="ConfirmCloseDialog_WindowTitle" xml:space="preserve">
<value>Ďō γőű шдπŧ ŧò ςłοѕз āĺℓ ţäьš? !!! !!! !!!</value>
<data name="CloseAllDialog.CloseButtonText" xml:space="preserve">
<value>Ćăʼnċęℓ !</value>
</data>
<data name="ConfirmCloseDialog_WindowPrimary" xml:space="preserve">
<value>Ĉŀõśê āłĺ !!!</value>
<data name="CloseAllDialog.PrimaryButtonText" xml:space="preserve">
<value>Ćļõѕέ аłℓ !!!</value>
</data>
<data name="ConfirmCloseDialog_TabTitle" xml:space="preserve">
<value>Đó уøυ ẅāńť тο çŀǿśę ŧĥíš τάъ? !!! !!! !!!</value>
</data>
<data name="ConfirmCloseDialog_TabPrimary" xml:space="preserve">
<value>Ċℓοѕē ţαъ !!!</value>
</data>
<data name="ConfirmCloseDialog_PaneTitle" xml:space="preserve">
<value>Đò γθũ ώăńт ťǿ ¢ℓσŝę ŧħîŝ ρаńе? !!! !!! !!!</value>
</data>
<data name="ConfirmCloseDialog_PanePrimary" xml:space="preserve">
<value>Ĉŀбśз φдŋё !!!</value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsTitle" xml:space="preserve">
<value>Đó ўоú ŵąňτ ŧò çŀσѕė ŧћěśé ţдьş? !!! !!! !!! </value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsPrimary" xml:space="preserve">
<value>Ćŀöśé ŧãвś !!!</value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesTitle" xml:space="preserve">
<value>Ðǿ ỳбū ŵáήť ŧо ćļόśě τнέšê φăñєš? !!! !!! !!! </value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesPrimary" xml:space="preserve">
<value>€łǿśē рāⁿęѕ !!!</value>
</data>
<data name="DontAskAgainCheckBox.Content" xml:space="preserve">
<value>Đòñ'ť ªѕķ мë àĝáîⁿ !!! !!</value>
<data name="CloseAllDialog.Title" xml:space="preserve">
<value>Đσ ŷőū шдиŧ тò čļòŝз αŀľ ţâвŝ? !!! !!! !!!</value>
</data>
<data name="CloseReadOnlyDialog.CloseButtonText" xml:space="preserve">
<value>Čǻñčėŀ !</value>
@@ -769,14 +745,6 @@
<value>Ẃϊйδοŵš !!</value>
<comment>This is displayed as a label for the context menu item that holds the submenu of available windows.</comment>
</data>
<data name="NotificationMessage_TabActivity" xml:space="preserve">
<value>Δćţíνïŧý īй τаь "{0}" !!! !!!</value>
<comment>{0} is the tab title. Shown as the body of a desktop notification when tab activity is detected.</comment>
</data>
<data name="NotificationMessage_TabActivityInWindow" xml:space="preserve">
<value>Δсŧìνιŧý įņ ţªь "{0}" (ŵϊņδόώ "{1}") !!! !!! !!! !</value>
<comment>{0} is the tab title, {1} is the window name. Shown as the body of a desktop notification when tab activity is detected and the window has a name.</comment>
</data>
<data name="DropPathTabRun.Text" xml:space="preserve">
<value>Фφĕń ª пёẅ ţâь ίи ğīνęņ ѕŧāятĩлğ δįŗęćтŏяγ !!! !!! !!! !!! </value>
</data>
@@ -913,10 +881,10 @@
<value>Ĩƒ šęţ, ŧнĕ ¢ömmдлδ ŵîĺł ьέ åφрєйδĕđ τσ ŧђė рřŏƒїłє'ş đзƒªūľţ ¢οmмăńδ іñѕţέáđ øƒ ѓēρļąċĭлĝ їţ. !!! !!! !!! !!! !!! !!! !!! !!! !!! !</value>
</data>
<data name="RestartConnectionText" xml:space="preserve">
<value>Γēѕŧâяŧ ŝєѕѕïσⁿ !!! !</value>
<value>Γēѕŧâяŧ ćǿńńēčťїöл !!! !!</value>
</data>
<data name="RestartConnectionToolTip" xml:space="preserve">
<value>Γėşťáгţ ŧħ℮ ŝёšŝīőń įй τђ℮ ăċţΐνе φǻñē !!! !!! !!! !!</value>
<value>Γėşťáгţ ŧħ℮ ãčтĩνέ ρăйё сǿηńëςтιóņ !!! !!! !!! !</value>
</data>
<data name="SnippetPaneTitle.Text" xml:space="preserve">
<value>Šņíрρēťş !!</value>

View File

@@ -496,48 +496,24 @@
<value>Уведомления третьих лиц</value>
<comment>A hyperlink name for the Terminal's third-party notices</comment>
</data>
<data name="ConfirmCloseDialog_Cancel" xml:space="preserve">
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
<value>Отмена</value>
</data>
<data name="ConfirmCloseDialog_CloseAllTitle" xml:space="preserve">
<data name="QuitDialog.PrimaryButtonText" xml:space="preserve">
<value>Закрыть все</value>
</data>
<data name="QuitDialog.Title" xml:space="preserve">
<value>Закрыть все окна?</value>
</data>
<data name="ConfirmCloseDialog_CloseAllPrimary" xml:space="preserve">
<data name="CloseAllDialog.CloseButtonText" xml:space="preserve">
<value>Отмена</value>
</data>
<data name="CloseAllDialog.PrimaryButtonText" xml:space="preserve">
<value>Закрыть все</value>
</data>
<data name="ConfirmCloseDialog_WindowTitle" xml:space="preserve">
<data name="CloseAllDialog.Title" xml:space="preserve">
<value>Закрыть все вкладки?</value>
</data>
<data name="ConfirmCloseDialog_WindowPrimary" xml:space="preserve">
<value>Закрыть все</value>
</data>
<data name="ConfirmCloseDialog_TabTitle" xml:space="preserve">
<value>Закрыть эту вкладку?</value>
</data>
<data name="ConfirmCloseDialog_TabPrimary" xml:space="preserve">
<value>Закрыть вкладку</value>
</data>
<data name="ConfirmCloseDialog_PaneTitle" xml:space="preserve">
<value>Закрыть эту панель?</value>
</data>
<data name="ConfirmCloseDialog_PanePrimary" xml:space="preserve">
<value>Закрыть область</value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsTitle" xml:space="preserve">
<value>Закрыть эти вкладки?</value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsPrimary" xml:space="preserve">
<value>Закрыть вкладки</value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesTitle" xml:space="preserve">
<value>Закрыть эти панели?</value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesPrimary" xml:space="preserve">
<value>Закрыть панели</value>
</data>
<data name="DontAskAgainCheckBox.Content" xml:space="preserve">
<value>Больше не спрашивать</value>
</data>
<data name="CloseReadOnlyDialog.CloseButtonText" xml:space="preserve">
<value>Отмена</value>
</data>
@@ -769,14 +745,6 @@
<value>Windows</value>
<comment>This is displayed as a label for the context menu item that holds the submenu of available windows.</comment>
</data>
<data name="NotificationMessage_TabActivity" xml:space="preserve">
<value>Активность на вкладке "{0}"</value>
<comment>{0} is the tab title. Shown as the body of a desktop notification when tab activity is detected.</comment>
</data>
<data name="NotificationMessage_TabActivityInWindow" xml:space="preserve">
<value>Активность на вкладке "{0}" (окно "{1}")</value>
<comment>{0} is the tab title, {1} is the window name. Shown as the body of a desktop notification when tab activity is detected and the window has a name.</comment>
</data>
<data name="DropPathTabRun.Text" xml:space="preserve">
<value>Открыть новую вкладку в указанном начальном каталоге</value>
</data>
@@ -913,10 +881,10 @@
<value>Если этот параметр настроен, команда будет добавлена к стандартной команде профиля, а не заменит ее.</value>
</data>
<data name="RestartConnectionText" xml:space="preserve">
<value>Перезапустить сеанс</value>
<value>Перезапустить подключение</value>
</data>
<data name="RestartConnectionToolTip" xml:space="preserve">
<value>Перезапустите сеанс в активной панели</value>
<value>Перезапустить соединение с активной панелью.</value>
</data>
<data name="SnippetPaneTitle.Text" xml:space="preserve">
<value>Фрагменты</value>

View File

@@ -496,48 +496,24 @@
<value>第三方通知</value>
<comment>A hyperlink name for the Terminal's third-party notices</comment>
</data>
<data name="ConfirmCloseDialog_Cancel" xml:space="preserve">
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
<value>取消</value>
</data>
<data name="ConfirmCloseDialog_CloseAllTitle" xml:space="preserve">
<data name="QuitDialog.PrimaryButtonText" xml:space="preserve">
<value>全部关闭</value>
</data>
<data name="QuitDialog.Title" xml:space="preserve">
<value>是否要关闭所有窗口?</value>
</data>
<data name="ConfirmCloseDialog_CloseAllPrimary" xml:space="preserve">
<data name="CloseAllDialog.CloseButtonText" xml:space="preserve">
<value>取消</value>
</data>
<data name="CloseAllDialog.PrimaryButtonText" xml:space="preserve">
<value>全部关闭</value>
</data>
<data name="ConfirmCloseDialog_WindowTitle" xml:space="preserve">
<data name="CloseAllDialog.Title" xml:space="preserve">
<value>是否要关闭所有标签页?</value>
</data>
<data name="ConfirmCloseDialog_WindowPrimary" xml:space="preserve">
<value>全部关闭</value>
</data>
<data name="ConfirmCloseDialog_TabTitle" xml:space="preserve">
<value>是否要关闭此选项卡?</value>
</data>
<data name="ConfirmCloseDialog_TabPrimary" xml:space="preserve">
<value>关闭选项卡</value>
</data>
<data name="ConfirmCloseDialog_PaneTitle" xml:space="preserve">
<value>是否要关闭此窗格?</value>
</data>
<data name="ConfirmCloseDialog_PanePrimary" xml:space="preserve">
<value>关闭窗格</value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsTitle" xml:space="preserve">
<value>是否要关闭这些选项卡?</value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsPrimary" xml:space="preserve">
<value>关闭选项卡</value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesTitle" xml:space="preserve">
<value>是否要关闭这些窗格?</value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesPrimary" xml:space="preserve">
<value>关闭窗格</value>
</data>
<data name="DontAskAgainCheckBox.Content" xml:space="preserve">
<value>不再询问</value>
</data>
<data name="CloseReadOnlyDialog.CloseButtonText" xml:space="preserve">
<value>取消</value>
</data>
@@ -769,14 +745,6 @@
<value>Windows</value>
<comment>This is displayed as a label for the context menu item that holds the submenu of available windows.</comment>
</data>
<data name="NotificationMessage_TabActivity" xml:space="preserve">
<value>选项卡“{0}”中的活动</value>
<comment>{0} is the tab title. Shown as the body of a desktop notification when tab activity is detected.</comment>
</data>
<data name="NotificationMessage_TabActivityInWindow" xml:space="preserve">
<value>选项卡“{0}”(窗口“{1}”)中的活动</value>
<comment>{0} is the tab title, {1} is the window name. Shown as the body of a desktop notification when tab activity is detected and the window has a name.</comment>
</data>
<data name="DropPathTabRun.Text" xml:space="preserve">
<value>在给定的起始目录中打开新选项卡</value>
</data>
@@ -913,10 +881,10 @@
<value>如果设置,该命令将追加到配置文件的默认命令,而不是替换它。</value>
</data>
<data name="RestartConnectionText" xml:space="preserve">
<value>重启会话</value>
<value>重新启动连接</value>
</data>
<data name="RestartConnectionToolTip" xml:space="preserve">
<value>重活动窗格中的会话</value>
<value>重新启动活动窗格连接</value>
</data>
<data name="SnippetPaneTitle.Text" xml:space="preserve">
<value>片段</value>

View File

@@ -496,48 +496,24 @@
<value>第三方注意事項</value>
<comment>A hyperlink name for the Terminal's third-party notices</comment>
</data>
<data name="ConfirmCloseDialog_Cancel" xml:space="preserve">
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
<value>取消</value>
</data>
<data name="ConfirmCloseDialog_CloseAllTitle" xml:space="preserve">
<data name="QuitDialog.PrimaryButtonText" xml:space="preserve">
<value>全部關閉</value>
</data>
<data name="QuitDialog.Title" xml:space="preserve">
<value>您要關閉所有視窗嗎?</value>
</data>
<data name="ConfirmCloseDialog_CloseAllPrimary" xml:space="preserve">
<data name="CloseAllDialog.CloseButtonText" xml:space="preserve">
<value>取消</value>
</data>
<data name="CloseAllDialog.PrimaryButtonText" xml:space="preserve">
<value>全部關閉</value>
</data>
<data name="ConfirmCloseDialog_WindowTitle" xml:space="preserve">
<data name="CloseAllDialog.Title" xml:space="preserve">
<value>您要關閉所有索引標籤嗎?</value>
</data>
<data name="ConfirmCloseDialog_WindowPrimary" xml:space="preserve">
<value>全部關閉</value>
</data>
<data name="ConfirmCloseDialog_TabTitle" xml:space="preserve">
<value>是否要關閉此索引標籤?</value>
</data>
<data name="ConfirmCloseDialog_TabPrimary" xml:space="preserve">
<value>關閉索引標籤</value>
</data>
<data name="ConfirmCloseDialog_PaneTitle" xml:space="preserve">
<value>是否要關閉此窗格?</value>
</data>
<data name="ConfirmCloseDialog_PanePrimary" xml:space="preserve">
<value>關閉窗格</value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsTitle" xml:space="preserve">
<value>是否要關閉這些索引標籤?</value>
</data>
<data name="ConfirmCloseDialog_MultipleTabsPrimary" xml:space="preserve">
<value>關閉索引標籤</value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesTitle" xml:space="preserve">
<value>是否要關閉這些窗格?</value>
</data>
<data name="ConfirmCloseDialog_MultiplePanesPrimary" xml:space="preserve">
<value>關閉窗格</value>
</data>
<data name="DontAskAgainCheckBox.Content" xml:space="preserve">
<value>不要再問我</value>
</data>
<data name="CloseReadOnlyDialog.CloseButtonText" xml:space="preserve">
<value>取消</value>
</data>
@@ -769,14 +745,6 @@
<value>Windows</value>
<comment>This is displayed as a label for the context menu item that holds the submenu of available windows.</comment>
</data>
<data name="NotificationMessage_TabActivity" xml:space="preserve">
<value>索引標籤「{0}」中的活動</value>
<comment>{0} is the tab title. Shown as the body of a desktop notification when tab activity is detected.</comment>
</data>
<data name="NotificationMessage_TabActivityInWindow" xml:space="preserve">
<value>索引標籤「{0}」(視窗「{1}」) 中的活動</value>
<comment>{0} is the tab title, {1} is the window name. Shown as the body of a desktop notification when tab activity is detected and the window has a name.</comment>
</data>
<data name="DropPathTabRun.Text" xml:space="preserve">
<value>開啟指定起始目錄中的新索引標籤</value>
</data>
@@ -913,10 +881,10 @@
<value>如果設定,命令會附加到設定檔的預設命令,而不是取代命令。</value>
</data>
<data name="RestartConnectionText" xml:space="preserve">
<value>重新啟動工作模式</value>
<value>重新啟動連線</value>
</data>
<data name="RestartConnectionToolTip" xml:space="preserve">
<value>使用中窗格重新啟動工作階段</value>
<value>重新啟動使用中窗格連線</value>
</data>
<data name="SnippetPaneTitle.Text" xml:space="preserve">
<value>片斷</value>

View File

@@ -23,7 +23,7 @@ namespace winrt::TerminalApp::implementation
winrt::Microsoft::Terminal::Settings::Model::INewContentArgs GetNewTerminalArgs(BuildStartupKind kind) const;
winrt::hstring Title() { return L"Scratchpad"; }
uint64_t TaskbarState() { return 0; }
winrt::Microsoft::Terminal::Control::TaskbarState TaskbarState() { return winrt::Microsoft::Terminal::Control::TaskbarState::Clear; }
uint64_t TaskbarProgress() { return 0; }
bool ReadOnly() { return false; }
winrt::hstring Icon() const;

View File

@@ -23,7 +23,7 @@ namespace winrt::TerminalApp::implementation
winrt::Microsoft::Terminal::Settings::Model::INewContentArgs GetNewTerminalArgs(const BuildStartupKind kind) const;
winrt::hstring Title() { return RS_(L"SettingsTab"); }
uint64_t TaskbarState() { return 0; }
winrt::Microsoft::Terminal::Control::TaskbarState TaskbarState() { return winrt::Microsoft::Terminal::Control::TaskbarState::Clear; }
uint64_t TaskbarProgress() { return 0; }
bool ReadOnly() { return false; }
winrt::hstring Icon() const;

View File

@@ -24,7 +24,7 @@ namespace winrt::TerminalApp::implementation
winrt::Microsoft::Terminal::Settings::Model::INewContentArgs GetNewTerminalArgs(BuildStartupKind kind) const;
winrt::hstring Title() { return RS_(L"SnippetPaneTitle/Text"); }
uint64_t TaskbarState() { return 0; }
winrt::Microsoft::Terminal::Control::TaskbarState TaskbarState() { return winrt::Microsoft::Terminal::Control::TaskbarState::Clear; }
uint64_t TaskbarProgress() { return 0; }
bool ReadOnly() { return false; }
winrt::hstring Icon() const;

View File

@@ -123,6 +123,12 @@ namespace winrt::TerminalApp::implementation
_bellIndicatorTimer.Stop();
}
void Tab::_ActivityIndicatorTimerTick(const Windows::Foundation::IInspectable& /*sender*/, const Windows::Foundation::IInspectable& /*e*/)
{
ShowActivityIndicator(false);
_activityIndicatorTimer.Stop();
}
// Method Description:
// - Initializes a TabViewItem for this Tab instance.
// Arguments:
@@ -329,6 +335,10 @@ namespace winrt::TerminalApp::implementation
{
ShowBellIndicator(false);
}
if (_tabStatus.ActivityIndicator())
{
ShowActivityIndicator(false);
}
}
}
@@ -361,6 +371,10 @@ namespace winrt::TerminalApp::implementation
// The tabWidthMode may have changed, update the header control accordingly
_UpdateHeaderControlMaxWidth();
// Refresh pane header visibility based on the current setting
const auto showHeaders = settings.GlobalSettings().ShowPaneHeaders() && _rootPane->GetLeafPaneCount() > 1;
_rootPane->ShowPaneHeaders(showHeaders);
// Update the settings on all our panes.
_rootPane->WalkTree([&](const auto& pane) {
pane->UpdateSettings(settings);
@@ -459,6 +473,26 @@ namespace winrt::TerminalApp::implementation
_bellIndicatorTimer.Start();
}
void Tab::ShowActivityIndicator(const bool show)
{
ASSERT_UI_THREAD();
_tabStatus.ActivityIndicator(show);
}
void Tab::ActivateActivityIndicatorTimer()
{
ASSERT_UI_THREAD();
if (!_activityIndicatorTimer)
{
_activityIndicatorTimer.Interval(std::chrono::milliseconds(2000));
_activityIndicatorTimer.Tick({ get_weak(), &Tab::_ActivityIndicatorTimerTick });
}
_activityIndicatorTimer.Start();
}
// Method Description:
// - Gets the title string of the last focused terminal control in our tree.
// Returns the empty string if there is no such control.
@@ -646,6 +680,14 @@ namespace winrt::TerminalApp::implementation
// After split, Close Pane Menu Item should be visible
_closePaneMenuItem.Visibility(WUX::Visibility::Visible);
// Show pane headers now that we have multiple panes (if the setting is enabled)
try
{
const auto settings{ winrt::TerminalApp::implementation::AppLogic::CurrentAppSettings() };
_rootPane->ShowPaneHeaders(settings.GlobalSettings().ShowPaneHeaders());
}
CATCH_LOG();
// The active pane has an id if it is a leaf
if (activePaneId)
{
@@ -844,14 +886,14 @@ namespace winrt::TerminalApp::implementation
// Arguments:
// - direction: The direction to move the separator in.
// Return Value:
// - whether a pane was resized
bool Tab::ResizePane(const ResizeDirection& direction)
// - <none>
void Tab::ResizePane(const ResizeDirection& direction)
{
ASSERT_UI_THREAD();
// NOTE: This _must_ be called on the root pane, so that it can propagate
// throughout the entire tree.
return _rootPane->ResizePane(direction);
_rootPane->ResizePane(direction);
}
// Method Description:
@@ -1181,8 +1223,45 @@ namespace winrt::TerminalApp::implementation
co_await wil::resume_foreground(dispatcher);
if (const auto tab{ weakThisCopy.get() })
{
const auto title = notifArgs.Title().empty() ? tab->Title() : notifArgs.Title();
tab->TabToastNotificationRequested.raise(title, notifArgs.Body(), sender);
const auto activeContent = tab->GetActiveContent();
const auto isActivePaneContent = activeContent && activeContent == sender;
if (notifArgs.OnlyWhenInactive() && isActivePaneContent &&
tab->_focusState != WUX::FocusState::Unfocused)
{
co_return;
}
const auto style = notifArgs.Style();
if (WI_IsFlagSet(style, OutputNotificationStyle::Taskbar))
{
tab->TabRaiseVisualBell.raise();
}
if (WI_IsFlagSet(style, winrt::Microsoft::Terminal::Control::OutputNotificationStyle::Audible))
{
if (const auto termContent{ sender.try_as<TerminalApp::TerminalPaneContent>() })
{
termContent.PlayNotificationSound();
}
}
if (WI_IsFlagSet(style, winrt::Microsoft::Terminal::Control::OutputNotificationStyle::Tab))
{
tab->ShowActivityIndicator(true);
if (tab->_focusState != WUX::FocusState::Unfocused)
{
tab->ActivateActivityIndicatorTimer();
}
}
if (WI_IsFlagSet(style, winrt::Microsoft::Terminal::Control::OutputNotificationStyle::Notification))
{
const auto title = notifArgs.Title().empty() ? tab->Title() : notifArgs.Title();
tab->TabToastNotificationRequested.raise(title, notifArgs.Body(), sender);
}
}
});
@@ -1242,11 +1321,10 @@ namespace winrt::TerminalApp::implementation
const auto taskbarState = state.State();
// The progress of the control changed, but not necessarily the progress of the tab.
// Set the tab's progress ring to the active pane's progress
if (taskbarState > 0)
if (taskbarState != winrt::Microsoft::Terminal::Control::TaskbarState::Clear)
{
if (taskbarState == 3)
if (taskbarState == winrt::Microsoft::Terminal::Control::TaskbarState::Indeterminate)
{
// 3 is the indeterminate state, set the progress ring as such
_tabStatus.IsProgressRingIndeterminate(true);
}
else
@@ -1337,6 +1415,7 @@ namespace winrt::TerminalApp::implementation
if (_rootPane->GetLeafPaneCount() == 1)
{
_closePaneMenuItem.Visibility(WUX::Visibility::Collapsed);
_rootPane->ShowPaneHeaders(false);
}
_RecalculateAndApplyReadOnly();
@@ -1422,6 +1501,10 @@ namespace winrt::TerminalApp::implementation
{
tab->ShowBellIndicator(false);
}
if (tab->_tabStatus.ActivityIndicator())
{
tab->ShowActivityIndicator(false);
}
}
});
@@ -2245,7 +2328,8 @@ namespace winrt::TerminalApp::implementation
if (tab->_tabStatus.IsInputBroadcastActive())
{
tab->_rootPane->BroadcastString(sender.try_as<TermControl>(),
e.Text());
e.Text(),
static_cast<winrt::Microsoft::Terminal::Control::WriteInputStringType>(e.Type()));
}
}
});

View File

@@ -48,12 +48,15 @@ namespace winrt::TerminalApp::implementation
void ShowBellIndicator(const bool show);
void ActivateBellIndicatorTimer();
void ShowActivityIndicator(const bool show);
void ActivateActivityIndicatorTimer();
float CalcSnappedDimension(const bool widthOrHeight, const float dimension) const;
std::optional<winrt::Microsoft::Terminal::Settings::Model::SplitDirection> PreCalculateCanSplit(winrt::Microsoft::Terminal::Settings::Model::SplitDirection splitType,
const float splitSize,
winrt::Windows::Foundation::Size availableSpace) const;
bool ResizePane(const winrt::Microsoft::Terminal::Settings::Model::ResizeDirection& direction);
void ResizePane(const winrt::Microsoft::Terminal::Settings::Model::ResizeDirection& direction);
bool NavigateFocus(const winrt::Microsoft::Terminal::Settings::Model::FocusDirection& direction);
bool SwapPane(const winrt::Microsoft::Terminal::Settings::Model::FocusDirection& direction);
bool FocusPane(const uint32_t id);
@@ -215,6 +218,9 @@ namespace winrt::TerminalApp::implementation
SafeDispatcherTimer _bellIndicatorTimer;
void _BellIndicatorTimerTick(const Windows::Foundation::IInspectable& sender, const Windows::Foundation::IInspectable& e);
SafeDispatcherTimer _activityIndicatorTimer;
void _ActivityIndicatorTimerTick(const Windows::Foundation::IInspectable& sender, const Windows::Foundation::IInspectable& e);
void _UpdateHeaderControlMaxWidth();
void _CreateContextMenu();

View File

@@ -32,6 +32,12 @@
FontSize="12"
Glyph="&#xEA8F;"
Visibility="{x:Bind TabStatus.BellIndicator, Mode=OneWay}" />
<FontIcon x:Name="HeaderActivityIndicator"
Margin="0,0,8,0"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="8"
Glyph="&#xF127;"
Visibility="{x:Bind TabStatus.ActivityIndicator, Mode=OneWay}" />
<FontIcon x:Name="HeaderZoomIcon"
Margin="0,0,8,0"
FontFamily="{ThemeResource SymbolThemeFontFamily}"

View File

@@ -1353,7 +1353,11 @@ namespace winrt::TerminalApp::implementation
// Use the Tab object's identity hash as a stable toast tag.
// This survives tab reordering and cross-window moves.
const auto tabHash = std::hash<winrt::Windows::Foundation::IUnknown>{}(*tab);
#ifdef _WIN64
const hstring tabTag{ fmt::format(FMT_COMPILE(L"wt-tab-{:016x}"), tabHash) };
#else
const hstring tabTag{ fmt::format(FMT_COMPILE(L"wt-tab-{:08x}"), tabHash) };
#endif
const implementation::DesktopNotificationArgs args{
.Title = notificationTitle,
@@ -1366,8 +1370,8 @@ namespace winrt::TerminalApp::implementation
{
// The toast Activated callback runs on a background thread.
// Marshal to the UI thread for tab focus and window summon.
page->Dispatcher().RunAsync(winrt::Windows::UI::Core::CoreDispatcherPriority::Normal, [weakPage{ page->get_weak() }, weakTab, weakContent]() {
if (const auto p{ weakPage.get() })
page->Dispatcher().RunAsync(winrt::Windows::UI::Core::CoreDispatcherPriority::Normal, [weakThis, weakTab, weakContent]() {
if (const auto p{ weakThis.get() })
{
if (const auto t{ weakTab.get() })
{

View File

@@ -9,27 +9,28 @@ namespace winrt::TerminalApp::implementation
{
// Default to unset, 0%.
TaskbarState::TaskbarState() :
TaskbarState(0, 0) {};
TaskbarState(winrt::Microsoft::Terminal::Control::TaskbarState::Clear, 0) {};
TaskbarState::TaskbarState(const uint64_t dispatchTypesState, const uint64_t progressParam) :
_State{ dispatchTypesState },
TaskbarState::TaskbarState(const winrt::Microsoft::Terminal::Control::TaskbarState state, const uint64_t progressParam) :
_State{ state },
_Progress{ progressParam } {}
uint64_t TaskbarState::Priority() const
{
// This seemingly nonsensical ordering is from
// https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-itaskbarlist3-setprogressstate#how-the-taskbar-button-chooses-the-progress-indicator-for-a-group
using TbState = winrt::Microsoft::Terminal::Control::TaskbarState;
switch (_State)
{
case 0: // Clear = 0,
case TbState::Clear:
return 5;
case 1: // Set = 1,
case TbState::Set:
return 3;
case 2: // Error = 2,
case TbState::Error:
return 1;
case 3: // Indeterminate = 3,
case TbState::Indeterminate:
return 4;
case 4: // Paused = 4
case TbState::Paused:
return 2;
}
// Here, return 6, to definitely be greater than all the other valid values.

View File

@@ -16,13 +16,13 @@ namespace winrt::TerminalApp::implementation
{
public:
TaskbarState();
TaskbarState(const uint64_t dispatchTypesState, const uint64_t progress);
TaskbarState(const winrt::Microsoft::Terminal::Control::TaskbarState state, const uint64_t progress);
static int ComparePriority(const winrt::TerminalApp::TaskbarState& lhs, const winrt::TerminalApp::TaskbarState& rhs);
uint64_t Priority() const;
WINRT_PROPERTY(uint64_t, State, 0);
WINRT_PROPERTY(winrt::Microsoft::Terminal::Control::TaskbarState, State, winrt::Microsoft::Terminal::Control::TaskbarState::Clear);
WINRT_PROPERTY(uint64_t, Progress, 0);
};
}

View File

@@ -6,9 +6,9 @@ namespace TerminalApp
[default_interface] runtimeclass TaskbarState
{
TaskbarState();
TaskbarState(UInt64 dispatchTypesState, UInt64 progress);
TaskbarState(Microsoft.Terminal.Control.TaskbarState state, UInt64 progress);
UInt64 State{ get; };
Microsoft.Terminal.Control.TaskbarState State{ get; };
UInt64 Progress{ get; };
UInt64 Priority { get; };
}

View File

@@ -2900,15 +2900,14 @@ namespace winrt::TerminalApp::implementation
// Arguments:
// - direction: The direction to move the separator in.
// Return Value:
// - whether a pane was resized
bool TerminalPage::_ResizePane(const ResizeDirection& direction)
// - <none>
void TerminalPage::_ResizePane(const ResizeDirection& direction)
{
if (const auto tabImpl{ _GetFocusedTabImpl() })
{
_UnZoomIfNeeded();
return tabImpl->ResizePane(direction);
tabImpl->ResizePane(direction);
}
return false;
}
// Method Description:
@@ -3056,9 +3055,7 @@ namespace winrt::TerminalApp::implementation
// - Sends the text back to the TermControl through the event's
// `HandleClipboardData` member function.
// - Does some of this in a background thread, as to not hang/crash the UI thread.
// Arguments:
// - eventArgs: the PasteFromClipboard event sent from the TermControl
safe_void_coroutine TerminalPage::_PasteFromClipboardHandler(const IInspectable sender, const PasteFromClipboardEventArgs eventArgs)
safe_void_coroutine TerminalPage::_PasteFromClipboardHandler(const IInspectable sender, const IInspectable /* args */)
try
{
// The old Win32 clipboard API as used below is somewhere in the order of 300-1000x faster than
@@ -3066,8 +3063,13 @@ namespace winrt::TerminalApp::implementation
const auto weakThis = get_weak();
const auto dispatcher = Dispatcher();
const auto globalSettings = _settings.GlobalSettings();
const auto bracketedPaste = eventArgs.BracketedPasteEnabled();
const auto sourceId = sender.try_as<ControlInteractivity>().Id();
const auto control = sender.as<TermControl>();
// TODO GH#20164 these were added to ease the transition to broadcast group management; fill them in
// Used to determine whether to emit empty pastes and strip extra whitespace
const auto anyHasBracketedPaste = control && !control.ReadOnly() && control.BracketedPasteEnabled();
// Used to determine whether to warn on multi-line paste
// If none lack bracketed paste, we can skip the warning.
const auto anyHasUnbracketedPaste = !anyHasBracketedPaste;
// GetClipboardData might block for up to 30s for delay-rendered contents.
co_await winrt::resume_background();
@@ -3078,8 +3080,11 @@ namespace winrt::TerminalApp::implementation
text = clipboard::read();
}
if (!bracketedPaste && globalSettings.TrimPaste())
if (!anyHasBracketedPaste && globalSettings.TrimPaste())
{
// Warning - when broadcast is enabled, this will trim the paste for all receivers.
// Until we propagate this decision-making elsewhere, this is safer; broadcast will not auto-submit commands in other panes.
// Tracked in GH#20164
text = winrt::hstring{ Utils::TrimPaste(text) };
}
@@ -3087,7 +3092,7 @@ namespace winrt::TerminalApp::implementation
// Bracketed Paste provides an application a way to know whether the
// user pasted, even if there was no applicable content on it. This
// behavior is observed in GNOME Terminal, among others.
if (!bracketedPaste && text.empty())
if (!anyHasBracketedPaste && text.empty())
{
co_return;
}
@@ -3099,7 +3104,7 @@ namespace winrt::TerminalApp::implementation
// NOTE that this is unsafe, because a shell that doesn't support bracketed paste
// will allow an attacker to enable the mode, not realize that, and then accept
// the paste as if it was a series of legitimate commands. See GH#13014.
warnMultiLine = !bracketedPaste;
warnMultiLine = anyHasUnbracketedPaste;
break;
case WarnAboutMultiLinePaste::Always:
warnMultiLine = true;
@@ -3169,7 +3174,7 @@ namespace winrt::TerminalApp::implementation
// This will end up calling ConptyConnection::WriteInput which calls WriteFile which may block for
// an indefinite amount of time. Avoid freezes and deadlocks by running this on a background thread.
assert(!dispatcher.HasThreadAccess());
eventArgs.HandleClipboardData(text);
control.WriteInputString(text, WriteInputStringType::Clipboard);
// GH#18821: If broadcast input is active, paste the same text into all other
// panes on the tab. We do this here (rather than re-reading the
@@ -3182,11 +3187,11 @@ namespace winrt::TerminalApp::implementation
if (tab->TabStatus().IsInputBroadcastActive())
{
tab->GetRootPane()->WalkTree([&](auto&& pane) {
if (const auto control = pane->GetTerminalControl())
if (const auto nextControl = pane->GetTerminalControl())
{
if (control.ContentId() != sourceId && !control.ReadOnly())
if (nextControl.ContentId() != control.ContentId() && !nextControl.ReadOnly())
{
control.RawWriteString(text);
nextControl.WriteInputString(text, WriteInputStringType::Clipboard);
}
}
});
@@ -3307,15 +3312,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();
@@ -3329,16 +3332,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;
}
@@ -3559,16 +3552,6 @@ namespace winrt::TerminalApp::implementation
}
}
// Method Description:
// - Paste text from the Windows Clipboard to the focused terminal
void TerminalPage::_PasteText()
{
if (const auto& control{ _GetActiveControl() })
{
control.PasteTextFromClipboard();
}
}
// Function Description:
// - Called when the settings button is clicked. ShellExecutes the settings
// file, as to open it in the default editor for .json files. Does this in

View File

@@ -426,7 +426,7 @@ namespace winrt::TerminalApp::implementation
const Microsoft::Terminal::Settings::Model::SplitDirection splitType,
const float splitSize,
std::shared_ptr<Pane> newPane);
bool _ResizePane(const Microsoft::Terminal::Settings::Model::ResizeDirection& direction);
void _ResizePane(const Microsoft::Terminal::Settings::Model::ResizeDirection& direction);
void _ToggleSplitOrientation();
void _ScrollPage(ScrollDirection scrollDirection);
@@ -434,11 +434,11 @@ namespace winrt::TerminalApp::implementation
void _SetAcceleratorForMenuItem(Windows::UI::Xaml::Controls::MenuFlyoutItem& menuItem, const winrt::Microsoft::Terminal::Control::KeyChord& keyChord);
safe_void_coroutine _PasteFromClipboardHandler(const IInspectable sender,
const Microsoft::Terminal::Control::PasteFromClipboardEventArgs eventArgs);
const IInspectable eventArgs);
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);

View File

@@ -10,6 +10,7 @@
#include "../../types/inc/utils.hpp"
#include "BellEventArgs.g.cpp"
#include "NotificationEventArgs.g.cpp"
#include "TerminalPaneContent.g.cpp"
using namespace winrt::Windows::Foundation;
@@ -34,6 +35,7 @@ namespace winrt::TerminalApp::implementation
{
_controlEvents._ConnectionStateChanged = _control.ConnectionStateChanged(winrt::auto_revoke, { this, &TerminalPaneContent::_controlConnectionStateChangedHandler });
_controlEvents._WarningBell = _control.WarningBell(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlWarningBellHandler });
_controlEvents._PromptStarted = _control.PromptStarted(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlPromptStartedHandler });
_controlEvents._CloseTerminalRequested = _control.CloseTerminalRequested(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_closeTerminalRequestedHandler });
_controlEvents._RestartTerminalRequested = _control.RestartTerminalRequested(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_restartTerminalRequestedHandler });
@@ -42,6 +44,8 @@ namespace winrt::TerminalApp::implementation
_controlEvents._SetTaskbarProgress = _control.SetTaskbarProgress(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlSetTaskbarProgress });
_controlEvents._ReadOnlyChanged = _control.ReadOnlyChanged(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlReadOnlyChanged });
_controlEvents._FocusFollowMouseRequested = _control.FocusFollowMouseRequested(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlFocusFollowMouseRequested });
_controlEvents._ShowNotification = _control.ShowNotification(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlShowNotification });
_controlEvents._OutputIdle = _control.OutputIdle(winrt::auto_revoke, { get_weak(), &TerminalPaneContent::_controlOutputIdleHandler });
}
void TerminalPaneContent::_removeControlEvents()
{
@@ -173,6 +177,16 @@ namespace winrt::TerminalApp::implementation
{
TaskbarProgressChanged.raise(*this, nullptr);
}
winrt::Microsoft::Terminal::Control::TaskbarState TerminalPaneContent::TaskbarState()
{
return _control.TaskbarState();
}
uint64_t TerminalPaneContent::TaskbarProgress()
{
return _control.TaskbarProgress();
}
void TerminalPaneContent::_controlReadOnlyChanged(const IInspectable&, const IInspectable&)
{
ReadOnlyChanged.raise(*this, nullptr);
@@ -182,6 +196,11 @@ namespace winrt::TerminalApp::implementation
FocusRequested.raise(*this, nullptr);
}
void TerminalPaneContent::_controlShowNotification(const IInspectable& /*sender*/, const ShowNotificationEventArgs& args)
{
NotificationRequested.raise(*this, winrt::make<implementation::NotificationEventArgs>(OutputNotificationStyle::Notification, false, args.Title(), args.Body()));
}
// Method Description:
// - Called when our attached control is closed. Triggers listeners to our close
// event, if we're a leaf pane.
@@ -261,6 +280,25 @@ namespace winrt::TerminalApp::implementation
// has the 'visual' flag set
// Arguments:
// - <unused>
void TerminalPaneContent::PlayNotificationSound()
{
if (_profile)
{
auto sounds{ _profile.BellSound() };
if (sounds && sounds.Size() > 0)
{
winrt::hstring soundPath{ sounds.GetAt(rand() % sounds.Size()).Resolved() };
winrt::Windows::Foundation::Uri uri{ soundPath };
_playBellSound(uri);
}
else
{
const auto soundAlias = reinterpret_cast<LPCTSTR>(SND_ALIAS_SYSTEMHAND);
PlaySound(soundAlias, NULL, SND_ALIAS_ID | SND_ASYNC | SND_SENTRY);
}
}
}
void TerminalPaneContent::_controlWarningBellHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
const winrt::Windows::Foundation::IInspectable& /*eventArgs*/)
{
@@ -272,18 +310,7 @@ namespace winrt::TerminalApp::implementation
if (WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Audible))
{
// Audible is set, play the sound
auto sounds{ _profile.BellSound() };
if (sounds && sounds.Size() > 0)
{
winrt::hstring soundPath{ sounds.GetAt(rand() % sounds.Size()).Resolved() };
winrt::Windows::Foundation::Uri uri{ soundPath };
_playBellSound(uri);
}
else
{
const auto soundAlias = reinterpret_cast<LPCTSTR>(SND_ALIAS_SYSTEMHAND);
PlaySound(soundAlias, NULL, SND_ALIAS_ID | SND_ASYNC | SND_SENTRY);
}
PlayNotificationSound();
}
if (WI_IsFlagSet(_profile.BellStyle(), winrt::Microsoft::Terminal::Settings::Model::BellStyle::Window))
@@ -300,6 +327,34 @@ namespace winrt::TerminalApp::implementation
}
}
void TerminalPaneContent::_controlPromptStartedHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
const winrt::Windows::Foundation::IInspectable& /*eventArgs*/)
{
if (_profile)
{
const auto notifyStyle = _profile.NotifyOnNextPrompt();
if (notifyStyle != OutputNotificationStyle::None)
{
NotificationRequested.raise(*this,
*winrt::make_self<TerminalApp::implementation::NotificationEventArgs>(notifyStyle, true));
}
}
}
void TerminalPaneContent::_controlOutputIdleHandler(const winrt::Windows::Foundation::IInspectable& /*sender*/,
const winrt::Windows::Foundation::IInspectable& /*eventArgs*/)
{
if (_profile)
{
const auto notifyStyle = _profile.NotifyOnActivity();
if (notifyStyle != OutputNotificationStyle::None)
{
NotificationRequested.raise(*this,
*winrt::make_self<TerminalApp::implementation::NotificationEventArgs>(notifyStyle, true));
}
}
}
safe_void_coroutine TerminalPaneContent::_playBellSound(winrt::Windows::Foundation::Uri uri)
{
auto weakThis{ get_weak() };

View File

@@ -24,9 +24,11 @@ namespace winrt::TerminalApp::implementation
struct NotificationEventArgs : public NotificationEventArgsT<NotificationEventArgs>
{
public:
NotificationEventArgs(const winrt::hstring& title = {}, const winrt::hstring& body = {}) :
Title(title), Body(body) {}
NotificationEventArgs(winrt::Microsoft::Terminal::Control::OutputNotificationStyle style, bool onlyWhenInactive = false, const winrt::hstring& title = {}, const winrt::hstring& body = {}) :
Style(style), OnlyWhenInactive(onlyWhenInactive), Title(title), Body(body) {}
til::property<winrt::Microsoft::Terminal::Control::OutputNotificationStyle> Style;
til::property<bool> OnlyWhenInactive;
til::property<winrt::hstring> Title;
til::property<winrt::hstring> Body;
};
@@ -48,6 +50,7 @@ namespace winrt::TerminalApp::implementation
void UpdateSettings(const winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings& settings);
void MarkAsDefterm();
void PlayNotificationSound();
winrt::Microsoft::Terminal::Settings::Model::Profile GetProfile() const
{
@@ -55,8 +58,8 @@ namespace winrt::TerminalApp::implementation
}
winrt::hstring Title() { return _control.Title(); }
uint64_t TaskbarState() { return _control.TaskbarState(); }
uint64_t TaskbarProgress() { return _control.TaskbarProgress(); }
winrt::Microsoft::Terminal::Control::TaskbarState TaskbarState();
uint64_t TaskbarProgress();
bool ReadOnly() { return _control.ReadOnly(); }
winrt::hstring Icon() const;
Windows::Foundation::IReference<winrt::Windows::UI::Color> TabColor() const noexcept;
@@ -83,6 +86,8 @@ namespace winrt::TerminalApp::implementation
{
winrt::Microsoft::Terminal::Control::TermControl::ConnectionStateChanged_revoker _ConnectionStateChanged;
winrt::Microsoft::Terminal::Control::TermControl::WarningBell_revoker _WarningBell;
winrt::Microsoft::Terminal::Control::TermControl::PromptStarted_revoker _PromptStarted;
winrt::Microsoft::Terminal::Control::TermControl::OutputIdle_revoker _OutputIdle;
winrt::Microsoft::Terminal::Control::TermControl::CloseTerminalRequested_revoker _CloseTerminalRequested;
winrt::Microsoft::Terminal::Control::TermControl::RestartTerminalRequested_revoker _RestartTerminalRequested;
@@ -91,6 +96,7 @@ namespace winrt::TerminalApp::implementation
winrt::Microsoft::Terminal::Control::TermControl::SetTaskbarProgress_revoker _SetTaskbarProgress;
winrt::Microsoft::Terminal::Control::TermControl::ReadOnlyChanged_revoker _ReadOnlyChanged;
winrt::Microsoft::Terminal::Control::TermControl::FocusFollowMouseRequested_revoker _FocusFollowMouseRequested;
winrt::Microsoft::Terminal::Control::TermControl::ShowNotification_revoker _ShowNotification;
} _controlEvents;
void _setupControlEvents();
@@ -101,6 +107,8 @@ namespace winrt::TerminalApp::implementation
safe_void_coroutine _controlConnectionStateChangedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& /*args*/);
void _controlWarningBellHandler(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Windows::Foundation::IInspectable& e);
void _controlPromptStartedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& eventArgs);
void _controlOutputIdleHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& eventArgs);
void _controlReadOnlyChangedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& e);
void _controlTitleChanged(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args);
@@ -108,6 +116,7 @@ namespace winrt::TerminalApp::implementation
void _controlSetTaskbarProgress(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args);
void _controlReadOnlyChanged(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args);
void _controlFocusFollowMouseRequested(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args);
void _controlShowNotification(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Microsoft::Terminal::Control::ShowNotificationEventArgs& args);
void _closeTerminalRequestedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& /*args*/);
void _restartTerminalRequestedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& /*args*/);

View File

@@ -11,6 +11,7 @@ namespace TerminalApp
Microsoft.Terminal.Control.TermControl GetTermControl();
void MarkAsDefterm();
void PlayNotificationSound();
Microsoft.Terminal.Settings.Model.Profile GetProfile();

View File

@@ -17,6 +17,7 @@ namespace winrt::TerminalApp::implementation
WINRT_OBSERVABLE_PROPERTY(bool, IsProgressRingActive, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(bool, IsProgressRingIndeterminate, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(bool, BellIndicator, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(bool, ActivityIndicator, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(bool, IsReadOnlyActive, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(uint32_t, ProgressValue, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(bool, IsInputBroadcastActive, PropertyChanged.raise);

View File

@@ -12,6 +12,7 @@ namespace TerminalApp
Boolean IsProgressRingActive { get; set; };
Boolean IsProgressRingIndeterminate { get; set; };
Boolean BellIndicator { get; set; };
Boolean ActivityIndicator { get; set; };
UInt32 ProgressValue { get; set; };
Boolean IsReadOnlyActive { get; set; };
Boolean IsInputBroadcastActive { get; set; };

View File

@@ -139,6 +139,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
auto pfnSearchMissingCommand = [this](auto&& PH1, auto&& PH2) { _terminalSearchMissingCommand(std::forward<decltype(PH1)>(PH1), std::forward<decltype(PH2)>(PH2)); };
_terminal->SetSearchMissingCommandCallback(pfnSearchMissingCommand);
auto pfnShowNotification = [this](auto&& PH1, auto&& PH2) { _terminalShowNotification(std::forward<decltype(PH1)>(PH1), std::forward<decltype(PH2)>(PH2)); };
_terminal->SetShowNotificationCallback(pfnShowNotification);
auto pfnPromptStarted = [this] { _terminalPromptStarted(); };
_terminal->SetPromptStartedCallback(pfnPromptStarted);
auto pfnOutputStarted = [this] { _terminalOutputStarted(); };
_terminal->SetOutputStartedCallback(pfnOutputStarted);
auto pfnClearQuickFix = [this] { ClearQuickFix(); };
_terminal->SetClearQuickFixCallback(pfnClearQuickFix);
@@ -498,7 +507,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// - wstr: the string of characters to write to the terminal connection.
// Return Value:
// - <none>
void ControlCore::SendInput(const std::wstring_view wstr)
void ControlCore::_sendInput(const std::wstring_view wstr)
{
if (wstr.empty())
{
@@ -554,7 +563,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
if (out)
{
SendInput(*out);
_sendInput(*out);
return true;
}
return false;
@@ -712,7 +721,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
if (out)
{
SendInput(*out);
_sendInput(*out);
return true;
}
return false;
@@ -731,7 +740,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
if (out)
{
SendInput(*out);
_sendInput(*out);
return true;
}
return false;
@@ -913,6 +922,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_hasUnfocusedAppearance = static_cast<bool>(newAppearance);
_unfocusedAppearance = _hasUnfocusedAppearance ? newAppearance : settings;
// Cache the auto-detect setting in an atomic so the off-thread output/prompt
// callbacks can read it without synchronizing with _settings. If the effective
// taskbar state changes (because a command is currently active and the setting
// toggled), notify listeners.
const auto nowEnabled = _settings.AutoDetectRunningCommand();
const auto wasEnabled = _autoDetectCommandActivity.exchange(nowEnabled, std::memory_order_relaxed);
if (wasEnabled != nowEnabled && _commandActive.load(std::memory_order_relaxed))
{
TaskbarProgressChanged.raise(*this, nullptr);
}
const auto lock = _terminal->LockForWriting();
_builtinGlyphs = _settings.EnableBuiltinGlyphs();
@@ -1451,24 +1471,34 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// Method Description:
// - Pre-process text pasted (presumably from the clipboard)
// before sending it over the terminal's connection.
void ControlCore::PasteText(const winrt::hstring& hstr)
void ControlCore::WriteInputString(const std::wstring_view& str, WriteInputStringType type)
{
using namespace ::Microsoft::Console::Utils;
auto filtered = FilterStringForPaste(hstr, CarriageReturnNewline | ControlCodes);
if (BracketedPasteEnabled())
switch (type)
{
filtered.insert(0, L"\x1b[200~");
filtered.append(L"\x1b[201~");
case WriteInputStringType::Clipboard:
{
using namespace ::Microsoft::Console::Utils;
auto filtered = FilterStringForPaste(str, CarriageReturnNewline | ControlCodes);
if (BracketedPasteEnabled())
{
filtered.insert(0, L"\x1b[200~");
filtered.append(L"\x1b[201~");
}
// It's important to not hold the terminal lock while calling this function as sending the data may take a long time.
_sendInput(filtered);
const auto lock = _terminal->LockForWriting();
_terminal->ClearSelection();
_updateSelectionUI();
_terminal->TrySnapOnInput();
return;
}
case WriteInputStringType::Raw:
_sendInput(str);
return;
}
// It's important to not hold the terminal lock while calling this function as sending the data may take a long time.
SendInput(filtered);
const auto lock = _terminal->LockForWriting();
_terminal->ClearSelection();
_updateSelectionUI();
_terminal->TrySnapOnInput();
}
FontInfo ControlCore::GetFont() const
@@ -1547,10 +1577,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// - Gets the internal taskbar state value
// Return Value:
// - The taskbar state of this control
const size_t ControlCore::TaskbarState() const noexcept
const Control::TaskbarState ControlCore::TaskbarState() const noexcept
{
const auto lock = _terminal->LockForReading();
return _terminal->GetTaskbarState();
const auto vtState = static_cast<Control::TaskbarState>(_terminal->GetTaskbarState());
if (vtState == Control::TaskbarState::Clear &&
_autoDetectCommandActivity.load(std::memory_order_relaxed) &&
_commandActive.load(std::memory_order_relaxed))
{
return Control::TaskbarState::Indeterminate;
}
return vtState;
}
// Method Description:
@@ -1580,6 +1617,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
return _terminal->GetViewport().Height();
}
// Function Description:
// - Gets the width of the terminal in columns. This is just the
// width of the viewport.
// Return Value:
// - The width of the terminal in columns
int ControlCore::ViewWidth() const
{
const auto lock = _terminal->LockForReading();
return _terminal->GetViewport().Width();
}
// Function Description:
// - Gets the height of the terminal in lines of text. This includes the
// history AND the viewport.
@@ -1599,6 +1647,26 @@ namespace winrt::Microsoft::Terminal::Control::implementation
WarningBell.raise(*this, nullptr);
}
void ControlCore::_terminalPromptStarted()
{
if (_commandActive.exchange(false, std::memory_order_relaxed) &&
_autoDetectCommandActivity.load(std::memory_order_relaxed))
{
TaskbarProgressChanged.raise(*this, nullptr);
}
PromptStarted.raise(*this, nullptr);
}
void ControlCore::_terminalOutputStarted()
{
if (!_commandActive.exchange(true, std::memory_order_relaxed) &&
_autoDetectCommandActivity.load(std::memory_order_relaxed))
{
TaskbarProgressChanged.raise(*this, nullptr);
}
OutputStarted.raise(*this, nullptr);
}
// Method Description:
// - Called for the Terminal's TitleChanged callback. This will re-raise
// a new winrt TypedEvent that can be listened to.
@@ -1691,6 +1759,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
SearchMissingCommand.raise(*this, make<implementation::SearchMissingCommandEventArgs>(hstring{ missingCommand }, bufferRow));
}
void ControlCore::_terminalShowNotification(std::wstring_view title, std::wstring_view body)
{
ShowNotification.raise(*this, make<implementation::ShowNotificationEventArgs>(hstring{ title }, hstring{ body }));
}
void ControlCore::OpenCWD()
{
const auto workingDirectory = WorkingDirectory();
@@ -2197,7 +2270,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// Sending input requires that we're unlocked, because
// writing the input pipe may block indefinitely.
const auto suspension = _terminal->SuspendLock();
SendInput(buffer);
_sendInput(buffer);
}
}
}
@@ -2338,6 +2411,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
_terminal->Write(sequence);
// Clear scroll marks so they don't remain stale in the scrollbar.
// The Scrollback case is already handled by the \x1b[3J path (TextBuffer::ClearScrollback).
if (clearType != ClearBufferType::Scrollback)
{
_terminal->ClearAllMarks();
}
}
if (clearType == Control::ClearBufferType::Screen || clearType == Control::ClearBufferType::All)

View File

@@ -122,8 +122,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
til::color ForegroundColor() const;
til::color BackgroundColor() const;
void SendInput(std::wstring_view wstr);
void PasteText(const winrt::hstring& hstr);
void WriteInputString(const std::wstring_view& str, WriteInputStringType type);
bool CopySelectionToClipboard(bool singleLine, bool withControlSequences, const CopyFormat formats);
void SelectAll();
void ClearSelection();
@@ -161,7 +160,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void OpenCWD();
#pragma region ICoreState
const size_t TaskbarState() const noexcept;
const Control::TaskbarState TaskbarState() const noexcept;
const size_t TaskbarProgress() const noexcept;
hstring Title();
@@ -172,6 +171,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
int ScrollOffset();
int ViewHeight() const;
int ViewWidth() const;
int BufferHeight() const;
bool HasSelection() const;
@@ -275,6 +275,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
til::typed_event<IInspectable, Control::TitleChangedEventArgs> TitleChanged;
til::typed_event<IInspectable, Control::WriteToClipboardEventArgs> WriteToClipboard;
til::typed_event<> WarningBell;
til::typed_event<> PromptStarted;
til::typed_event<> OutputStarted;
til::typed_event<> TabColorChanged;
til::typed_event<> BackgroundColorChanged;
til::typed_event<IInspectable, Control::ScrollPositionChangedArgs> ScrollPositionChanged;
@@ -292,6 +294,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
til::typed_event<IInspectable, Control::OpenHyperlinkEventArgs> OpenHyperlink;
til::typed_event<IInspectable, Control::CompletionsChangedEventArgs> CompletionsChanged;
til::typed_event<IInspectable, Control::SearchMissingCommandEventArgs> SearchMissingCommand;
til::typed_event<IInspectable, Control::ShowNotificationEventArgs> ShowNotification;
til::typed_event<> RefreshQuickFixUI;
til::typed_event<IInspectable, Control::WindowSizeChangedEventArgs> WindowSizeChanged;
@@ -320,9 +323,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void _handleControlC();
void _sendInputToConnection(std::wstring_view wstr);
void _sendInput(std::wstring_view wstr);
#pragma region TerminalCoreCallbacks
void _terminalWarningBell();
void _terminalPromptStarted();
void _terminalOutputStarted();
void _terminalTitleChanged(std::wstring_view wstr);
void _terminalScrollPositionChanged(const int viewTop,
const int viewHeight,
@@ -333,6 +339,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
const int velocity,
const std::chrono::microseconds duration);
void _terminalSearchMissingCommand(std::wstring_view missingCommand, const til::CoordType& bufferRow);
void _terminalShowNotification(std::wstring_view title, std::wstring_view body);
void _terminalWindowSizeChanged(int32_t width, int32_t height);
void _terminalCompletionsChanged(std::wstring_view menuJson, unsigned int replaceLength);
@@ -419,6 +426,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
std::optional<til::point> _lastHoveredCell;
uint16_t _lastHoveredId{ 0 };
std::atomic<bool> _initializedTerminal{ false };
std::atomic<bool> _autoDetectCommandActivity{ false };
std::atomic<bool> _commandActive{ false };
bool _isReadOnly{ false };
bool _closing{ false };

View File

@@ -68,6 +68,14 @@ namespace Microsoft.Terminal.Control
Boolean SearchRegexInvalid;
};
enum WriteInputStringType
{
// Text which is to be passed through unmodified.
Raw,
// Text which is to be treated as clipboard input, stripped and formatted according to the application's wishes.
Clipboard,
};
[default_interface] runtimeclass SelectionColor
{
SelectionColor();
@@ -128,8 +136,7 @@ namespace Microsoft.Terminal.Control
Boolean SendCharEvent(Char ch,
Int16 scanCode,
Microsoft.Terminal.Core.ControlKeyStates modifiers);
void SendInput(String text);
void PasteText(String text);
void WriteInputString(String text, WriteInputStringType type);
void SelectAll();
void ClearSelection();
Boolean ToggleBlockSelection();
@@ -192,12 +199,15 @@ namespace Microsoft.Terminal.Control
event Windows.Foundation.TypedEventHandler<Object, TitleChangedEventArgs> TitleChanged;
event Windows.Foundation.TypedEventHandler<Object, WriteToClipboardEventArgs> WriteToClipboard;
event Windows.Foundation.TypedEventHandler<Object, Object> WarningBell;
event Windows.Foundation.TypedEventHandler<Object, Object> PromptStarted;
event Windows.Foundation.TypedEventHandler<Object, Object> OutputStarted;
event Windows.Foundation.TypedEventHandler<Object, Object> TabColorChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> BackgroundColorChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> TaskbarProgressChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> RendererEnteredErrorState;
event Windows.Foundation.TypedEventHandler<Object, ShowWindowArgs> ShowWindowChanged;
event Windows.Foundation.TypedEventHandler<Object, SearchMissingCommandEventArgs> SearchMissingCommand;
event Windows.Foundation.TypedEventHandler<Object, ShowNotificationEventArgs> ShowNotification;
event Windows.Foundation.TypedEventHandler<Object, Object> RefreshQuickFixUI;
event Windows.Foundation.TypedEventHandler<Object, WindowSizeChangedEventArgs> WindowSizeChanged;

View File

@@ -242,14 +242,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// - Initiate a paste operation.
void ControlInteractivity::RequestPasteTextFromClipboard()
{
auto args = winrt::make<PasteFromClipboardEventArgs>(
[core = _core](const winrt::hstring& wstr) {
core->PasteText(wstr);
},
_core->BracketedPasteEnabled());
// send paste event up to TermApp
PasteFromClipboard.raise(*this, std::move(args));
PasteFromClipboard.raise(*this, nullptr);
}
void ControlInteractivity::PointerPressed(const uint32_t /*pointerId*/,

View File

@@ -92,7 +92,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void AttachToNewControl();
til::typed_event<IInspectable, Control::OpenHyperlinkEventArgs> OpenHyperlink;
til::typed_event<IInspectable, Control::PasteFromClipboardEventArgs> PasteFromClipboard;
til::typed_event<IInspectable, IInspectable> PasteFromClipboard;
til::typed_event<IInspectable, Control::ScrollPositionChangedArgs> ScrollPositionChanged;
til::typed_event<IInspectable, Control::ContextMenuRequestedEventArgs> ContextMenuRequested;

View File

@@ -68,7 +68,7 @@ namespace Microsoft.Terminal.Control
event Windows.Foundation.TypedEventHandler<Object, OpenHyperlinkEventArgs> OpenHyperlink;
event Windows.Foundation.TypedEventHandler<Object, ScrollPositionChangedArgs> ScrollPositionChanged;
event Windows.Foundation.TypedEventHandler<Object, PasteFromClipboardEventArgs> PasteFromClipboard;
event Windows.Foundation.TypedEventHandler<Object, Object> PasteFromClipboard;
event Windows.Foundation.TypedEventHandler<Object, Object> Closed;

View File

@@ -7,7 +7,6 @@
#include "TitleChangedEventArgs.g.cpp"
#include "ContextMenuRequestedEventArgs.g.cpp"
#include "WriteToClipboardEventArgs.g.cpp"
#include "PasteFromClipboardEventArgs.g.cpp"
#include "OpenHyperlinkEventArgs.g.cpp"
#include "NoticeEventArgs.g.cpp"
#include "ScrollPositionChangedArgs.g.cpp"

View File

@@ -7,7 +7,6 @@
#include "TitleChangedEventArgs.g.h"
#include "ContextMenuRequestedEventArgs.g.h"
#include "WriteToClipboardEventArgs.g.h"
#include "PasteFromClipboardEventArgs.g.h"
#include "OpenHyperlinkEventArgs.g.h"
#include "NoticeEventArgs.g.h"
#include "ScrollPositionChangedArgs.g.h"
@@ -20,6 +19,7 @@
#include "CharSentEventArgs.g.h"
#include "StringSentEventArgs.g.h"
#include "SearchMissingCommandEventArgs.g.h"
#include "ShowNotificationEventArgs.g.h"
#include "WindowSizeChangedEventArgs.g.h"
namespace winrt::Microsoft::Terminal::Control::implementation
@@ -83,24 +83,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
std::string _rtf;
};
struct PasteFromClipboardEventArgs : public PasteFromClipboardEventArgsT<PasteFromClipboardEventArgs>
{
public:
PasteFromClipboardEventArgs(std::function<void(const hstring&)> clipboardDataHandler, bool bracketedPasteEnabled) :
m_clipboardDataHandler(clipboardDataHandler),
_BracketedPasteEnabled{ bracketedPasteEnabled } {}
void HandleClipboardData(hstring value)
{
m_clipboardDataHandler(value);
};
WINRT_PROPERTY(bool, BracketedPasteEnabled, false);
private:
std::function<void(const hstring&)> m_clipboardDataHandler;
};
struct OpenHyperlinkEventArgs : public OpenHyperlinkEventArgsT<OpenHyperlinkEventArgs>
{
public:
@@ -235,10 +217,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
struct StringSentEventArgs : public StringSentEventArgsT<StringSentEventArgs>
{
public:
StringSentEventArgs(const winrt::hstring& text) :
_Text(text) {}
StringSentEventArgs(const winrt::hstring& text, uint32_t type) :
_Text(text), _Type(type) {}
WINRT_PROPERTY(winrt::hstring, Text);
WINRT_PROPERTY(uint32_t, Type);
};
struct SearchMissingCommandEventArgs : public SearchMissingCommandEventArgsT<SearchMissingCommandEventArgs>
@@ -252,6 +235,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
til::property<til::CoordType> BufferRow;
};
struct ShowNotificationEventArgs : public ShowNotificationEventArgsT<ShowNotificationEventArgs>
{
public:
ShowNotificationEventArgs(const winrt::hstring& title, const winrt::hstring& body) :
Title(title),
Body(body) {}
til::property<winrt::hstring> Title;
til::property<winrt::hstring> Body;
};
struct WindowSizeChangedEventArgs : public WindowSizeChangedEventArgsT<WindowSizeChangedEventArgs>
{
public:

View File

@@ -68,12 +68,6 @@ namespace Microsoft.Terminal.Control
byte[] Rtf { get; }; // UTF-8, as required by "Rich Text Format"
}
runtimeclass PasteFromClipboardEventArgs
{
void HandleClipboardData(String data);
Boolean BracketedPasteEnabled { get; };
}
runtimeclass OpenHyperlinkEventArgs
{
OpenHyperlinkEventArgs(String uri);
@@ -152,6 +146,7 @@ namespace Microsoft.Terminal.Control
runtimeclass StringSentEventArgs
{
String Text { get; };
UInt32 Type { get; }; // We cannot forward-declare WriteInputStringType, and as of GH#20164 this whole event is getting deleted anyway.
}
runtimeclass SearchMissingCommandEventArgs
@@ -160,6 +155,12 @@ namespace Microsoft.Terminal.Control
Int32 BufferRow { get; };
}
runtimeclass ShowNotificationEventArgs
{
String Title { get; };
String Body { get; };
}
runtimeclass WindowSizeChangedEventArgs
{
Int32 Width;

View File

@@ -29,6 +29,30 @@ namespace Microsoft.Terminal.Control
MinGW,
};
[flags]
enum OutputNotificationStyle
{
None = 0,
Taskbar = 0x1,
Audible = 0x2,
Tab = 0x4,
Notification = 0x8,
All = 0xffffffff
};
// Mirrors Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState
// (which is shared with conhost and lives outside the WinRT projection).
// Values must remain numerically identical so the conversion at the
// ControlCore boundary is a 1:1 cast.
enum TaskbarState
{
Clear = 0,
Set = 1,
Error = 2,
Indeterminate = 3,
Paused = 4,
};
// Class Description:
// TerminalSettings encapsulates all settings that control the
// TermControl's behavior. In these settings there is both the entirety
@@ -78,6 +102,10 @@ namespace Microsoft.Terminal.Control
PathTranslationStyle PathTranslationStyle { get; };
String DragDropDelimiter { get; };
OutputNotificationStyle NotifyOnActivity { get; };
OutputNotificationStyle NotifyOnNextPrompt { get; };
Boolean AutoDetectRunningCommand { get; };
// NOTE! When adding something here, make sure to update ControlProperties.h too!
};
}

View File

@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import "IControlSettings.idl";
namespace Microsoft.Terminal.Control
{
enum MarkCategory
@@ -31,7 +33,7 @@ namespace Microsoft.Terminal.Control
interface ICoreState
{
String Title { get; };
UInt64 TaskbarState { get; };
Microsoft.Terminal.Control.TaskbarState TaskbarState { get; };
UInt64 TaskbarProgress { get; };
String WorkingDirectory { get; };

View File

@@ -238,7 +238,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
return;
}
core->SendInput(text);
core->WriteInputString(text, WriteInputStringType::Raw);
}
::Microsoft::Console::Render::Renderer* TsfDataProvider::GetRenderer()
@@ -328,6 +328,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_revokers.CompletionsChanged = _core.CompletionsChanged(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleCompletionsChanged });
_revokers.RestartTerminalRequested = _core.RestartTerminalRequested(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleRestartTerminalRequested });
_revokers.SearchMissingCommand = _core.SearchMissingCommand(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleSearchMissingCommand });
_revokers.ShowNotification = _core.ShowNotification(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleShowNotification });
_revokers.WindowSizeChanged = _core.WindowSizeChanged(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleWindowSizeChanged });
_revokers.WriteToClipboard = _core.WriteToClipboard(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleWriteToClipboard });
@@ -393,6 +394,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// attached content before we set up the throttled func, and that'll A/V
_revokers.coreScrollPositionChanged = _core.ScrollPositionChanged(winrt::auto_revoke, { get_weak(), &TermControl::_ScrollPositionChanged });
_revokers.WarningBell = _core.WarningBell(winrt::auto_revoke, { get_weak(), &TermControl::_coreWarningBell });
_revokers.PromptStarted = _core.PromptStarted(winrt::auto_revoke, { get_weak(), &TermControl::_corePromptStarted });
_revokers.OutputStarted = _core.OutputStarted(winrt::auto_revoke, { get_weak(), &TermControl::_coreOutputStarted });
static constexpr auto AutoScrollUpdateInterval = std::chrono::microseconds(static_cast<int>(1.0 / 30.0 * 1000000));
_autoScrollTimer.Interval(AutoScrollUpdateInterval);
@@ -912,19 +915,25 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// - wstr: the string of characters to write to the terminal connection.
// Return Value:
// - <none>
void TermControl::SendInput(const winrt::hstring& wstr)
void TermControl::WriteInputString(const winrt::hstring& wstr, WriteInputStringType type)
{
// Dismiss any previewed input.
PreviewInput(hstring{});
WriteInputStringWithoutBroadcast(wstr, type);
// only broadcast if there's an actual listener. Saves the overhead of some object creation.
if (StringSent)
{
StringSent.raise(*this, winrt::make<StringSentEventArgs>(wstr));
StringSent.raise(*this, winrt::make<StringSentEventArgs>(wstr, static_cast<uint32_t>(type)));
}
RawWriteString(wstr);
}
void TermControl::WriteInputStringWithoutBroadcast(const winrt::hstring& wstr, WriteInputStringType type)
{
// Dismiss any previewed input.
PreviewInput(hstring{});
_core.WriteInputString(wstr, type);
}
void TermControl::ClearBuffer(Control::ClearBufferType clearType)
{
_core.ClearBuffer(clearType);
@@ -1524,11 +1533,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
return _core.SendCharEvent(character, scanCode, modifiers);
}
void TermControl::RawWriteString(const winrt::hstring& text)
{
_core.SendInput(text);
}
// Method Description:
// - Manually handles key events for certain keys that can't be passed to us
// normally. Namely, the keys we're concerned with are F7 down and Alt up.
@@ -1675,7 +1679,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// If it encounters a string that isn't, cppwinrt will abort().
// It should already be null-terminated, but let's make sure to not crash.
buf[buf_len] = L'\0';
_core.SendInput(std::wstring_view{ &buf[0], buf_len });
_core.WriteInputString(std::wstring_view{ &buf[0], buf_len }, WriteInputStringType::Raw);
}
s = {};
@@ -2456,6 +2460,46 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
_automationPeer.UpdateControlBounds();
}
// Show resize overlay with columns x rows
_ShowResizeOverlay();
}
// Method Description:
// - Shows a centered overlay with the current terminal dimensions (columns x rows).
// Used during window resize and font size changes. Skipped for disabled controls
// (e.g. the Settings preview terminal) to avoid visual noise.
void TermControl::_ShowResizeOverlay()
{
// Don't show the overlay in the Settings preview control
if (!IsEnabled())
{
return;
}
const auto coreImpl = winrt::get_self<ControlCore>(_core);
const auto cols = coreImpl->ViewWidth();
const auto rows = coreImpl->ViewHeight();
if (cols > 0 && rows > 0)
{
ResizeOverlayText().Text(fmt::format(FMT_COMPILE(L"{} \u00D7 {}"), cols, rows));
ResizeOverlay().Visibility(Visibility::Visible);
if (!_resizeOverlayTimer)
{
_resizeOverlayTimer.emplace();
_resizeOverlayTimer->Interval(std::chrono::milliseconds(750));
_resizeOverlayTimer->Tick([weakThis = get_weak()](auto&&, auto&&) {
if (auto self = weakThis.get())
{
self->ResizeOverlay().Visibility(Visibility::Collapsed);
self->_resizeOverlayTimer->Stop();
}
});
}
_resizeOverlayTimer->Start();
}
}
// Method Description:
@@ -3102,7 +3146,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
auto link{ co_await e.DataView().GetApplicationLinkAsync() };
if (const auto strong = weak.get())
{
_pasteTextWithBroadcast(link.AbsoluteUri());
WriteInputString(link.AbsoluteUri(), WriteInputStringType::Clipboard);
}
}
CATCH_LOG();
@@ -3114,7 +3158,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
auto link{ co_await e.DataView().GetWebLinkAsync() };
if (const auto strong = weak.get())
{
_pasteTextWithBroadcast(link.AbsoluteUri());
WriteInputString(link.AbsoluteUri(), WriteInputStringType::Clipboard);
}
}
CATCH_LOG();
@@ -3126,7 +3170,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
auto text{ co_await e.DataView().GetTextAsync() };
if (const auto strong = weak.get())
{
_pasteTextWithBroadcast(text);
WriteInputString(text, WriteInputStringType::Clipboard);
}
}
CATCH_LOG();
@@ -3224,27 +3268,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
}
_pasteTextWithBroadcast(winrt::hstring{ allPathsString });
WriteInputString(winrt::hstring{ allPathsString }, WriteInputStringType::Clipboard);
}
}
}
// Method Description:
// - Paste this text, and raise a StringSent, to potentially broadcast this
// text to other controls in the app. For certain interactions, like
// drag/dropping a file, we want to act like we "pasted" the text (even if
// the text didn't come from the clipboard). This lets those interactions
// broadcast as well.
void TermControl::_pasteTextWithBroadcast(const winrt::hstring& text)
{
// only broadcast if there's an actual listener. Saves the overhead of some object creation.
if (StringSent)
{
StringSent.raise(*this, winrt::make<StringSentEventArgs>(text));
}
_core.PasteText(text);
}
// Method Description:
// - Handle the DragOver event. We'll signal that the drag operation we
// support is the "copy" operation, and we'll also customize the
@@ -3356,7 +3384,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// - Gets the internal taskbar state value
// Return Value:
// - The taskbar state of this control
const uint64_t TermControl::TaskbarState() const noexcept
const Control::TaskbarState TermControl::TaskbarState() const noexcept
{
return _core.TaskbarState();
}
@@ -3726,6 +3754,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_playWarningBell->Run();
}
void TermControl::_corePromptStarted(const IInspectable& /*sender*/, const IInspectable& /*args*/)
{
PromptStarted.raise(*this, nullptr);
}
void TermControl::_coreOutputStarted(const IInspectable& /*sender*/, const IInspectable& /*args*/)
{
OutputStarted.raise(*this, nullptr);
}
hstring TermControl::ReadEntireBuffer() const
{
return _core.ReadEntireBuffer();
@@ -3843,6 +3881,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void TermControl::_coreOutputIdle(const IInspectable& /*sender*/, const IInspectable& /*args*/)
{
_refreshSearch();
OutputIdle.raise(*this, nullptr);
}
void TermControl::OwningHwnd(uint64_t owner)

View File

@@ -86,7 +86,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void ColorSelection(Control::SelectionColor fg, Control::SelectionColor bg, Core::MatchMode matchMode);
#pragma region ICoreState
const uint64_t TaskbarState() const noexcept;
const Control::TaskbarState TaskbarState() const noexcept;
const uint64_t TaskbarProgress() const noexcept;
hstring Title();
@@ -125,7 +125,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void ResetFontSize();
winrt::Windows::Foundation::Size GetFontSize() const;
void SendInput(const winrt::hstring& input);
void WriteInputString(const winrt::hstring& wstr, WriteInputStringType type);
void WriteInputStringWithoutBroadcast(const winrt::hstring& wstr, WriteInputStringType type);
void ClearBuffer(Control::ClearBufferType clearType);
void ToggleShaderEffects();
@@ -179,7 +180,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
bool RawWriteKeyEvent(const WORD vkey, const WORD scanCode, const winrt::Microsoft::Terminal::Core::ControlKeyStates modifiers, const bool keyDown);
bool RawWriteChar(const wchar_t character, const WORD scanCode, const winrt::Microsoft::Terminal::Core::ControlKeyStates modifiers);
void RawWriteString(const winrt::hstring& text);
void ShowContextMenu();
bool OpenQuickFixMenu();
@@ -211,6 +211,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
til::typed_event<IInspectable, IInspectable> FocusFollowMouseRequested;
til::typed_event<Control::TermControl, Windows::UI::Xaml::RoutedEventArgs> Initialized;
til::typed_event<> WarningBell;
til::typed_event<> PromptStarted;
til::typed_event<> OutputStarted;
til::typed_event<> OutputIdle;
til::typed_event<IInspectable, Control::KeySentEventArgs> KeySent;
til::typed_event<IInspectable, Control::CharSentEventArgs> CharSent;
til::typed_event<IInspectable, Control::StringSentEventArgs> StringSent;
@@ -229,7 +232,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
BUBBLED_FORWARDED_TYPED_EVENT(CompletionsChanged, IInspectable, Control::CompletionsChangedEventArgs);
BUBBLED_FORWARDED_TYPED_EVENT(RestartTerminalRequested, IInspectable, IInspectable);
BUBBLED_FORWARDED_TYPED_EVENT(WriteToClipboard, IInspectable, Control::WriteToClipboardEventArgs);
BUBBLED_FORWARDED_TYPED_EVENT(PasteFromClipboard, IInspectable, Control::PasteFromClipboardEventArgs);
BUBBLED_FORWARDED_TYPED_EVENT(PasteFromClipboard, IInspectable, IInspectable);
BUBBLED_FORWARDED_TYPED_EVENT(ShowNotification, IInspectable, Control::ShowNotificationEventArgs);
// clang-format on
@@ -316,6 +320,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
winrt::hstring _restorePath;
bool _showMarksInScrollbar{ false };
std::optional<SafeDispatcherTimer> _resizeOverlayTimer;
void _ShowResizeOverlay();
bool _isBackgroundLight{ false };
bool _detached{ false };
til::CoordType _searchScrollOffset = 0;
@@ -424,13 +431,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void _coreTransparencyChanged(IInspectable sender, Control::TransparencyChangedEventArgs args);
void _coreRaisedNotice(const IInspectable& s, const Control::NoticeEventArgs& args);
void _coreWarningBell(const IInspectable& sender, const IInspectable& args);
void _corePromptStarted(const IInspectable& sender, const IInspectable& args);
void _coreOutputStarted(const IInspectable& sender, const IInspectable& args);
void _coreOutputIdle(const IInspectable& sender, const IInspectable& args);
winrt::Windows::Foundation::Point _toPosInDips(const Core::Point terminalCellPos);
void _throttledUpdateScrollbar(const ScrollBarUpdate& update);
void _pasteTextWithBroadcast(const winrt::hstring& text);
void _contextMenuHandler(IInspectable sender, Control::ContextMenuRequestedEventArgs args);
void _showContextMenuAt(const winrt::Windows::Foundation::Point& controlRelativePos);
@@ -449,6 +456,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
Control::ControlCore::ScrollPositionChanged_revoker coreScrollPositionChanged;
Control::ControlCore::WarningBell_revoker WarningBell;
Control::ControlCore::PromptStarted_revoker PromptStarted;
Control::ControlCore::OutputStarted_revoker OutputStarted;
Control::ControlCore::RendererEnteredErrorState_revoker RendererEnteredErrorState;
Control::ControlCore::BackgroundColorChanged_revoker BackgroundColorChanged;
Control::ControlCore::FontSizeChanged_revoker FontSizeChanged;
@@ -468,6 +477,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
Control::ControlCore::CompletionsChanged_revoker CompletionsChanged;
Control::ControlCore::RestartTerminalRequested_revoker RestartTerminalRequested;
Control::ControlCore::SearchMissingCommand_revoker SearchMissingCommand;
Control::ControlCore::ShowNotification_revoker ShowNotification;
Control::ControlCore::RefreshQuickFixUI_revoker RefreshQuickFixUI;
Control::ControlCore::WindowSizeChanged_revoker WindowSizeChanged;

View File

@@ -64,11 +64,14 @@ namespace Microsoft.Terminal.Control
event Windows.Foundation.TypedEventHandler<Object, TitleChangedEventArgs> TitleChanged;
event Windows.Foundation.TypedEventHandler<Object, WriteToClipboardEventArgs> WriteToClipboard;
event Windows.Foundation.TypedEventHandler<Object, PasteFromClipboardEventArgs> PasteFromClipboard;
event Windows.Foundation.TypedEventHandler<Object, Object> PasteFromClipboard;
event Windows.Foundation.TypedEventHandler<Object, OpenHyperlinkEventArgs> OpenHyperlink;
event Windows.Foundation.TypedEventHandler<Object, Object> SetTaskbarProgress;
event Windows.Foundation.TypedEventHandler<Object, NoticeEventArgs> RaiseNotice;
event Windows.Foundation.TypedEventHandler<Object, Object> WarningBell;
event Windows.Foundation.TypedEventHandler<Object, Object> PromptStarted;
event Windows.Foundation.TypedEventHandler<Object, Object> OutputStarted;
event Windows.Foundation.TypedEventHandler<Object, Object> OutputIdle;
event Windows.Foundation.TypedEventHandler<Object, Object> HidePointerCursor;
event Windows.Foundation.TypedEventHandler<Object, Object> RestorePointerCursor;
event Windows.Foundation.TypedEventHandler<Object, Object> TabColorChanged;
@@ -82,6 +85,7 @@ namespace Microsoft.Terminal.Control
event Windows.Foundation.TypedEventHandler<Object, CharSentEventArgs> CharSent;
event Windows.Foundation.TypedEventHandler<Object, StringSentEventArgs> StringSent;
event Windows.Foundation.TypedEventHandler<Object, SearchMissingCommandEventArgs> SearchMissingCommand;
event Windows.Foundation.TypedEventHandler<Object, ShowNotificationEventArgs> ShowNotification;
Microsoft.UI.Xaml.Controls.CommandBarFlyout ContextMenu { get; };
@@ -127,10 +131,12 @@ namespace Microsoft.Terminal.Control
void ResetFontSize();
void ToggleShaderEffects();
void SendInput(String input);
Boolean RawWriteKeyEvent(UInt16 vkey, UInt16 scanCode, Microsoft.Terminal.Core.ControlKeyStates modifiers, Boolean keyDown);
Boolean RawWriteChar(Char character, UInt16 scanCode, Microsoft.Terminal.Core.ControlKeyStates modifiers);
void RawWriteString(String text);
void WriteInputString(String text, WriteInputStringType type);
// This is a stopgap until GH#20164 removes StringSent
// It prevents us from entering an infinite broadcast loop
void WriteInputStringWithoutBroadcast(String text, WriteInputStringType type);
void BellLightOn();

View File

@@ -1365,6 +1365,24 @@
</Grid>
<!-- Resize overlay: shows columns x rows when terminal is resized -->
<Border x:Name="ResizeOverlay"
Padding="16,8,16,8"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="{ThemeResource SystemControlBackgroundAltHighBrush}"
BorderBrush="{ThemeResource SystemAccentColor}"
BorderThickness="1"
CornerRadius="{ThemeResource OverlayCornerRadius}"
IsHitTestVisible="False"
Visibility="Collapsed">
<TextBlock x:Name="ResizeOverlayText"
FontSize="18"
FontWeight="SemiBold"
Foreground="{ThemeResource SystemControlForegroundBaseHighBrush}"
TextAlignment="Center" />
</Border>
<Grid x:Name="RendererFailedNotice"
HorizontalAlignment="Center"
VerticalAlignment="Center"

View File

@@ -124,6 +124,7 @@ namespace Microsoft.Terminal.Core
Boolean AllowKittyKeyboardMode { get; };
Boolean AllowVtChecksumReport { get; };
Boolean AllowVtClipboardWrite { get; };
Boolean AllowOscNotifications { get; };
Boolean TrimBlockSelection { get; };
Boolean DetectURLs { get; };

View File

@@ -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();
@@ -267,6 +263,7 @@ void Terminal::SetOptionalFeatures(winrt::Microsoft::Terminal::Core::ICoreSettin
auto features = til::enumset<ITermDispatch::OptionalFeature>{};
features.set(ITermDispatch::OptionalFeature::ChecksumReport, settings.AllowVtChecksumReport());
features.set(ITermDispatch::OptionalFeature::ClipboardWrite, settings.AllowVtClipboardWrite());
features.set(ITermDispatch::OptionalFeature::DesktopNotification, settings.AllowOscNotifications());
engine.Dispatch().SetOptionalFeatures(features);
}
@@ -767,6 +764,11 @@ TerminalInput::OutputType Terminal::SendCharEvent(const wchar_t ch, const WORD s
// This changed the scrollbar marks - raise a notification to update them
_NotifyScrollEvent();
}
// regardless, notify that we started command output
if (_pfnOutputStarted)
{
_pfnOutputStarted();
}
}
}
@@ -1252,7 +1254,7 @@ const std::optional<til::color> Terminal::GetTabColor() const
// - Gets the internal taskbar state value
// Return Value:
// - The taskbar state
const size_t Microsoft::Terminal::Core::Terminal::GetTaskbarState() const noexcept
const Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState Microsoft::Terminal::Core::Terminal::GetTaskbarState() const noexcept
{
return _taskbarState;
}
@@ -1276,11 +1278,26 @@ void Microsoft::Terminal::Core::Terminal::SetSearchMissingCommandCallback(std::f
_pfnSearchMissingCommand.swap(pfn);
}
void Microsoft::Terminal::Core::Terminal::SetShowNotificationCallback(std::function<void(std::wstring_view, std::wstring_view)> pfn) noexcept
{
_pfnShowNotification.swap(pfn);
}
void Microsoft::Terminal::Core::Terminal::SetClearQuickFixCallback(std::function<void()> pfn) noexcept
{
_pfnClearQuickFix.swap(pfn);
}
void Terminal::SetPromptStartedCallback(std::function<void()> pfn) noexcept
{
_pfnPromptStarted.swap(pfn);
}
void Terminal::SetOutputStartedCallback(std::function<void()> pfn) noexcept
{
_pfnOutputStarted.swap(pfn);
}
// Method Description:
// - Stores the search highlighted regions in the terminal
void Terminal::SetSearchHighlights(const std::vector<til::point_span>& highlights) noexcept

View File

@@ -159,12 +159,14 @@ public:
bool IsVtInputEnabled() const noexcept override;
void NotifyBufferRotation(const int delta) override;
void NotifyShellIntegrationMark() override;
void NotifyShellIntegrationMark(ShellIntegrationMark mark) override;
void InvokeCompletions(std::wstring_view menuJson, unsigned int replaceLength) override;
void SearchMissingCommand(const std::wstring_view command) override;
void ShowNotification(const std::wstring_view title, const std::wstring_view body) override;
#pragma endregion
void ClearMark();
@@ -233,8 +235,11 @@ public:
void SetPlayMidiNoteCallback(std::function<void(const int, const int, const std::chrono::microseconds)> pfn) noexcept;
void CompletionsChangedCallback(std::function<void(std::wstring_view, unsigned int)> pfn) noexcept;
void SetSearchMissingCommandCallback(std::function<void(std::wstring_view, const til::CoordType)> pfn) noexcept;
void SetShowNotificationCallback(std::function<void(std::wstring_view, std::wstring_view)> pfn) noexcept;
void SetClearQuickFixCallback(std::function<void()> pfn) noexcept;
void SetWindowSizeChangedCallback(std::function<void(int32_t, int32_t)> pfn) noexcept;
void SetPromptStartedCallback(std::function<void()> pfn) noexcept;
void SetOutputStartedCallback(std::function<void()> pfn) noexcept;
void SetSearchHighlights(const std::vector<til::point_span>& highlights) noexcept;
void SetSearchHighlightFocused(size_t focusedIdx) noexcept;
void ScrollToSearchHighlight(til::CoordType searchScrollOffset);
@@ -243,7 +248,7 @@ public:
const std::optional<til::color> GetTabColor() const;
const size_t GetTaskbarState() const noexcept;
const ::Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState GetTaskbarState() const noexcept;
const size_t GetTaskbarProgress() const noexcept;
void ColorSelection(const TextAttribute& attr, winrt::Microsoft::Terminal::Core::MatchMode matchMode);
@@ -341,15 +346,18 @@ private:
std::function<void(const int, const int, const std::chrono::microseconds)> _pfnPlayMidiNote;
std::function<void(std::wstring_view, unsigned int)> _pfnCompletionsChanged;
std::function<void(std::wstring_view, const til::CoordType)> _pfnSearchMissingCommand;
std::function<void(std::wstring_view, std::wstring_view)> _pfnShowNotification;
std::function<void()> _pfnClearQuickFix;
std::function<void(int32_t, int32_t)> _pfnWindowSizeChanged;
std::function<void()> _pfnPromptStarted;
std::function<void()> _pfnOutputStarted;
RenderSettings _renderSettings;
std::unique_ptr<::Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine;
::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;
@@ -363,6 +371,9 @@ private:
til::enumset<Mode> _systemMode{ Mode::AutoWrap };
::Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState _taskbarState{ ::Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState::Clear };
size_t _taskbarProgress = 0;
bool _focused = false;
bool _snapOnInput = true;
bool _altGrAliasing = true;
@@ -371,9 +382,6 @@ private:
bool _autoMarkPrompts = false;
bool _rainbowSuggestions = false;
size_t _taskbarState = 0;
size_t _taskbarProgress = 0;
size_t _hyperlinkPatternId = 0;
std::wstring _answerbackMessage;

View File

@@ -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);
@@ -173,7 +162,7 @@ void Terminal::SetTaskbarProgress(const ::Microsoft::Console::VirtualTerminal::D
{
_assertLocked();
_taskbarState = static_cast<size_t>(state);
_taskbarState = state;
switch (state)
{
@@ -380,6 +369,14 @@ void Terminal::SearchMissingCommand(const std::wstring_view command)
}
}
void Terminal::ShowNotification(const std::wstring_view title, const std::wstring_view body)
{
if (_pfnShowNotification)
{
_pfnShowNotification(title, body);
}
}
void Terminal::NotifyBufferRotation(const int delta)
{
// Update our selection, so it doesn't move as the buffer is cycled
@@ -416,8 +413,26 @@ void Terminal::NotifyBufferRotation(const int delta)
}
}
void Terminal::NotifyShellIntegrationMark()
void Terminal::NotifyShellIntegrationMark(ShellIntegrationMark mark)
{
// Notify the scrollbar that marks have been added so it can refresh the mark indicators
_NotifyScrollEvent();
switch (mark)
{
case ShellIntegrationMark::Prompt:
if (_pfnPromptStarted)
{
_pfnPromptStarted();
}
break;
case ShellIntegrationMark::Output:
if (_pfnOutputStarted)
{
_pfnOutputStarted();
}
break;
default:
break;
}
}

View File

@@ -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:

View File

@@ -352,8 +352,12 @@ namespace winrt::Microsoft::Terminal::Settings
_AllowKittyKeyboardMode = profile.AllowKittyKeyboardMode();
_AllowVtChecksumReport = profile.AllowVtChecksumReport();
_AllowVtClipboardWrite = profile.AllowVtClipboardWrite();
_AllowOscNotifications = profile.AllowOscNotifications();
_PathTranslationStyle = profile.PathTranslationStyle();
_DragDropDelimiter = profile.DragDropDelimiter();
_NotifyOnActivity = profile.NotifyOnActivity();
_NotifyOnNextPrompt = profile.NotifyOnNextPrompt();
_AutoDetectRunningCommand = profile.AutoDetectRunningCommand();
}
// Method Description:

View File

@@ -81,7 +81,7 @@
CurrentValueAccessibleName="{x:Bind Appearance.CurrentColorScheme.Name, Mode=OneWay}"
HasSettingValue="{x:Bind Appearance.HasDarkColorSchemeName, Mode=OneWay}"
SettingOverrideSource="{x:Bind Appearance.DarkColorSchemeNameOverrideSource, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyle}">
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
<local:SettingContainer.CurrentValue>
<ComboBox Padding="4"
ItemsSource="{x:Bind Appearance.SchemesList, Mode=OneWay}"
@@ -220,7 +220,7 @@
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
HasSettingValue="{x:Bind Appearance.HasForeground, Mode=OneWay}"
SettingOverrideSource="{x:Bind Appearance.ForegroundOverrideSource, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyle}">
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
<local:NullableColorPicker x:Uid="Profile_Foreground_NullableColorPicker"
ColorSchemeVM="{x:Bind Appearance.CurrentColorScheme, Mode=OneWay}"
CurrentColor="{x:Bind Appearance.Foreground, Mode=TwoWay}"
@@ -236,7 +236,7 @@
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
HasSettingValue="{x:Bind Appearance.HasBackground, Mode=OneWay}"
SettingOverrideSource="{x:Bind Appearance.BackgroundOverrideSource, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyle}">
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
<local:NullableColorPicker x:Uid="Profile_Background_NullableColorPicker"
ColorSchemeVM="{x:Bind Appearance.CurrentColorScheme, Mode=OneWay}"
CurrentColor="{x:Bind Appearance.Background, Mode=TwoWay}"
@@ -252,7 +252,7 @@
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
HasSettingValue="{x:Bind Appearance.HasSelectionBackground, Mode=OneWay}"
SettingOverrideSource="{x:Bind Appearance.SelectionBackgroundOverrideSource, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyle}">
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
<local:NullableColorPicker x:Uid="Profile_SelectionBackground_NullableColorPicker"
ColorSchemeVM="{x:Bind Appearance.CurrentColorScheme, Mode=OneWay}"
CurrentColor="{x:Bind Appearance.SelectionBackground, Mode=TwoWay}"
@@ -536,7 +536,7 @@
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
HasSettingValue="{x:Bind Appearance.HasCursorColor, Mode=OneWay}"
SettingOverrideSource="{x:Bind Appearance.CursorColorOverrideSource, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyle}">
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
<local:NullableColorPicker x:Uid="Profile_CursorColor_NullableColorPicker"
ColorSchemeVM="{x:Bind Appearance.CurrentColorScheme, Mode=OneWay}"
CurrentColor="{x:Bind Appearance.CursorColor, Mode=TwoWay}"

View File

@@ -8,9 +8,8 @@
xmlns:mtu="using:Microsoft.Terminal.UI"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls">
<!-- Merge SettingsControls and SettingContainer styles here to give every page access to them -->
<!-- Merge SettingContainerStyle here to give every page access to the SettingContainer -->
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="SettingsControlsStyle.xaml" />
<ResourceDictionary Source="SettingContainerStyle.xaml" />
</ResourceDictionary.MergedDictionaries>
@@ -1201,6 +1200,87 @@
</Setter>
</Style>
<Style x:Key="NavigatorButtonStyle"
TargetType="Button">
<Setter Property="Background" Value="{ThemeResource ExpanderHeaderBackground}" />
<Setter Property="MinWidth" Value="{ThemeResource FlyoutThemeMinWidth}" />
<Setter Property="MinHeight" Value="64" />
<Setter Property="BorderThickness" Value="{ThemeResource ExpanderHeaderBorderThickness}" />
<Setter Property="BorderBrush" Value="{ThemeResource ExpanderHeaderBorderBrush}" />
<Setter Property="Padding" Value="16,0,8,0" />
<Setter Property="Margin" Value="0,4,0,0" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="Grid"
Padding="{TemplateBinding Padding}"
AutomationProperties.AccessibilityView="Raw"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="ContentPresenter"
Grid.Column="0"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}" />
<FontIcon Grid.Column="1"
Margin="20,0,8,0"
HorizontalAlignment="Right"
FontSize="10"
FontWeight="Black"
Glyph="&#xE76C;" />
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Grid"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{ThemeResource ToggleButtonBackgroundPointerOver}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Grid"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{ThemeResource ToggleButtonBorderBrushPointerOver}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Grid"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{ThemeResource ToggleButtonBackgroundPressed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Grid"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{ThemeResource ToggleButtonBorderBrushPressed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="NewInfoBadge"
TargetType="muxc:InfoBadge">
<Setter Property="Padding" Value="5,1,5,2" />

View File

@@ -1,139 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "ControlSizeTrigger.h"
#include "ControlSizeTrigger.g.cpp"
#include <limits>
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::UI::Xaml;
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
DependencyProperty ControlSizeTrigger::_CanTriggerProperty{ nullptr };
DependencyProperty ControlSizeTrigger::_MinWidthProperty{ nullptr };
DependencyProperty ControlSizeTrigger::_MaxWidthProperty{ nullptr };
DependencyProperty ControlSizeTrigger::_MinHeightProperty{ nullptr };
DependencyProperty ControlSizeTrigger::_MaxHeightProperty{ nullptr };
DependencyProperty ControlSizeTrigger::_TargetElementProperty{ nullptr };
ControlSizeTrigger::ControlSizeTrigger()
{
_InitializeProperties();
}
void ControlSizeTrigger::_InitializeProperties()
{
// Defaults mirror the toolkit: trigger is always evaluatable, bounds
// are wide open, no target element until one is bound.
if (!_CanTriggerProperty)
{
_CanTriggerProperty = DependencyProperty::Register(
L"CanTrigger",
xaml_typename<bool>(),
xaml_typename<Editor::ControlSizeTrigger>(),
PropertyMetadata{ box_value(true), PropertyChangedCallback{ &ControlSizeTrigger::_OnTriggerInputChanged } });
}
if (!_MinWidthProperty)
{
_MinWidthProperty = DependencyProperty::Register(
L"MinWidth",
xaml_typename<double>(),
xaml_typename<Editor::ControlSizeTrigger>(),
PropertyMetadata{ box_value(0.0), PropertyChangedCallback{ &ControlSizeTrigger::_OnTriggerInputChanged } });
}
if (!_MaxWidthProperty)
{
_MaxWidthProperty = DependencyProperty::Register(
L"MaxWidth",
xaml_typename<double>(),
xaml_typename<Editor::ControlSizeTrigger>(),
PropertyMetadata{ box_value(std::numeric_limits<double>::infinity()), PropertyChangedCallback{ &ControlSizeTrigger::_OnTriggerInputChanged } });
}
if (!_MinHeightProperty)
{
_MinHeightProperty = DependencyProperty::Register(
L"MinHeight",
xaml_typename<double>(),
xaml_typename<Editor::ControlSizeTrigger>(),
PropertyMetadata{ box_value(0.0), PropertyChangedCallback{ &ControlSizeTrigger::_OnTriggerInputChanged } });
}
if (!_MaxHeightProperty)
{
_MaxHeightProperty = DependencyProperty::Register(
L"MaxHeight",
xaml_typename<double>(),
xaml_typename<Editor::ControlSizeTrigger>(),
PropertyMetadata{ box_value(std::numeric_limits<double>::infinity()), PropertyChangedCallback{ &ControlSizeTrigger::_OnTriggerInputChanged } });
}
if (!_TargetElementProperty)
{
_TargetElementProperty = DependencyProperty::Register(
L"TargetElement",
xaml_typename<FrameworkElement>(),
xaml_typename<Editor::ControlSizeTrigger>(),
PropertyMetadata{ nullptr, PropertyChangedCallback{ &ControlSizeTrigger::_OnTargetElementChanged } });
}
}
void ControlSizeTrigger::_OnTriggerInputChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
{
if (const auto obj{ d.try_as<Editor::ControlSizeTrigger>() })
{
get_self<ControlSizeTrigger>(obj)->_UpdateTrigger();
}
}
void ControlSizeTrigger::_OnTargetElementChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& e)
{
const auto obj{ d.try_as<Editor::ControlSizeTrigger>() };
if (!obj)
{
return;
}
const auto oldElement = e.OldValue().try_as<FrameworkElement>();
const auto newElement = e.NewValue().try_as<FrameworkElement>();
get_self<ControlSizeTrigger>(obj)->_UpdateTargetElement(oldElement, newElement);
}
void ControlSizeTrigger::_UpdateTargetElement(const FrameworkElement& /*oldValue*/, const FrameworkElement& newValue)
{
// Revoking handles both unhooking the previous element and a null `newValue`.
_sizeChangedRevoker.revoke();
if (newValue)
{
_sizeChangedRevoker = newValue.SizeChanged(winrt::auto_revoke, [weakThis = get_weak()](auto&&, auto&&) {
if (const auto strongThis = weakThis.get())
{
strongThis->_UpdateTrigger();
}
});
}
_UpdateTrigger();
}
void ControlSizeTrigger::_UpdateTrigger()
{
const auto target = TargetElement();
if (!target || !CanTrigger())
{
_isActive = false;
SetActive(false);
return;
}
const auto width = target.ActualWidth();
const auto height = target.ActualHeight();
const bool activate =
MinWidth() <= width &&
width < MaxWidth() &&
MinHeight() <= height &&
height < MaxHeight();
_isActive = activate;
SetActive(activate);
}
}

View File

@@ -1,64 +0,0 @@
/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- ControlSizeTrigger
Abstract:
- A conditional state trigger that activates based on the size (width and/or
height) of a target FrameworkElement. Lets XAML visual states swap based on
the live size of a templated part. Ported from the Windows Community Toolkit
primitive `CommunityToolkit.WinUI.ControlSizeTrigger`.
The trigger is "active" when:
MinWidth <= TargetElement.ActualWidth < MaxWidth AND
MinHeight <= TargetElement.ActualHeight < MaxHeight
Defaults: MinWidth = MinHeight = 0; MaxWidth = MaxHeight = +inf, which makes
the trigger always active unless `CanTrigger` is false or `TargetElement` is
null.
Author(s):
- Carlos Zamora - May 2026 (port from CommunityToolkit.WinUI.ControlSizeTrigger)
--*/
#pragma once
#include "ControlSizeTrigger.g.h"
#include "Utils.h"
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
struct ControlSizeTrigger : ControlSizeTriggerT<ControlSizeTrigger>
{
public:
ControlSizeTrigger();
bool IsActive() const { return _isActive; }
DEPENDENCY_PROPERTY(bool, CanTrigger);
DEPENDENCY_PROPERTY(double, MinWidth);
DEPENDENCY_PROPERTY(double, MaxWidth);
DEPENDENCY_PROPERTY(double, MinHeight);
DEPENDENCY_PROPERTY(double, MaxHeight);
DEPENDENCY_PROPERTY(Windows::UI::Xaml::FrameworkElement, TargetElement);
private:
static void _InitializeProperties();
static void _OnTriggerInputChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
static void _OnTargetElementChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
void _UpdateTargetElement(const Windows::UI::Xaml::FrameworkElement& oldValue, const Windows::UI::Xaml::FrameworkElement& newValue);
void _UpdateTrigger();
Windows::UI::Xaml::FrameworkElement::SizeChanged_revoker _sizeChangedRevoker;
bool _isActive{ false };
};
}
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
{
BASIC_FACTORY(ControlSizeTrigger);
}

View File

@@ -1,30 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace Microsoft.Terminal.Settings.Editor
{
[default_interface] runtimeclass ControlSizeTrigger : Windows.UI.Xaml.StateTriggerBase
{
ControlSizeTrigger();
Boolean CanTrigger;
static Windows.UI.Xaml.DependencyProperty CanTriggerProperty { get; };
Double MinWidth;
static Windows.UI.Xaml.DependencyProperty MinWidthProperty { get; };
Double MaxWidth;
static Windows.UI.Xaml.DependencyProperty MaxWidthProperty { get; };
Double MinHeight;
static Windows.UI.Xaml.DependencyProperty MinHeightProperty { get; };
Double MaxHeight;
static Windows.UI.Xaml.DependencyProperty MaxHeightProperty { get; };
Windows.UI.Xaml.FrameworkElement TargetElement;
static Windows.UI.Xaml.DependencyProperty TargetElementProperty { get; };
Boolean IsActive { get; };
}
}

View File

@@ -1,58 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "CornerRadiusFilterConverters.h"
#include "CornerRadiusConverter.g.cpp"
#include "TopCornerRadiusFilterConverter.g.cpp"
#include "BottomCornerRadiusFilterConverter.g.cpp"
using namespace winrt::Windows::UI::Xaml;
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
winrt::Windows::Foundation::IInspectable CornerRadiusConverter::Convert(const winrt::Windows::Foundation::IInspectable& value, const Interop::TypeName& /*targetType*/, const winrt::Windows::Foundation::IInspectable& /*parameter*/, const hstring& /*language*/)
{
if (!value)
{
return value;
}
const auto cr = unbox_value_or<CornerRadius>(value, CornerRadius{ 0, 0, 0, 0 });
return box_value(CornerRadius{ 0, 0, cr.BottomRight, cr.BottomLeft });
}
winrt::Windows::Foundation::IInspectable CornerRadiusConverter::ConvertBack(const winrt::Windows::Foundation::IInspectable& value, const Interop::TypeName& /*targetType*/, const winrt::Windows::Foundation::IInspectable& /*parameter*/, const hstring& /*language*/)
{
return value;
}
winrt::Windows::Foundation::IInspectable TopCornerRadiusFilterConverter::Convert(const winrt::Windows::Foundation::IInspectable& value, const Interop::TypeName& /*targetType*/, const winrt::Windows::Foundation::IInspectable& /*parameter*/, const hstring& /*language*/)
{
if (!value)
{
return value;
}
const auto cr = unbox_value_or<CornerRadius>(value, CornerRadius{ 0, 0, 0, 0 });
return box_value(CornerRadius{ cr.TopLeft, cr.TopRight, 0, 0 });
}
winrt::Windows::Foundation::IInspectable TopCornerRadiusFilterConverter::ConvertBack(const winrt::Windows::Foundation::IInspectable& value, const Interop::TypeName& /*targetType*/, const winrt::Windows::Foundation::IInspectable& /*parameter*/, const hstring& /*language*/)
{
return value;
}
winrt::Windows::Foundation::IInspectable BottomCornerRadiusFilterConverter::Convert(const winrt::Windows::Foundation::IInspectable& value, const Interop::TypeName& /*targetType*/, const winrt::Windows::Foundation::IInspectable& /*parameter*/, const hstring& /*language*/)
{
if (!value)
{
return value;
}
const auto cr = unbox_value_or<CornerRadius>(value, CornerRadius{ 0, 0, 0, 0 });
return box_value(CornerRadius{ 0, 0, cr.BottomRight, cr.BottomLeft });
}
winrt::Windows::Foundation::IInspectable BottomCornerRadiusFilterConverter::ConvertBack(const winrt::Windows::Foundation::IInspectable& value, const Interop::TypeName& /*targetType*/, const winrt::Windows::Foundation::IInspectable& /*parameter*/, const hstring& /*language*/)
{
return value;
}
}

View File

@@ -1,42 +0,0 @@
// Copyright (c) Microsoft Corporation
// Licensed under the MIT license.
#pragma once
#include "CornerRadiusConverter.g.h"
#include "TopCornerRadiusFilterConverter.g.h"
#include "BottomCornerRadiusFilterConverter.g.h"
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
struct CornerRadiusConverter : CornerRadiusConverterT<CornerRadiusConverter>
{
CornerRadiusConverter() = default;
Windows::Foundation::IInspectable Convert(const Windows::Foundation::IInspectable& value, const Windows::UI::Xaml::Interop::TypeName& targetType, const Windows::Foundation::IInspectable& parameter, const hstring& language);
Windows::Foundation::IInspectable ConvertBack(const Windows::Foundation::IInspectable& value, const Windows::UI::Xaml::Interop::TypeName& targetType, const Windows::Foundation::IInspectable& parameter, const hstring& language);
};
struct TopCornerRadiusFilterConverter : TopCornerRadiusFilterConverterT<TopCornerRadiusFilterConverter>
{
TopCornerRadiusFilterConverter() = default;
Windows::Foundation::IInspectable Convert(const Windows::Foundation::IInspectable& value, const Windows::UI::Xaml::Interop::TypeName& targetType, const Windows::Foundation::IInspectable& parameter, const hstring& language);
Windows::Foundation::IInspectable ConvertBack(const Windows::Foundation::IInspectable& value, const Windows::UI::Xaml::Interop::TypeName& targetType, const Windows::Foundation::IInspectable& parameter, const hstring& language);
};
struct BottomCornerRadiusFilterConverter : BottomCornerRadiusFilterConverterT<BottomCornerRadiusFilterConverter>
{
BottomCornerRadiusFilterConverter() = default;
Windows::Foundation::IInspectable Convert(const Windows::Foundation::IInspectable& value, const Windows::UI::Xaml::Interop::TypeName& targetType, const Windows::Foundation::IInspectable& parameter, const hstring& language);
Windows::Foundation::IInspectable ConvertBack(const Windows::Foundation::IInspectable& value, const Windows::UI::Xaml::Interop::TypeName& targetType, const Windows::Foundation::IInspectable& parameter, const hstring& language);
};
}
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
{
BASIC_FACTORY(CornerRadiusConverter);
BASIC_FACTORY(TopCornerRadiusFilterConverter);
BASIC_FACTORY(BottomCornerRadiusFilterConverter);
}

View File

@@ -1,20 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace Microsoft.Terminal.Settings.Editor
{
[default_interface] runtimeclass CornerRadiusConverter : Windows.UI.Xaml.Data.IValueConverter
{
CornerRadiusConverter();
}
[default_interface] runtimeclass TopCornerRadiusFilterConverter : Windows.UI.Xaml.Data.IValueConverter
{
TopCornerRadiusFilterConverter();
}
[default_interface] runtimeclass BottomCornerRadiusFilterConverter : Windows.UI.Xaml.Data.IValueConverter
{
BottomCornerRadiusFilterConverter();
}
}

View File

@@ -79,7 +79,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void Extensions::ExtensionNavigator_Click(const IInspectable& sender, const RoutedEventArgs& /*args*/)
{
const auto extPkgVM = sender.as<FrameworkElement>().Tag().as<Editor::ExtensionPackageViewModel>();
const auto extPkgVM = sender.as<Controls::Button>().Tag().as<Editor::ExtensionPackageViewModel>();
_ViewModel.CurrentExtensionPackage(extPkgVM);
}

View File

@@ -127,58 +127,78 @@
<DataTemplate x:Key="DefaultExtensionNavigatorTemplate"
x:DataType="local:ExtensionPackageViewModel">
<local:SettingsCard AutomationProperties.Name="{x:Bind AccessibleName}"
Click="ExtensionNavigator_Click"
Header="{x:Bind Package.Source}"
IsClickEnabled="True"
Tag="{x:Bind}">
<local:SettingsCard.HeaderIcon>
<FontIcon Glyph="&#xE74C;" />
</local:SettingsCard.HeaderIcon>
<ToggleSwitch HorizontalAlignment="Right"
VerticalAlignment="Center"
AutomationProperties.Name="{x:Bind AccessibleName}"
IsOn="{x:Bind Enabled, Mode=TwoWay}"
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
</local:SettingsCard>
<Button AutomationProperties.Name="{x:Bind AccessibleName}"
Click="ExtensionNavigator_Click"
Style="{StaticResource NavigatorButtonStyle}"
Tag="{x:Bind}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentPresenter Content="{x:Bind}"
ContentTemplate="{StaticResource DefaultExtensionIdentifierTemplate}" />
<ToggleSwitch Grid.Column="1"
HorizontalAlignment="Right"
VerticalAlignment="Center"
AutomationProperties.Name="{x:Bind AccessibleName}"
IsOn="{x:Bind Enabled, Mode=TwoWay}"
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
</Grid>
</Button>
</DataTemplate>
<DataTemplate x:Key="ComplexExtensionNavigatorTemplate"
x:DataType="local:ExtensionPackageViewModel">
<local:SettingsCard AutomationProperties.Name="{x:Bind AccessibleName}"
Click="ExtensionNavigator_Click"
Description="{x:Bind Package.Source}"
Header="{x:Bind Package.DisplayName}"
IsClickEnabled="True"
Tag="{x:Bind}">
<local:SettingsCard.HeaderIcon>
<IconSourceElement IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Package.Icon)}" />
</local:SettingsCard.HeaderIcon>
<ToggleSwitch HorizontalAlignment="Right"
VerticalAlignment="Center"
AutomationProperties.Name="{x:Bind AccessibleName}"
IsOn="{x:Bind Enabled, Mode=TwoWay}"
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
</local:SettingsCard>
<Button AutomationProperties.Name="{x:Bind AccessibleName}"
Click="ExtensionNavigator_Click"
Style="{StaticResource NavigatorButtonStyle}"
Tag="{x:Bind}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentPresenter Content="{x:Bind}"
ContentTemplate="{StaticResource ComplexExtensionIdentifierTemplate}" />
<ToggleSwitch Grid.Column="1"
HorizontalAlignment="Right"
VerticalAlignment="Center"
AutomationProperties.Name="{x:Bind AccessibleName}"
IsOn="{x:Bind Enabled, Mode=TwoWay}"
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
</Grid>
</Button>
</DataTemplate>
<DataTemplate x:Key="ComplexExtensionNavigatorTemplateWithFontIcon"
x:DataType="local:ExtensionPackageViewModel">
<local:SettingsCard AutomationProperties.Name="{x:Bind AccessibleName}"
Click="ExtensionNavigator_Click"
Description="{x:Bind Package.Source}"
Header="{x:Bind Package.DisplayName}"
IsClickEnabled="True"
Tag="{x:Bind}">
<local:SettingsCard.HeaderIcon>
<FontIcon Glyph="{x:Bind Package.Icon}" />
</local:SettingsCard.HeaderIcon>
<ToggleSwitch HorizontalAlignment="Right"
VerticalAlignment="Center"
AutomationProperties.Name="{x:Bind AccessibleName}"
IsOn="{x:Bind Enabled, Mode=TwoWay}"
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
</local:SettingsCard>
<Button AutomationProperties.Name="{x:Bind AccessibleName}"
Click="ExtensionNavigator_Click"
Style="{StaticResource NavigatorButtonStyle}"
Tag="{x:Bind}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentPresenter Content="{x:Bind}"
ContentTemplate="{StaticResource ComplexExtensionIdentifierTemplateWithFontIcon}" />
<ToggleSwitch Grid.Column="1"
HorizontalAlignment="Right"
VerticalAlignment="Center"
AutomationProperties.Name="{x:Bind AccessibleName}"
IsOn="{x:Bind Enabled, Mode=TwoWay}"
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
</Grid>
</Button>
</DataTemplate>
<DataTemplate x:Key="FragmentProfileViewModelTemplate"
@@ -482,11 +502,9 @@
<!-- Scope -->
<local:SettingContainer x:Name="Scope"
x:Uid="Extensions_Scope"
IsTabStop="False">
<TextBlock VerticalAlignment="Center"
Style="{ThemeResource SecondaryTextBlockStyle}"
Text="{x:Bind ViewModel.CurrentExtensionPackage.Scope, Mode=OneWay}" />
</local:SettingContainer>
Content="{x:Bind ViewModel.CurrentExtensionPackage.Scope, Mode=OneWay}"
IsTabStop="False"
Style="{StaticResource SettingContainerWithTextContent}" />
<!-- JSON -->
<ItemsControl IsTabStop="False"
ItemTemplate="{StaticResource JsonTemplate}"

View File

@@ -62,9 +62,9 @@
<!-- Always show tabs -->
<local:SettingContainer x:Name="AlwaysShowTabs"
x:Uid="Globals_AlwaysShowTabs"
IsEnabled="{x:Bind mtu:Converters.InvertBoolean(ViewModel.ShowTabsInTitlebar), Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind ViewModel.AlwaysShowTabs, Mode=TwoWay}"
x:Uid="Globals_AlwaysShowTabs">
<ToggleSwitch IsEnabled="{x:Bind mtu:Converters.InvertBoolean(ViewModel.ShowTabsInTitlebar), Mode=OneWay}"
IsOn="{x:Bind ViewModel.AlwaysShowTabs, Mode=TwoWay}"
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
</local:SettingContainer>
@@ -75,6 +75,13 @@
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
</local:SettingContainer>
<!-- Show pane headers -->
<local:SettingContainer x:Name="ShowPaneHeaders"
x:Uid="Globals_ShowPaneHeaders">
<ToggleSwitch IsOn="{x:Bind ViewModel.ShowPaneHeaders, Mode=TwoWay}"
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
</local:SettingContainer>
<!-- Show Acrylic in Tab Row -->
<local:SettingContainer x:Name="AcrylicTabRow"
x:Uid="Globals_AcrylicTabRow">

View File

@@ -33,6 +33,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, AlwaysShowTabs);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ShowTabsFullscreen);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ShowPaneHeaders);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ShowTabsInTitlebar);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, UseAcrylicInTabRow);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ShowTitleInTitlebar);

View File

@@ -27,6 +27,7 @@ namespace Microsoft.Terminal.Settings.Editor
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, AlwaysShowTabs);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, ShowTabsFullscreen);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, ShowPaneHeaders);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, ShowTabsInTitlebar);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, UseAcrylicInTabRow);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, ShowTitleInTitlebar);

View File

@@ -173,24 +173,6 @@
<ClInclude Include="SettingContainer.h">
<DependentUpon>SettingContainer.idl</DependentUpon>
</ClInclude>
<ClInclude Include="SettingsCard.h">
<DependentUpon>SettingsCard.idl</DependentUpon>
</ClInclude>
<ClInclude Include="SettingsExpander.h">
<DependentUpon>SettingsExpander.idl</DependentUpon>
</ClInclude>
<ClInclude Include="StyleExtensions.h">
<DependentUpon>StyleExtensions.idl</DependentUpon>
</ClInclude>
<ClInclude Include="ControlSizeTrigger.h">
<DependentUpon>ControlSizeTrigger.idl</DependentUpon>
</ClInclude>
<ClInclude Include="CornerRadiusFilterConverters.h">
<DependentUpon>CornerRadiusFilterConverters.idl</DependentUpon>
</ClInclude>
<ClInclude Include="StringDefaultTemplateSelector.h">
<DependentUpon>StringDefaultTemplateSelector.idl</DependentUpon>
</ClInclude>
<ClInclude Include="Utils.h" />
<ClInclude Include="PreviewConnection.h" />
<ClInclude Include="$(GeneratedFilesDir)GeneratedSettingsIndex.g.h" />
@@ -270,12 +252,6 @@
<Page Include="SettingContainerStyle.xaml">
<Type>DefaultStyle</Type>
</Page>
<Page Include="SettingsControlsStyle.xaml">
<Type>DefaultStyle</Type>
</Page>
<Page Include="SettingsControlsImplicitStyles.xaml">
<Type>DefaultStyle</Type>
</Page>
</ItemGroup>
<!-- ========================= Cpp Files ======================== -->
<ItemGroup>
@@ -409,24 +385,6 @@
<ClCompile Include="SettingContainer.cpp">
<DependentUpon>SettingContainer.idl</DependentUpon>
</ClCompile>
<ClCompile Include="SettingsCard.cpp">
<DependentUpon>SettingsCard.idl</DependentUpon>
</ClCompile>
<ClCompile Include="SettingsExpander.cpp">
<DependentUpon>SettingsExpander.idl</DependentUpon>
</ClCompile>
<ClCompile Include="StyleExtensions.cpp">
<DependentUpon>StyleExtensions.idl</DependentUpon>
</ClCompile>
<ClCompile Include="ControlSizeTrigger.cpp">
<DependentUpon>ControlSizeTrigger.idl</DependentUpon>
</ClCompile>
<ClCompile Include="CornerRadiusFilterConverters.cpp">
<DependentUpon>CornerRadiusFilterConverters.idl</DependentUpon>
</ClCompile>
<ClCompile Include="StringDefaultTemplateSelector.cpp">
<DependentUpon>StringDefaultTemplateSelector.idl</DependentUpon>
</ClCompile>
<ClCompile Include="Utils.cpp" />
<ClCompile Include="PreviewConnection.cpp">
<DependentUpon>PreviewConnection.h</DependentUpon>
@@ -534,24 +492,6 @@
<Midl Include="SettingContainer.idl">
<SubType>Code</SubType>
</Midl>
<Midl Include="SettingsCard.idl">
<SubType>Code</SubType>
</Midl>
<Midl Include="SettingsExpander.idl">
<SubType>Code</SubType>
</Midl>
<Midl Include="StyleExtensions.idl">
<SubType>Code</SubType>
</Midl>
<Midl Include="ControlSizeTrigger.idl">
<SubType>Code</SubType>
</Midl>
<Midl Include="CornerRadiusFilterConverters.idl">
<SubType>Code</SubType>
</Midl>
<Midl Include="StringDefaultTemplateSelector.idl">
<SubType>Code</SubType>
</Midl>
</ItemGroup>
<!-- ========================= Misc Files ======================== -->
<ItemGroup>

View File

@@ -30,12 +30,6 @@
<Midl Include="LaunchViewModel.idl" />
<Midl Include="EnumEntry.idl" />
<Midl Include="SettingContainer.idl" />
<Midl Include="SettingsCard.idl" />
<Midl Include="SettingsExpander.idl" />
<Midl Include="StyleExtensions.idl" />
<Midl Include="ControlSizeTrigger.idl" />
<Midl Include="CornerRadiusFilterConverters.idl" />
<Midl Include="StringDefaultTemplateSelector.idl" />
<Midl Include="TerminalColorConverters.idl" />
<Midl Include="NewTabMenuViewModel.idl" />
</ItemGroup>
@@ -58,8 +52,6 @@
<Page Include="Actions.xaml" />
<Page Include="EditAction.xaml" />
<Page Include="SettingContainerStyle.xaml" />
<Page Include="SettingsControlsStyle.xaml" />
<Page Include="SettingsControlsImplicitStyles.xaml" />
<Page Include="AddProfile.xaml" />
<Page Include="KeyChordListener.xaml" />
<Page Include="NullableColorPicker.xaml" />

View File

@@ -332,7 +332,7 @@
<local:SettingContainer x:Name="CurrentFolderIcon"
x:Uid="NewTabMenu_CurrentFolderIcon"
CurrentValueAccessibleName="{x:Bind ViewModel.CurrentFolderLocalizedIcon, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyle}">
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
<local:SettingContainer.CurrentValue>
<Grid>
<ContentControl Width="16"
@@ -378,7 +378,8 @@
<!-- Add Profile -->
<local:SettingContainer x:Name="AddProfile"
x:Uid="NewTabMenu_AddProfile"
FontIconGlyph="&#xE756;">
FontIconGlyph="&#xE756;"
Style="{StaticResource SettingContainerWithIcon}">
<StackPanel Orientation="Horizontal"
Spacing="4">
@@ -427,7 +428,8 @@
<!-- Add Separator -->
<local:SettingContainer x:Name="AddSeparator"
x:Uid="NewTabMenu_AddSeparator"
FontIconGlyph="&#xE76f;">
FontIconGlyph="&#xE76f;"
Style="{StaticResource SettingContainerWithIcon}">
<Button x:Name="AddSeparatorButton"
x:Uid="NewTabMenu_AddSeparatorButton"
HorizontalAlignment="Stretch"
@@ -443,7 +445,8 @@
<!-- Add Folder -->
<local:SettingContainer x:Name="AddFolder"
x:Uid="NewTabMenu_AddFolder"
FontIconGlyph="&#xF12B;">
FontIconGlyph="&#xF12B;"
Style="{StaticResource SettingContainerWithIcon}">
<StackPanel Orientation="Horizontal"
Spacing="5">
<TextBox x:Name="FolderNameTextBox"
@@ -470,7 +473,7 @@
<local:SettingContainer x:Name="AddMatchProfiles"
x:Uid="NewTabMenu_AddMatchProfiles"
FontIconGlyph="&#xE748;"
Style="{StaticResource ExpanderSettingContainerStyle}">
Style="{StaticResource ExpanderSettingContainerStyleWithIcon}">
<StackPanel Spacing="8">
<HyperlinkButton x:Uid="NewTabMenu_AddMatchProfiles_Help"
NavigateUri="https://learn.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference" />
@@ -497,7 +500,8 @@
<!-- Add Remaining Profiles -->
<local:SettingContainer x:Name="AddRemainingProfiles"
x:Uid="NewTabMenu_AddRemainingProfiles"
FontIconGlyph="&#xE902;">
FontIconGlyph="&#xE902;"
Style="{StaticResource SettingContainerWithIcon}">
<Button x:Name="AddRemainingProfilesButton"
x:Uid="NewTabMenu_AddRemainingProfilesButton"
HorizontalAlignment="Stretch"

View File

@@ -106,6 +106,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
_NotifyChanges(L"CurrentPathTranslationStyle");
}
else if (viewModelProperty == L"NotifyOnActivity")
{
_NotifyChanges(L"IsNotifyOnActivityFlagSet", L"NotifyOnActivityPreview");
}
else if (viewModelProperty == L"NotifyOnNextPrompt")
{
_NotifyChanges(L"IsNotifyOnNextPromptFlagSet", L"NotifyOnNextPromptPreview");
}
else if (viewModelProperty == L"Padding")
{
_parsedPadding = StringToXamlThickness(_profile.Padding());
@@ -571,6 +579,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
return iconPath.empty() || iconPath == IconPicker::HideIconValue;
}
#pragma region BellStyle
hstring ProfileViewModel::BellStylePreview() const
{
const auto bellStyle = BellStyle();
@@ -650,6 +659,147 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
WI_UpdateFlag(currentStyle, Model::BellStyle::Notification, winrt::unbox_value<bool>(on));
BellStyle(currentStyle);
}
#pragma endregion
#pragma region NotifyOnActivity
hstring ProfileViewModel::NotifyOnActivityPreview() const
{
using Ons = Control::OutputNotificationStyle;
const auto style = NotifyOnActivity();
if (WI_AreAllFlagsSet(style, Ons::Taskbar | Ons::Audible | Ons::Tab | Ons::Notification))
{
return RS_(L"Profile_OutputNotificationStyleAll/Content");
}
else if (style == Ons::None)
{
return RS_(L"Profile_OutputNotificationStyleNone/Content");
}
std::wstring result;
const auto appendIfFlagSet = [&](Ons flag, std::wstring_view resource) {
// WI_IsFlagSet requires a compile-time constant flag; `flag` is a runtime parameter here.
if ((WI_EnumValue(style) & WI_EnumValue(flag)) != 0)
{
if (!result.empty())
{
result.append(L", ");
}
result.append(resource);
}
};
appendIfFlagSet(Ons::Taskbar, RS_(L"Profile_OutputNotificationStyleTaskbar/Content"));
appendIfFlagSet(Ons::Audible, RS_(L"Profile_OutputNotificationStyleAudible/Content"));
appendIfFlagSet(Ons::Tab, RS_(L"Profile_OutputNotificationStyleTab/Content"));
appendIfFlagSet(Ons::Notification, RS_(L"Profile_OutputNotificationStyleNotification/Content"));
return hstring{ result };
}
bool ProfileViewModel::IsNotifyOnActivityFlagSet(const uint32_t flag)
{
return (WI_EnumValue(NotifyOnActivity()) & flag) == flag;
}
void ProfileViewModel::SetNotifyOnActivityTaskbar(winrt::Windows::Foundation::IReference<bool> on)
{
auto currentStyle = NotifyOnActivity();
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Taskbar, winrt::unbox_value<bool>(on));
NotifyOnActivity(currentStyle);
}
void ProfileViewModel::SetNotifyOnActivityAudible(winrt::Windows::Foundation::IReference<bool> on)
{
auto currentStyle = NotifyOnActivity();
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Audible, winrt::unbox_value<bool>(on));
NotifyOnActivity(currentStyle);
}
void ProfileViewModel::SetNotifyOnActivityTab(winrt::Windows::Foundation::IReference<bool> on)
{
auto currentStyle = NotifyOnActivity();
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Tab, winrt::unbox_value<bool>(on));
NotifyOnActivity(currentStyle);
}
void ProfileViewModel::SetNotifyOnActivityNotification(winrt::Windows::Foundation::IReference<bool> on)
{
auto currentStyle = NotifyOnActivity();
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Notification, winrt::unbox_value<bool>(on));
NotifyOnActivity(currentStyle);
}
#pragma endregion
#pragma region NotifyOnNextPrompt
hstring ProfileViewModel::NotifyOnNextPromptPreview() const
{
using Ons = Control::OutputNotificationStyle;
const auto style = NotifyOnNextPrompt();
if (WI_AreAllFlagsSet(style, Ons::Taskbar | Ons::Audible | Ons::Tab | Ons::Notification))
{
return RS_(L"Profile_OutputNotificationStyleAll/Content");
}
else if (style == Ons::None)
{
return RS_(L"Profile_OutputNotificationStyleNone/Content");
}
std::wstring result;
const auto appendIfFlagSet = [&](Ons flag, std::wstring_view resource) {
// WI_IsFlagSet requires a compile-time constant flag; `flag` is a runtime parameter here.
if ((WI_EnumValue(style) & WI_EnumValue(flag)) != 0)
{
if (!result.empty())
{
result.append(L", ");
}
result.append(resource);
}
};
appendIfFlagSet(Ons::Taskbar, RS_(L"Profile_OutputNotificationStyleTaskbar/Content"));
appendIfFlagSet(Ons::Audible, RS_(L"Profile_OutputNotificationStyleAudible/Content"));
appendIfFlagSet(Ons::Tab, RS_(L"Profile_OutputNotificationStyleTab/Content"));
appendIfFlagSet(Ons::Notification, RS_(L"Profile_OutputNotificationStyleNotification/Content"));
return hstring{ result };
}
bool ProfileViewModel::IsNotifyOnNextPromptFlagSet(const uint32_t flag)
{
return (WI_EnumValue(NotifyOnNextPrompt()) & flag) == flag;
}
void ProfileViewModel::SetNotifyOnNextPromptTaskbar(winrt::Windows::Foundation::IReference<bool> on)
{
auto currentStyle = NotifyOnNextPrompt();
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Taskbar, winrt::unbox_value<bool>(on));
NotifyOnNextPrompt(currentStyle);
}
void ProfileViewModel::SetNotifyOnNextPromptAudible(winrt::Windows::Foundation::IReference<bool> on)
{
auto currentStyle = NotifyOnNextPrompt();
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Audible, winrt::unbox_value<bool>(on));
NotifyOnNextPrompt(currentStyle);
}
void ProfileViewModel::SetNotifyOnNextPromptTab(winrt::Windows::Foundation::IReference<bool> on)
{
auto currentStyle = NotifyOnNextPrompt();
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Tab, winrt::unbox_value<bool>(on));
NotifyOnNextPrompt(currentStyle);
}
void ProfileViewModel::SetNotifyOnNextPromptNotification(winrt::Windows::Foundation::IReference<bool> on)
{
auto currentStyle = NotifyOnNextPrompt();
WI_UpdateFlag(currentStyle, Control::OutputNotificationStyle::Notification, winrt::unbox_value<bool>(on));
NotifyOnNextPrompt(currentStyle);
}
#pragma endregion
#pragma region BellSound
// Method Description:
// - Construct _CurrentBellSounds by importing the _inherited_ value from the model
@@ -788,6 +938,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
_NotifyChanges(L"CurrentBellSounds");
}
}
#pragma endregion
void ProfileViewModel::DeleteProfile()
{

View File

@@ -48,6 +48,22 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void SetBellStyleTaskbar(winrt::Windows::Foundation::IReference<bool> on);
void SetBellStyleNotification(winrt::Windows::Foundation::IReference<bool> on);
// notify on activity bits
hstring NotifyOnActivityPreview() const;
bool IsNotifyOnActivityFlagSet(const uint32_t flag);
void SetNotifyOnActivityTaskbar(winrt::Windows::Foundation::IReference<bool> on);
void SetNotifyOnActivityAudible(winrt::Windows::Foundation::IReference<bool> on);
void SetNotifyOnActivityTab(winrt::Windows::Foundation::IReference<bool> on);
void SetNotifyOnActivityNotification(winrt::Windows::Foundation::IReference<bool> on);
// notify on next prompt bits
hstring NotifyOnNextPromptPreview() const;
bool IsNotifyOnNextPromptFlagSet(const uint32_t flag);
void SetNotifyOnNextPromptTaskbar(winrt::Windows::Foundation::IReference<bool> on);
void SetNotifyOnNextPromptAudible(winrt::Windows::Foundation::IReference<bool> on);
void SetNotifyOnNextPromptTab(winrt::Windows::Foundation::IReference<bool> on);
void SetNotifyOnNextPromptNotification(winrt::Windows::Foundation::IReference<bool> on);
hstring BellSoundPreview();
void RequestAddBellSound(hstring path);
void RequestDeleteBellSound(const Editor::BellSoundViewModel& vm);
@@ -143,10 +159,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
OBSERVABLE_PROJECTED_SETTING(_profile, AllowKittyKeyboardMode);
OBSERVABLE_PROJECTED_SETTING(_profile, AllowVtChecksumReport);
OBSERVABLE_PROJECTED_SETTING(_profile, AllowVtClipboardWrite);
OBSERVABLE_PROJECTED_SETTING(_profile, AllowOscNotifications);
OBSERVABLE_PROJECTED_SETTING(_profile, AnswerbackMessage);
OBSERVABLE_PROJECTED_SETTING(_profile, RainbowSuggestions);
OBSERVABLE_PROJECTED_SETTING(_profile, PathTranslationStyle);
OBSERVABLE_PROJECTED_SETTING(_profile, DragDropDelimiter);
OBSERVABLE_PROJECTED_SETTING(_profile, NotifyOnActivity);
OBSERVABLE_PROJECTED_SETTING(_profile, NotifyOnNextPrompt);
OBSERVABLE_PROJECTED_SETTING(_profile, AutoDetectRunningCommand);
WINRT_PROPERTY(bool, IsBaseLayer, false);
WINRT_PROPERTY(bool, FocusDeleteButton, false);

View File

@@ -51,6 +51,20 @@ namespace Microsoft.Terminal.Settings.Editor
void SetBellStyleTaskbar(Windows.Foundation.IReference<Boolean> on);
void SetBellStyleNotification(Windows.Foundation.IReference<Boolean> on);
String NotifyOnActivityPreview { get; };
Boolean IsNotifyOnActivityFlagSet(UInt32 flag);
void SetNotifyOnActivityTaskbar(Windows.Foundation.IReference<Boolean> on);
void SetNotifyOnActivityAudible(Windows.Foundation.IReference<Boolean> on);
void SetNotifyOnActivityTab(Windows.Foundation.IReference<Boolean> on);
void SetNotifyOnActivityNotification(Windows.Foundation.IReference<Boolean> on);
String NotifyOnNextPromptPreview { get; };
Boolean IsNotifyOnNextPromptFlagSet(UInt32 flag);
void SetNotifyOnNextPromptTaskbar(Windows.Foundation.IReference<Boolean> on);
void SetNotifyOnNextPromptAudible(Windows.Foundation.IReference<Boolean> on);
void SetNotifyOnNextPromptTab(Windows.Foundation.IReference<Boolean> on);
void SetNotifyOnNextPromptNotification(Windows.Foundation.IReference<Boolean> on);
String BellSoundPreview { get; };
Windows.Foundation.Collections.IObservableVector<BellSoundViewModel> CurrentBellSounds { get; };
void RequestAddBellSound(String path);
@@ -142,5 +156,9 @@ namespace Microsoft.Terminal.Settings.Editor
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Control.PathTranslationStyle, PathTranslationStyle);
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, DragDropDelimiter);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AllowVtClipboardWrite);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AllowOscNotifications);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Control.OutputNotificationStyle, NotifyOnActivity);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Control.OutputNotificationStyle, NotifyOnNextPrompt);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AutoDetectRunningCommand);
}
}

View File

@@ -198,6 +198,56 @@
</StackPanel>
</local:SettingContainer>
<!-- Notify On Activity -->
<local:SettingContainer x:Name="NotifyOnActivity"
x:Uid="Profile_NotifyOnActivity"
ClearSettingValue="{x:Bind Profile.ClearNotifyOnActivity}"
CurrentValue="{x:Bind Profile.NotifyOnActivityPreview, Mode=OneWay}"
HasSettingValue="{x:Bind Profile.HasNotifyOnActivity, Mode=OneWay}"
SettingOverrideSource="{x:Bind Profile.NotifyOnActivityOverrideSource, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyle}">
<StackPanel>
<CheckBox x:Uid="Profile_OutputNotificationStyleTaskbar"
IsChecked="{x:Bind Profile.IsNotifyOnActivityFlagSet(1), BindBack=Profile.SetNotifyOnActivityTaskbar, Mode=TwoWay}" />
<CheckBox x:Uid="Profile_OutputNotificationStyleAudible"
IsChecked="{x:Bind Profile.IsNotifyOnActivityFlagSet(2), BindBack=Profile.SetNotifyOnActivityAudible, Mode=TwoWay}" />
<CheckBox x:Uid="Profile_OutputNotificationStyleTab"
IsChecked="{x:Bind Profile.IsNotifyOnActivityFlagSet(4), BindBack=Profile.SetNotifyOnActivityTab, Mode=TwoWay}" />
<CheckBox x:Uid="Profile_OutputNotificationStyleNotification"
IsChecked="{x:Bind Profile.IsNotifyOnActivityFlagSet(8), BindBack=Profile.SetNotifyOnActivityNotification, Mode=TwoWay}" />
</StackPanel>
</local:SettingContainer>
<!-- Notify On Next Prompt -->
<local:SettingContainer x:Name="NotifyOnNextPrompt"
x:Uid="Profile_NotifyOnNextPrompt"
ClearSettingValue="{x:Bind Profile.ClearNotifyOnNextPrompt}"
CurrentValue="{x:Bind Profile.NotifyOnNextPromptPreview, Mode=OneWay}"
HasSettingValue="{x:Bind Profile.HasNotifyOnNextPrompt, Mode=OneWay}"
SettingOverrideSource="{x:Bind Profile.NotifyOnNextPromptOverrideSource, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyle}">
<StackPanel>
<CheckBox x:Uid="Profile_OutputNotificationStyleTaskbar"
IsChecked="{x:Bind Profile.IsNotifyOnNextPromptFlagSet(1), BindBack=Profile.SetNotifyOnNextPromptTaskbar, Mode=TwoWay}" />
<CheckBox x:Uid="Profile_OutputNotificationStyleAudible"
IsChecked="{x:Bind Profile.IsNotifyOnNextPromptFlagSet(2), BindBack=Profile.SetNotifyOnNextPromptAudible, Mode=TwoWay}" />
<CheckBox x:Uid="Profile_OutputNotificationStyleTab"
IsChecked="{x:Bind Profile.IsNotifyOnNextPromptFlagSet(4), BindBack=Profile.SetNotifyOnNextPromptTab, Mode=TwoWay}" />
<CheckBox x:Uid="Profile_OutputNotificationStyleNotification"
IsChecked="{x:Bind Profile.IsNotifyOnNextPromptFlagSet(8), BindBack=Profile.SetNotifyOnNextPromptNotification, Mode=TwoWay}" />
</StackPanel>
</local:SettingContainer>
<!-- Auto Detect Running Command -->
<local:SettingContainer x:Name="AutoDetectRunningCommand"
x:Uid="Profile_AutoDetectRunningCommand"
ClearSettingValue="{x:Bind Profile.ClearAutoDetectRunningCommand}"
HasSettingValue="{x:Bind Profile.HasAutoDetectRunningCommand, Mode=OneWay}"
SettingOverrideSource="{x:Bind Profile.AutoDetectRunningCommandOverrideSource, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind Profile.AutoDetectRunningCommand, Mode=TwoWay}"
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
</local:SettingContainer>
<!-- RightClickContextMenu -->
<local:SettingContainer x:Name="RightClickContextMenu"
x:Uid="Profile_RightClickContextMenu"

View File

@@ -22,9 +22,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
Automation::AutomationProperties::SetFullDescription(StartingDirectoryUseParentCheckbox(), unbox_value<hstring>(startingDirCheckboxTooltip));
Automation::AutomationProperties::SetName(DeleteButton(), RS_(L"Profile_DeleteButton/Text"));
AppearanceNavigator().Header(box_value(RS_(L"Profile_Appearance/Header")));
TerminalNavigator().Header(box_value(RS_(L"Profile_Terminal/Header")));
AdvancedNavigator().Header(box_value(RS_(L"Profile_Advanced/Header")));
AppearanceNavigator().Content(box_value(RS_(L"Profile_Appearance/Header")));
TerminalNavigator().Content(box_value(RS_(L"Profile_Terminal/Header")));
AdvancedNavigator().Content(box_value(RS_(L"Profile_Advanced/Header")));
}
void Profiles_Base::OnNavigatedTo(const NavigationEventArgs& e)

View File

@@ -106,7 +106,7 @@
CurrentValueAccessibleName="{x:Bind Profile.LocalizedIcon, Mode=OneWay}"
HasSettingValue="{x:Bind Profile.HasIcon, Mode=OneWay}"
SettingOverrideSource="{x:Bind Profile.IconOverrideSource, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyle}">
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
<local:SettingContainer.CurrentValue>
<Grid>
<ContentControl Width="16"
@@ -150,7 +150,7 @@
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
HasSettingValue="{x:Bind Profile.HasTabColor, Mode=OneWay}"
SettingOverrideSource="{x:Bind Profile.TabColorOverrideSource, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyle}">
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
<local:NullableColorPicker x:Uid="Profile_TabColor_NullableColorPicker"
ColorSchemeVM="{x:Bind Profile.DefaultAppearance.CurrentColorScheme, Mode=OneWay}"
CurrentColor="{x:Bind Profile.TabColor, Mode=TwoWay}"
@@ -179,15 +179,15 @@
Margin="0,32,0,4"
Style="{StaticResource TextBlockSubHeaderStyle}" />
<local:SettingsCard x:Name="AppearanceNavigator"
Click="Appearance_Click"
IsClickEnabled="True" />
<local:SettingsCard x:Name="TerminalNavigator"
Click="Terminal_Click"
IsClickEnabled="True" />
<local:SettingsCard x:Name="AdvancedNavigator"
Click="Advanced_Click"
IsClickEnabled="True" />
<Button x:Name="AppearanceNavigator"
Click="Appearance_Click"
Style="{StaticResource NavigatorButtonStyle}" />
<Button x:Name="TerminalNavigator"
Click="Terminal_Click"
Style="{StaticResource NavigatorButtonStyle}" />
<Button x:Name="AdvancedNavigator"
Click="Advanced_Click"
Style="{StaticResource NavigatorButtonStyle}" />
<!-- Delete Button -->
<Border MaxWidth="{StaticResource StandardControlMaxWidth}">
<Button x:Name="DeleteButton"

View File

@@ -81,6 +81,16 @@
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
</local:SettingContainer>
<!-- Allow OSC 777 Desktop Notifications -->
<local:SettingContainer x:Name="AllowOscNotifications"
x:Uid="Profile_AllowOscNotifications"
ClearSettingValue="{x:Bind Profile.ClearAllowOscNotifications}"
HasSettingValue="{x:Bind Profile.HasAllowOscNotifications, Mode=OneWay}"
SettingOverrideSource="{x:Bind Profile.AllowOscNotificationsOverrideSource, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind Profile.AllowOscNotifications, Mode=TwoWay}"
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
</local:SettingContainer>
<!-- Answerback Message -->
<local:SettingContainer x:Name="AnswerbackMessage"
x:Uid="Profile_AnswerbackMessage"

View File

@@ -1553,10 +1553,6 @@
<value>Blinkendes Fenster</value>
<comment>An option to choose from for the "bell style" setting. When selected, a visual notification is used to notify the user. In this case, the window is flashed.</comment>
</data>
<data name="Profile_BellStyleNotification.Content" xml:space="preserve">
<value>Desktopbenachrichtigung</value>
<comment>An option to choose from for the "bell style" setting. When selected, a Windows desktop notification (toast) is sent to notify the user.</comment>
</data>
<data name="ColorScheme_AddNewButton.Text" xml:space="preserve">
<value>Neu hinzufügen</value>
<comment>Button label that creates a new color scheme.</comment>
@@ -2201,26 +2197,6 @@
<value>Warnen, wenn mehrere Registerkarten geschlossen werden</value>
<comment>Header for a control to toggle whether to show a confirm dialog box when closing the application with multiple tabs open.</comment>
</data>
<data name="Globals_ConfirmOnClose.Header" xml:space="preserve">
<value>Beim Schließen warnen</value>
<comment>Header for a dropdown controlling when to show a confirmation dialog before closing.</comment>
</data>
<data name="Globals_ConfirmOnClose.HelpText" xml:space="preserve">
<value>Steuert, wann ein Bestätigungsdialogfeld angezeigt wird, bevor Registerkarten oder Fenster geschlossen werden. "Immer" zeigt das Dialogfeld beim Schließen eines Fensters an.</value>
<comment>Help text associated with Globals_ConfirmOnClose. "Always" refers to Globals_ConfirmOnCloseAlways.Content.</comment>
</data>
<data name="Globals_ConfirmOnCloseNever.Content" xml:space="preserve">
<value>Nie</value>
<comment>Option associated with Globals_ConfirmOnClose. "Never" means that the system will never display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAlways.Content" xml:space="preserve">
<value>Immer</value>
<comment>Option associated with Globals_ConfirmOnClose. "Always" means that the system will always display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAutomatic.Content" xml:space="preserve">
<value>Mehrere Registerkarten oder Bereiche</value>
<comment>Option associated with Globals_ConfirmOnClose. The system will display a warning when multiple tabs or panes are present.</comment>
</data>
<data name="Globals_InputServiceWarning.Header" xml:space="preserve">
<value>Warnen, wenn „Dienst für Bildschirmtastatur und Handschrifteingabefeld“ deaktiviert ist</value>
</data>

View File

@@ -573,6 +573,14 @@
<value>Allow OSC 52 (Manipulate Selection Data) to write to the clipboard</value>
<comment>{Locked="OSC 52"}{Locked="Manipulate Selection Data"}Header for a control to toggle support for applications to change the contents of the Windows system clipboard.</comment>
</data>
<data name="Profile_AllowOscNotifications.Header" xml:space="preserve">
<value>Allow OSC 777 (Desktop Notification) to show toast notifications</value>
<comment>{Locked="OSC 777"}{Locked="Desktop Notification"}Header for a control to toggle support for applications to display desktop toast notifications via the OSC 777 escape sequence.</comment>
</data>
<data name="Profile_AllowOscNotifications.HelpText" xml:space="preserve">
<value>When enabled, applications can send the OSC 777 escape sequence to trigger a desktop notification with a custom title and body.</value>
<comment>{Locked="OSC 777"}Help text for the OSC 777 desktop notification toggle.</comment>
</data>
<data name="Globals_AllowHeadless.Header" xml:space="preserve">
<value>Allow Windows Terminal to run in the background</value>
<comment>Header for a control to toggle support for Windows Terminal to run in the background.</comment>
@@ -1553,6 +1561,54 @@
<value>Flash window</value>
<comment>An option to choose from for the "bell style" setting. When selected, a visual notification is used to notify the user. In this case, the window is flashed.</comment>
</data>
<data name="Profile_OutputNotificationStyleNone.Content" xml:space="preserve">
<value>None</value>
<comment>An option to choose from for the notification style setting. When selected, no notification is sent.</comment>
</data>
<data name="Profile_OutputNotificationStyleAll.Content" xml:space="preserve">
<value>All</value>
<comment>An option to choose from for the notification style setting. When selected, all notification methods are used.</comment>
</data>
<data name="Profile_OutputNotificationStyleTaskbar.Content" xml:space="preserve">
<value>Flash taskbar</value>
<comment>An option to choose from for the notification style setting. Flashes the taskbar icon.</comment>
</data>
<data name="Profile_OutputNotificationStyleAudible.Content" xml:space="preserve">
<value>Play sound</value>
<comment>An option to choose from for the notification style setting. Plays an audible notification sound.</comment>
</data>
<data name="Profile_OutputNotificationStyleTab.Content" xml:space="preserve">
<value>Show tab indicator</value>
<comment>An option to choose from for the notification style setting. Shows an activity indicator on the tab.</comment>
</data>
<data name="Profile_OutputNotificationStyleNotification.Content" xml:space="preserve">
<value>Desktop notification</value>
<comment>An option to choose from for the notification style setting. Sends a Windows desktop notification (toast).</comment>
</data>
<data name="Profile_NotifyOnActivity.Header" xml:space="preserve">
<value>Notify on activity</value>
<comment>Header for a control to set the notification style when a background tab has new activity (output).</comment>
</data>
<data name="Profile_NotifyOnActivity.HelpText" xml:space="preserve">
<value>Choose how to be notified when a background tab produces new output.</value>
<comment>Help text for the notify on activity setting.</comment>
</data>
<data name="Profile_NotifyOnNextPrompt.Header" xml:space="preserve">
<value>Notify on next prompt</value>
<comment>Header for a control to set the notification style when a new shell prompt is detected (requires shell integration).</comment>
</data>
<data name="Profile_NotifyOnNextPrompt.HelpText" xml:space="preserve">
<value>Choose how to be notified when a command finishes and a new prompt appears. Requires shell integration.</value>
<comment>Help text for the notify on next prompt setting.</comment>
</data>
<data name="Profile_AutoDetectRunningCommand.Header" xml:space="preserve">
<value>Auto-detect running command</value>
<comment>Header for a control to configure automatic detection of a running command's progress state.</comment>
</data>
<data name="Profile_AutoDetectRunningCommand.HelpText" xml:space="preserve">
<value>Automatically show a progress indicator when a command is running. Requires shell integration.</value>
<comment>Help text for the auto-detect running command setting.</comment>
</data>
<data name="Profile_BellStyleNotification.Content" xml:space="preserve">
<value>Desktop notification</value>
<comment>An option to choose from for the "bell style" setting. When selected, a Windows desktop notification (toast) is sent to notify the user.</comment>
@@ -2617,6 +2673,14 @@
<value>When enabled, the tab bar will be visible when the app is full screen.</value>
<comment>A description for what the "show tabs in full screen" setting does.</comment>
</data>
<data name="Globals_ShowPaneHeaders.Header" xml:space="preserve">
<value>Show pane title headers</value>
<comment>Header for a control to toggle if the app should show title headers above each pane when multiple panes are open.</comment>
</data>
<data name="Globals_ShowPaneHeaders.HelpText" xml:space="preserve">
<value>When enabled, a title header is shown above each pane when multiple panes are open.</value>
<comment>A description for what the "show pane headers" setting does. Presented near "Globals_ShowPaneHeaders.Header".</comment>
</data>
<data name="Profile_PathTranslationStyle.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Path translation</value>
<comment>Name for a control to select how file and directory paths are translated.</comment>

View File

@@ -1553,10 +1553,6 @@
<value>Ventana Flash</value>
<comment>An option to choose from for the "bell style" setting. When selected, a visual notification is used to notify the user. In this case, the window is flashed.</comment>
</data>
<data name="Profile_BellStyleNotification.Content" xml:space="preserve">
<value>Notificaciones de escritorio</value>
<comment>An option to choose from for the "bell style" setting. When selected, a Windows desktop notification (toast) is sent to notify the user.</comment>
</data>
<data name="ColorScheme_AddNewButton.Text" xml:space="preserve">
<value>Agregar nuevo</value>
<comment>Button label that creates a new color scheme.</comment>
@@ -2201,26 +2197,6 @@
<value>Advertir al cerrar más de una pestaña</value>
<comment>Header for a control to toggle whether to show a confirm dialog box when closing the application with multiple tabs open.</comment>
</data>
<data name="Globals_ConfirmOnClose.Header" xml:space="preserve">
<value>Advertir al cerrar</value>
<comment>Header for a dropdown controlling when to show a confirmation dialog before closing.</comment>
</data>
<data name="Globals_ConfirmOnClose.HelpText" xml:space="preserve">
<value>Controla cuándo aparece un cuadro de diálogo de confirmación antes de cerrar pestañas o ventanas. "Siempre" presenta el cuadro de diálogo al cerrar cualquier panel.</value>
<comment>Help text associated with Globals_ConfirmOnClose. "Always" refers to Globals_ConfirmOnCloseAlways.Content.</comment>
</data>
<data name="Globals_ConfirmOnCloseNever.Content" xml:space="preserve">
<value>Nunca</value>
<comment>Option associated with Globals_ConfirmOnClose. "Never" means that the system will never display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAlways.Content" xml:space="preserve">
<value>Siempre</value>
<comment>Option associated with Globals_ConfirmOnClose. "Always" means that the system will always display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAutomatic.Content" xml:space="preserve">
<value>Varias pestañas o paneles</value>
<comment>Option associated with Globals_ConfirmOnClose. The system will display a warning when multiple tabs or panes are present.</comment>
</data>
<data name="Globals_InputServiceWarning.Header" xml:space="preserve">
<value>Advertir cuando el servicio "Panel de escritura a mano y teclado táctil" está deshabilitado</value>
</data>

View File

@@ -1553,10 +1553,6 @@
<value>Fenêtre Flash</value>
<comment>An option to choose from for the "bell style" setting. When selected, a visual notification is used to notify the user. In this case, the window is flashed.</comment>
</data>
<data name="Profile_BellStyleNotification.Content" xml:space="preserve">
<value>Notification de bureau</value>
<comment>An option to choose from for the "bell style" setting. When selected, a Windows desktop notification (toast) is sent to notify the user.</comment>
</data>
<data name="ColorScheme_AddNewButton.Text" xml:space="preserve">
<value>Ajouter nouveau</value>
<comment>Button label that creates a new color scheme.</comment>
@@ -2201,26 +2197,6 @@
<value>M'avertir lorsque je ferme plusieurs onglets</value>
<comment>Header for a control to toggle whether to show a confirm dialog box when closing the application with multiple tabs open.</comment>
</data>
<data name="Globals_ConfirmOnClose.Header" xml:space="preserve">
<value>Avertir lors de la fermeture</value>
<comment>Header for a dropdown controlling when to show a confirmation dialog before closing.</comment>
</data>
<data name="Globals_ConfirmOnClose.HelpText" xml:space="preserve">
<value>Contrôle lapparition dune boîte de dialogue de confirmation avant la fermeture des onglets ou des fenêtres. « Toujours » affiche la boîte de dialogue lors de la fermeture de nimporte quel volet.</value>
<comment>Help text associated with Globals_ConfirmOnClose. "Always" refers to Globals_ConfirmOnCloseAlways.Content.</comment>
</data>
<data name="Globals_ConfirmOnCloseNever.Content" xml:space="preserve">
<value>Jamais</value>
<comment>Option associated with Globals_ConfirmOnClose. "Never" means that the system will never display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAlways.Content" xml:space="preserve">
<value>Toujours</value>
<comment>Option associated with Globals_ConfirmOnClose. "Always" means that the system will always display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAutomatic.Content" xml:space="preserve">
<value>Plusieurs onglets ou volets</value>
<comment>Option associated with Globals_ConfirmOnClose. The system will display a warning when multiple tabs or panes are present.</comment>
</data>
<data name="Globals_InputServiceWarning.Header" xml:space="preserve">
<value>Avertir lorsque le « service clavier tactile et volet décriture manuscrite » est désactivé</value>
</data>

View File

@@ -1553,10 +1553,6 @@
<value>Finestra di Flash</value>
<comment>An option to choose from for the "bell style" setting. When selected, a visual notification is used to notify the user. In this case, the window is flashed.</comment>
</data>
<data name="Profile_BellStyleNotification.Content" xml:space="preserve">
<value>Notifica desktop</value>
<comment>An option to choose from for the "bell style" setting. When selected, a Windows desktop notification (toast) is sent to notify the user.</comment>
</data>
<data name="ColorScheme_AddNewButton.Text" xml:space="preserve">
<value>Aggiungi nuovo</value>
<comment>Button label that creates a new color scheme.</comment>
@@ -2201,26 +2197,6 @@
<value>Avvisa in caso di chiusura di più schede</value>
<comment>Header for a control to toggle whether to show a confirm dialog box when closing the application with multiple tabs open.</comment>
</data>
<data name="Globals_ConfirmOnClose.Header" xml:space="preserve">
<value>Avvisa in caso di chiusura</value>
<comment>Header for a dropdown controlling when to show a confirmation dialog before closing.</comment>
</data>
<data name="Globals_ConfirmOnClose.HelpText" xml:space="preserve">
<value>Controlla quando viene visualizzata una finestra di dialogo di conferma prima di chiudere schede o finestre. "Sempre" visualizza la finestra di dialogo quando si chiude un riquadro.</value>
<comment>Help text associated with Globals_ConfirmOnClose. "Always" refers to Globals_ConfirmOnCloseAlways.Content.</comment>
</data>
<data name="Globals_ConfirmOnCloseNever.Content" xml:space="preserve">
<value>Mai</value>
<comment>Option associated with Globals_ConfirmOnClose. "Never" means that the system will never display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAlways.Content" xml:space="preserve">
<value>Sempre</value>
<comment>Option associated with Globals_ConfirmOnClose. "Always" means that the system will always display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAutomatic.Content" xml:space="preserve">
<value>Più schede o pannelli</value>
<comment>Option associated with Globals_ConfirmOnClose. The system will display a warning when multiple tabs or panes are present.</comment>
</data>
<data name="Globals_InputServiceWarning.Header" xml:space="preserve">
<value>Avvisa quando il servizio "Tastiera virtuale e pannello per la grafia" è disabilitato</value>
</data>

View File

@@ -1553,10 +1553,6 @@
<value>フラッシュ ウィンドウ</value>
<comment>An option to choose from for the "bell style" setting. When selected, a visual notification is used to notify the user. In this case, the window is flashed.</comment>
</data>
<data name="Profile_BellStyleNotification.Content" xml:space="preserve">
<value>デスクトップ通知</value>
<comment>An option to choose from for the "bell style" setting. When selected, a Windows desktop notification (toast) is sent to notify the user.</comment>
</data>
<data name="ColorScheme_AddNewButton.Text" xml:space="preserve">
<value>新規追加</value>
<comment>Button label that creates a new color scheme.</comment>
@@ -2201,26 +2197,6 @@
<value>複数のタブを閉じるときに警告する</value>
<comment>Header for a control to toggle whether to show a confirm dialog box when closing the application with multiple tabs open.</comment>
</data>
<data name="Globals_ConfirmOnClose.Header" xml:space="preserve">
<value>閉じるときに警告する</value>
<comment>Header for a dropdown controlling when to show a confirmation dialog before closing.</comment>
</data>
<data name="Globals_ConfirmOnClose.HelpText" xml:space="preserve">
<value>タブまたはウィンドウを閉じる前に確認ダイアログを表示するタイミングを制御します。[常に] を選択すると、ウィンドウを閉じるときにダイアログが表示されます。</value>
<comment>Help text associated with Globals_ConfirmOnClose. "Always" refers to Globals_ConfirmOnCloseAlways.Content.</comment>
</data>
<data name="Globals_ConfirmOnCloseNever.Content" xml:space="preserve">
<value>しない</value>
<comment>Option associated with Globals_ConfirmOnClose. "Never" means that the system will never display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAlways.Content" xml:space="preserve">
<value>常に</value>
<comment>Option associated with Globals_ConfirmOnClose. "Always" means that the system will always display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAutomatic.Content" xml:space="preserve">
<value>複数のタブまたはウィンドウ</value>
<comment>Option associated with Globals_ConfirmOnClose. The system will display a warning when multiple tabs or panes are present.</comment>
</data>
<data name="Globals_InputServiceWarning.Header" xml:space="preserve">
<value>[タッチ キーボードと手書きパネル サービス] が無効になっている場合に警告する</value>
</data>

View File

@@ -1553,10 +1553,6 @@
<value>플래시 창</value>
<comment>An option to choose from for the "bell style" setting. When selected, a visual notification is used to notify the user. In this case, the window is flashed.</comment>
</data>
<data name="Profile_BellStyleNotification.Content" xml:space="preserve">
<value>데스크톱 알림</value>
<comment>An option to choose from for the "bell style" setting. When selected, a Windows desktop notification (toast) is sent to notify the user.</comment>
</data>
<data name="ColorScheme_AddNewButton.Text" xml:space="preserve">
<value>새로 추가</value>
<comment>Button label that creates a new color scheme.</comment>
@@ -2201,26 +2197,6 @@
<value>두 개 이상의 탭을 닫을 때 경고</value>
<comment>Header for a control to toggle whether to show a confirm dialog box when closing the application with multiple tabs open.</comment>
</data>
<data name="Globals_ConfirmOnClose.Header" xml:space="preserve">
<value>닫을 때 경고 표시</value>
<comment>Header for a dropdown controlling when to show a confirmation dialog before closing.</comment>
</data>
<data name="Globals_ConfirmOnClose.HelpText" xml:space="preserve">
<value>탭이나 창을 닫기 전에 확인 대화 상자가 나타나는 시기를 제어합니다. "항상"은 창을 닫을 때 대화 상자를 표시합니다.</value>
<comment>Help text associated with Globals_ConfirmOnClose. "Always" refers to Globals_ConfirmOnCloseAlways.Content.</comment>
</data>
<data name="Globals_ConfirmOnCloseNever.Content" xml:space="preserve">
<value>사용 안 함</value>
<comment>Option associated with Globals_ConfirmOnClose. "Never" means that the system will never display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAlways.Content" xml:space="preserve">
<value>항상</value>
<comment>Option associated with Globals_ConfirmOnClose. "Always" means that the system will always display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAutomatic.Content" xml:space="preserve">
<value>여러 탭 또는 창</value>
<comment>Option associated with Globals_ConfirmOnClose. The system will display a warning when multiple tabs or panes are present.</comment>
</data>
<data name="Globals_InputServiceWarning.Header" xml:space="preserve">
<value>"터치 키보드 및 필기 패널 서비스"를 사용할 수 없는 경우 경고</value>
</data>

View File

@@ -1553,10 +1553,6 @@
<value>Piscar janela</value>
<comment>An option to choose from for the "bell style" setting. When selected, a visual notification is used to notify the user. In this case, the window is flashed.</comment>
</data>
<data name="Profile_BellStyleNotification.Content" xml:space="preserve">
<value>Notificação da área de trabalho</value>
<comment>An option to choose from for the "bell style" setting. When selected, a Windows desktop notification (toast) is sent to notify the user.</comment>
</data>
<data name="ColorScheme_AddNewButton.Text" xml:space="preserve">
<value>Adicionar novo</value>
<comment>Button label that creates a new color scheme.</comment>
@@ -2201,26 +2197,6 @@
<value>Avisar ao fechar mais de uma guia</value>
<comment>Header for a control to toggle whether to show a confirm dialog box when closing the application with multiple tabs open.</comment>
</data>
<data name="Globals_ConfirmOnClose.Header" xml:space="preserve">
<value>Avisar ao fechar</value>
<comment>Header for a dropdown controlling when to show a confirmation dialog before closing.</comment>
</data>
<data name="Globals_ConfirmOnClose.HelpText" xml:space="preserve">
<value>Controla quando uma caixa de diálogo de confirmação aparece antes de fechar guias ou janelas. "Sempre" apresenta a caixa de diálogo ao fechar qualquer painel.</value>
<comment>Help text associated with Globals_ConfirmOnClose. "Always" refers to Globals_ConfirmOnCloseAlways.Content.</comment>
</data>
<data name="Globals_ConfirmOnCloseNever.Content" xml:space="preserve">
<value>Nunca</value>
<comment>Option associated with Globals_ConfirmOnClose. "Never" means that the system will never display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAlways.Content" xml:space="preserve">
<value>Sempre</value>
<comment>Option associated with Globals_ConfirmOnClose. "Always" means that the system will always display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAutomatic.Content" xml:space="preserve">
<value>Múltiplas guias ou painéis</value>
<comment>Option associated with Globals_ConfirmOnClose. The system will display a warning when multiple tabs or panes are present.</comment>
</data>
<data name="Globals_InputServiceWarning.Header" xml:space="preserve">
<value>Avisar quando o "Serviço de Teclado Virtual e Painel de Manuscrito" estiver desabilitado</value>
</data>

View File

@@ -1553,10 +1553,6 @@
<value>₣łāŝћ ẅїňďŏщ !!! </value>
<comment>An option to choose from for the "bell style" setting. When selected, a visual notification is used to notify the user. In this case, the window is flashed.</comment>
</data>
<data name="Profile_BellStyleNotification.Content" xml:space="preserve">
<value>Ðëśкťõρ ʼnσţíƒΐçâτĭõη !!! !!!</value>
<comment>An option to choose from for the "bell style" setting. When selected, a Windows desktop notification (toast) is sent to notify the user.</comment>
</data>
<data name="ColorScheme_AddNewButton.Text" xml:space="preserve">
<value>Äδď ⁿĕш !!</value>
<comment>Button label that creates a new color scheme.</comment>
@@ -2201,26 +2197,6 @@
<value>Ẃářй ẅђëπ ĉľôśĩήĝ mǿѓĕ тĥąπ òπё τάь !!! !!! !!! !</value>
<comment>Header for a control to toggle whether to show a confirm dialog box when closing the application with multiple tabs open.</comment>
</data>
<data name="Globals_ConfirmOnClose.Header" xml:space="preserve">
<value>Ŵǻřπ ωћеŋ ςĺõşϊйĝ !!! !!</value>
<comment>Header for a dropdown controlling when to show a confirmation dialog before closing.</comment>
</data>
<data name="Globals_ConfirmOnClose.HelpText" xml:space="preserve">
<value>Ĉбńţřòłѕ шĥεπ à čоņƒϊřmąτīóп ďíдłбġ ªррéǻŕѕ ъеƒбѓě ςłôśîпğ ţавś оѓ шϊńδǿẅş. "Άŀшãўś" ргзŝêņţš ťнê ðіāľŏĝ ẃћĕй ċℓöѕíñĝ αпŷ рāйε. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!</value>
<comment>Help text associated with Globals_ConfirmOnClose. "Always" refers to Globals_ConfirmOnCloseAlways.Content.</comment>
</data>
<data name="Globals_ConfirmOnCloseNever.Content" xml:space="preserve">
<value>Ņèνέѓ !</value>
<comment>Option associated with Globals_ConfirmOnClose. "Never" means that the system will never display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAlways.Content" xml:space="preserve">
<value>Δŀώǻỳş !</value>
<comment>Option associated with Globals_ConfirmOnClose. "Always" means that the system will always display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAutomatic.Content" xml:space="preserve">
<value>Μύłтîрĺё ťдьś óя φąŋéŝ !!! !!! </value>
<comment>Option associated with Globals_ConfirmOnClose. The system will display a warning when multiple tabs or panes are present.</comment>
</data>
<data name="Globals_InputServiceWarning.Header" xml:space="preserve">
<value>Ẃǻґņ ώћĕπ "Ŧõũčђ Κзγьοдгď ąʼnð Нáлđẅŕīťίńģ Ρàňεℓ Śεŕνîçé" íš đìşāъŀêδ !!! !!! !!! !!! !!! !!! !!</value>
</data>

View File

@@ -1553,10 +1553,6 @@
<value>₣łāŝћ ẅїňďŏщ !!! </value>
<comment>An option to choose from for the "bell style" setting. When selected, a visual notification is used to notify the user. In this case, the window is flashed.</comment>
</data>
<data name="Profile_BellStyleNotification.Content" xml:space="preserve">
<value>Ðëśкťõρ ʼnσţíƒΐçâτĭõη !!! !!!</value>
<comment>An option to choose from for the "bell style" setting. When selected, a Windows desktop notification (toast) is sent to notify the user.</comment>
</data>
<data name="ColorScheme_AddNewButton.Text" xml:space="preserve">
<value>Äδď ⁿĕш !!</value>
<comment>Button label that creates a new color scheme.</comment>
@@ -2201,26 +2197,6 @@
<value>Ẃářй ẅђëπ ĉľôśĩήĝ mǿѓĕ тĥąπ òπё τάь !!! !!! !!! !</value>
<comment>Header for a control to toggle whether to show a confirm dialog box when closing the application with multiple tabs open.</comment>
</data>
<data name="Globals_ConfirmOnClose.Header" xml:space="preserve">
<value>Ŵǻřπ ωћеŋ ςĺõşϊйĝ !!! !!</value>
<comment>Header for a dropdown controlling when to show a confirmation dialog before closing.</comment>
</data>
<data name="Globals_ConfirmOnClose.HelpText" xml:space="preserve">
<value>Ĉбńţřòłѕ шĥεπ à čоņƒϊřmąτīóп ďíдłбġ ªррéǻŕѕ ъеƒбѓě ςłôśîпğ ţавś оѓ шϊńδǿẅş. "Άŀшãўś" ргзŝêņţš ťнê ðіāľŏĝ ẃћĕй ċℓöѕíñĝ αпŷ рāйε. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!</value>
<comment>Help text associated with Globals_ConfirmOnClose. "Always" refers to Globals_ConfirmOnCloseAlways.Content.</comment>
</data>
<data name="Globals_ConfirmOnCloseNever.Content" xml:space="preserve">
<value>Ņèνέѓ !</value>
<comment>Option associated with Globals_ConfirmOnClose. "Never" means that the system will never display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAlways.Content" xml:space="preserve">
<value>Δŀώǻỳş !</value>
<comment>Option associated with Globals_ConfirmOnClose. "Always" means that the system will always display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAutomatic.Content" xml:space="preserve">
<value>Μύłтîрĺё ťдьś óя φąŋéŝ !!! !!! </value>
<comment>Option associated with Globals_ConfirmOnClose. The system will display a warning when multiple tabs or panes are present.</comment>
</data>
<data name="Globals_InputServiceWarning.Header" xml:space="preserve">
<value>Ẃǻґņ ώћĕπ "Ŧõũčђ Κзγьοдгď ąʼnð Нáлđẅŕīťίńģ Ρàňεℓ Śεŕνîçé" íš đìşāъŀêδ !!! !!! !!! !!! !!! !!! !!</value>
</data>

View File

@@ -1553,10 +1553,6 @@
<value>₣łāŝћ ẅїňďŏщ !!! </value>
<comment>An option to choose from for the "bell style" setting. When selected, a visual notification is used to notify the user. In this case, the window is flashed.</comment>
</data>
<data name="Profile_BellStyleNotification.Content" xml:space="preserve">
<value>Ðëśкťõρ ʼnσţíƒΐçâτĭõη !!! !!!</value>
<comment>An option to choose from for the "bell style" setting. When selected, a Windows desktop notification (toast) is sent to notify the user.</comment>
</data>
<data name="ColorScheme_AddNewButton.Text" xml:space="preserve">
<value>Äδď ⁿĕш !!</value>
<comment>Button label that creates a new color scheme.</comment>
@@ -2201,26 +2197,6 @@
<value>Ẃářй ẅђëπ ĉľôśĩήĝ mǿѓĕ тĥąπ òπё τάь !!! !!! !!! !</value>
<comment>Header for a control to toggle whether to show a confirm dialog box when closing the application with multiple tabs open.</comment>
</data>
<data name="Globals_ConfirmOnClose.Header" xml:space="preserve">
<value>Ŵǻřπ ωћеŋ ςĺõşϊйĝ !!! !!</value>
<comment>Header for a dropdown controlling when to show a confirmation dialog before closing.</comment>
</data>
<data name="Globals_ConfirmOnClose.HelpText" xml:space="preserve">
<value>Ĉбńţřòłѕ шĥεπ à čоņƒϊřmąτīóп ďíдłбġ ªррéǻŕѕ ъеƒбѓě ςłôśîпğ ţавś оѓ шϊńδǿẅş. "Άŀшãўś" ргзŝêņţš ťнê ðіāľŏĝ ẃћĕй ċℓöѕíñĝ αпŷ рāйε. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!</value>
<comment>Help text associated with Globals_ConfirmOnClose. "Always" refers to Globals_ConfirmOnCloseAlways.Content.</comment>
</data>
<data name="Globals_ConfirmOnCloseNever.Content" xml:space="preserve">
<value>Ņèνέѓ !</value>
<comment>Option associated with Globals_ConfirmOnClose. "Never" means that the system will never display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAlways.Content" xml:space="preserve">
<value>Δŀώǻỳş !</value>
<comment>Option associated with Globals_ConfirmOnClose. "Always" means that the system will always display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAutomatic.Content" xml:space="preserve">
<value>Μύłтîрĺё ťдьś óя φąŋéŝ !!! !!! </value>
<comment>Option associated with Globals_ConfirmOnClose. The system will display a warning when multiple tabs or panes are present.</comment>
</data>
<data name="Globals_InputServiceWarning.Header" xml:space="preserve">
<value>Ẃǻґņ ώћĕπ "Ŧõũčђ Κзγьοдгď ąʼnð Нáлđẅŕīťίńģ Ρàňεℓ Śεŕνîçé" íš đìşāъŀêδ !!! !!! !!! !!! !!! !!! !!</value>
</data>

View File

@@ -1553,10 +1553,6 @@
<value>Мигающее окно</value>
<comment>An option to choose from for the "bell style" setting. When selected, a visual notification is used to notify the user. In this case, the window is flashed.</comment>
</data>
<data name="Profile_BellStyleNotification.Content" xml:space="preserve">
<value>Уведомления на рабочем столе</value>
<comment>An option to choose from for the "bell style" setting. When selected, a Windows desktop notification (toast) is sent to notify the user.</comment>
</data>
<data name="ColorScheme_AddNewButton.Text" xml:space="preserve">
<value>Добавить новую</value>
<comment>Button label that creates a new color scheme.</comment>
@@ -2201,26 +2197,6 @@
<value>Предупреждать при закрытии нескольких вкладок</value>
<comment>Header for a control to toggle whether to show a confirm dialog box when closing the application with multiple tabs open.</comment>
</data>
<data name="Globals_ConfirmOnClose.Header" xml:space="preserve">
<value>Предупреждать при закрытии</value>
<comment>Header for a dropdown controlling when to show a confirmation dialog before closing.</comment>
</data>
<data name="Globals_ConfirmOnClose.HelpText" xml:space="preserve">
<value>Определяет, когда появляется диалоговое окно подтверждения перед закрытием вкладок или окон. "Всегда" — диалог отображается при закрытии любой панели.</value>
<comment>Help text associated with Globals_ConfirmOnClose. "Always" refers to Globals_ConfirmOnCloseAlways.Content.</comment>
</data>
<data name="Globals_ConfirmOnCloseNever.Content" xml:space="preserve">
<value>Никогда</value>
<comment>Option associated with Globals_ConfirmOnClose. "Never" means that the system will never display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAlways.Content" xml:space="preserve">
<value>Всегда</value>
<comment>Option associated with Globals_ConfirmOnClose. "Always" means that the system will always display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAutomatic.Content" xml:space="preserve">
<value>Несколько вкладок или панелей</value>
<comment>Option associated with Globals_ConfirmOnClose. The system will display a warning when multiple tabs or panes are present.</comment>
</data>
<data name="Globals_InputServiceWarning.Header" xml:space="preserve">
<value>Предупреждать, если параметр "Служба сенсорной клавиатуры и панели рукописного ввода" отключен</value>
</data>

View File

@@ -1553,10 +1553,6 @@
<value>闪烁窗口</value>
<comment>An option to choose from for the "bell style" setting. When selected, a visual notification is used to notify the user. In this case, the window is flashed.</comment>
</data>
<data name="Profile_BellStyleNotification.Content" xml:space="preserve">
<value>桌面通知</value>
<comment>An option to choose from for the "bell style" setting. When selected, a Windows desktop notification (toast) is sent to notify the user.</comment>
</data>
<data name="ColorScheme_AddNewButton.Text" xml:space="preserve">
<value>新增</value>
<comment>Button label that creates a new color scheme.</comment>
@@ -2201,26 +2197,6 @@
<value>关闭多个选项卡时发出警告</value>
<comment>Header for a control to toggle whether to show a confirm dialog box when closing the application with multiple tabs open.</comment>
</data>
<data name="Globals_ConfirmOnClose.Header" xml:space="preserve">
<value>关闭时发出警告</value>
<comment>Header for a dropdown controlling when to show a confirmation dialog before closing.</comment>
</data>
<data name="Globals_ConfirmOnClose.HelpText" xml:space="preserve">
<value>控制在关闭选项卡或窗口之前何时显示确认对话框。“始终”在关闭任何窗格时显示对话框。</value>
<comment>Help text associated with Globals_ConfirmOnClose. "Always" refers to Globals_ConfirmOnCloseAlways.Content.</comment>
</data>
<data name="Globals_ConfirmOnCloseNever.Content" xml:space="preserve">
<value>从不</value>
<comment>Option associated with Globals_ConfirmOnClose. "Never" means that the system will never display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAlways.Content" xml:space="preserve">
<value>始终</value>
<comment>Option associated with Globals_ConfirmOnClose. "Always" means that the system will always display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAutomatic.Content" xml:space="preserve">
<value>多个选项卡或窗格</value>
<comment>Option associated with Globals_ConfirmOnClose. The system will display a warning when multiple tabs or panes are present.</comment>
</data>
<data name="Globals_InputServiceWarning.Header" xml:space="preserve">
<value>禁用“触摸键盘和手写面板服务”时发出警告</value>
</data>

View File

@@ -1553,10 +1553,6 @@
<value>快閃視窗</value>
<comment>An option to choose from for the "bell style" setting. When selected, a visual notification is used to notify the user. In this case, the window is flashed.</comment>
</data>
<data name="Profile_BellStyleNotification.Content" xml:space="preserve">
<value>桌面通知</value>
<comment>An option to choose from for the "bell style" setting. When selected, a Windows desktop notification (toast) is sent to notify the user.</comment>
</data>
<data name="ColorScheme_AddNewButton.Text" xml:space="preserve">
<value>新增</value>
<comment>Button label that creates a new color scheme.</comment>
@@ -2201,26 +2197,6 @@
<value>關閉多個索引標籤時發出警告</value>
<comment>Header for a control to toggle whether to show a confirm dialog box when closing the application with multiple tabs open.</comment>
</data>
<data name="Globals_ConfirmOnClose.Header" xml:space="preserve">
<value>關閉時警告</value>
<comment>Header for a dropdown controlling when to show a confirmation dialog before closing.</comment>
</data>
<data name="Globals_ConfirmOnClose.HelpText" xml:space="preserve">
<value>控制在關閉索引標籤或視窗之前出現確認對話方塊的時間。[永遠] 會在關閉任何窗格時顯示對話方塊。</value>
<comment>Help text associated with Globals_ConfirmOnClose. "Always" refers to Globals_ConfirmOnCloseAlways.Content.</comment>
</data>
<data name="Globals_ConfirmOnCloseNever.Content" xml:space="preserve">
<value>一律不要</value>
<comment>Option associated with Globals_ConfirmOnClose. "Never" means that the system will never display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAlways.Content" xml:space="preserve">
<value>一律</value>
<comment>Option associated with Globals_ConfirmOnClose. "Always" means that the system will always display a warning when closing.</comment>
</data>
<data name="Globals_ConfirmOnCloseAutomatic.Content" xml:space="preserve">
<value>多個索引標籤或窗格</value>
<comment>Option associated with Globals_ConfirmOnClose. The system will display a warning when multiple tabs or panes are present.</comment>
</data>
<data name="Globals_InputServiceWarning.Header" xml:space="preserve">
<value>停用「觸控式鍵盤和手寫面板服務」時發出警告</value>
</data>

View File

@@ -3,7 +3,6 @@
#include "pch.h"
#include "SettingContainer.h"
#include "SettingsExpander.h"
#include "SettingContainer.g.cpp"
using namespace winrt::Windows::UI::Xaml;
@@ -55,7 +54,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
L"FontIconGlyph",
xaml_typename<hstring>(),
xaml_typename<Editor::SettingContainer>(),
PropertyMetadata{ box_value(L""), PropertyChangedCallback{ &SettingContainer::_OnFontIconGlyphChanged } });
PropertyMetadata{ box_value(L"") });
}
if (!_CurrentValueProperty)
{
@@ -135,30 +134,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void SettingContainer::_UpdateHelpText()
{
const auto helpText{ HelpText() };
// Forward HelpText into the SettingsCard / SettingsExpander Description
// slot so it renders through the WCT-ported PART_DescriptionPresenter.
// Setting it to nullptr when empty collapses the description visually so we don't
// reserve vertical space for a blank line.
const auto description{ helpText.empty() ? Windows::Foundation::IInspectable{ nullptr } : box_value(helpText) };
// Get the correct base to apply automation properties to
std::vector<DependencyObject> base;
base.reserve(3);
if (const auto& child{ GetTemplateChild(L"Card") })
{
if (const auto& card{ child.try_as<Editor::SettingsCard>() })
{
card.Description(description);
base.push_back(child);
}
}
base.reserve(2);
if (const auto& child{ GetTemplateChild(L"Expander") })
{
if (const auto& expander{ child.try_as<Editor::SettingsExpander>() })
if (const auto& expander{ child.try_as<Microsoft::UI::Xaml::Controls::Expander>() })
{
expander.Description(description);
base.push_back(child);
}
}
@@ -178,7 +160,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
Automation::AutomationProperties::SetName(obj, _GenerateAccessibleName());
// apply help text as tooltip and full description (automation property)
if (!helpText.empty())
if (const auto& helpText{ HelpText() }; !helpText.empty())
{
Automation::AutomationProperties::SetFullDescription(obj, helpText);
}
@@ -188,6 +170,15 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
Automation::AutomationProperties::SetFullDescription(obj, L"");
}
}
const auto textBlockHidden = HelpText().empty();
if (const auto& child{ GetTemplateChild(L"HelpTextBlock") })
{
if (const auto& textBlock{ child.try_as<Controls::TextBlock>() })
{
textBlock.Visibility(textBlockHidden ? Visibility::Collapsed : Visibility::Visible);
}
}
}
void SettingContainer::OnApplyTemplate()
@@ -232,54 +223,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
_UpdateOverrideSystem();
_UpdateHelpText();
_UpdateHeaderIcon();
}
void SettingContainer::_UpdateHeaderIcon()
{
// Only forward FontIconGlyph into HeaderIcon when the caller actually
// supplied a glyph. Some templates (Warning/Error) already set
// SettingsCard.HeaderIcon in XAML to a stacked severity glyph; if we
// unconditionally wrote nullptr here we'd clobber that XAML default for
// every callsite that doesn't set FontIconGlyph.
const auto glyph{ FontIconGlyph() };
if (glyph.empty())
{
return;
}
Controls::FontIcon fi;
fi.Glyph(glyph);
const Controls::IconElement icon{ fi };
if (const auto& cardChild{ GetTemplateChild(L"Card") })
{
if (const auto& card{ cardChild.try_as<Editor::SettingsCard>() })
{
card.HeaderIcon(icon);
return;
}
}
if (const auto& expanderChild{ GetTemplateChild(L"Expander") })
{
if (const auto& expander{ expanderChild.try_as<Editor::SettingsExpander>() })
{
expander.HeaderIcon(icon);
}
}
}
void SettingContainer::_OnFontIconGlyphChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*args*/)
{
const auto& obj{ d.try_as<Editor::SettingContainer>() };
get_self<SettingContainer>(obj)->_UpdateHeaderIcon();
}
void SettingContainer::SetExpanded(bool expanded)
{
if (const auto& child{ GetTemplateChild(L"Expander") })
{
if (const auto& expander{ child.try_as<Editor::SettingsExpander>() })
if (const auto& expander{ child.try_as<Microsoft::UI::Xaml::Controls::Expander>() })
{
expander.IsExpanded(expanded);
}
@@ -321,7 +271,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
if (const auto& child{ GetTemplateChild(L"Expander") })
{
if (const auto& expander{ child.try_as<Editor::SettingsExpander>() })
if (const auto& expander{ child.try_as<Microsoft::UI::Xaml::Controls::Expander>() })
{
Automation::AutomationProperties::SetName(expander, _GenerateAccessibleName());
}

View File

@@ -48,13 +48,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
static void _OnCurrentValueChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
static void _OnHasSettingValueChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
static void _OnHelpTextChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
static void _OnFontIconGlyphChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
static hstring _GenerateOverrideMessage(const IInspectable& settingOrigin);
hstring _GenerateAccessibleName();
void _UpdateOverrideSystem();
void _UpdateHelpText();
void _UpdateCurrentValueAutoProp();
void _UpdateHeaderIcon();
};
}

View File

@@ -18,6 +18,8 @@
</Style>
<SolidColorBrush x:Key="SubgroupHeaderBrush"
Color="{StaticResource TextFillColorSecondary}" />
<StaticResource x:Key="ExpanderHeaderBorderBrush"
ResourceKey="CardStrokeColorDefaultBrush" />
<StaticResource x:Key="SettingContainerErrorSeverityBackgroundBrush"
ResourceKey="SystemFillColorCriticalBackgroundBrush" />
@@ -29,14 +31,28 @@
<StaticResource x:Key="SettingContainerWarningSeverityIconBackground"
ResourceKey="SystemFillColorCautionBrush" />
<StaticResource x:Key="SettingContainerErrorSeverityIconForeground"
ResourceKey="TextFillColorInverseBrush" />
<StaticResource x:Key="SettingContainerWarningSeverityIconForeground"
ResourceKey="TextFillColorInverseBrush" />
<StaticResource x:Key="SettingContainerTitleForeground"
ResourceKey="TextFillColorPrimaryBrush" />
<StaticResource x:Key="SettingContainerMessageForeground"
ResourceKey="TextFillColorPrimaryBrush" />
<StaticResource x:Key="SettingContainerResetButtonIconForeground"
ResourceKey="SystemAccentColorDark2" />
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast">
<Style x:Key="SecondaryTextBlockStyle"
TargetType="TextBlock" />
<!-- Do not mess with the foreground color for High Contrast. Let it ride as is. -->
<SolidColorBrush x:Key="SubgroupHeaderBrush"
Color="{ThemeResource SystemColorWindowTextColor}" />
<StaticResource x:Key="ExpanderHeaderBorderBrush"
ResourceKey="SystemColorButtonTextColorBrush" />
<StaticResource x:Key="SettingContainerErrorSeverityBackgroundBrush"
ResourceKey="SystemColorWindowColorBrush" />
@@ -48,6 +64,16 @@
<StaticResource x:Key="SettingContainerWarningSeverityIconBackground"
ResourceKey="SystemColorHighlightColorBrush" />
<StaticResource x:Key="SettingContainerErrorSeverityIconForeground"
ResourceKey="SystemColorHighlightTextColorBrush" />
<StaticResource x:Key="SettingContainerWarningSeverityIconForeground"
ResourceKey="SystemColorHighlightTextColorBrush" />
<StaticResource x:Key="SettingContainerTitleForeground"
ResourceKey="SystemColorWindowTextColorBrush" />
<StaticResource x:Key="SettingContainerMessageForeground"
ResourceKey="SystemColorWindowTextColorBrush" />
<StaticResource x:Key="SettingContainerResetButtonIconForeground"
ResourceKey="SystemAccentColorLight1" />
</ResourceDictionary>
@@ -58,6 +84,8 @@
</Style>
<SolidColorBrush x:Key="SubgroupHeaderBrush"
Color="{StaticResource TextFillColorSecondary}" />
<StaticResource x:Key="ExpanderHeaderBorderBrush"
ResourceKey="CardStrokeColorDefaultBrush" />
<StaticResource x:Key="SettingContainerErrorSeverityBackgroundBrush"
ResourceKey="SystemFillColorCriticalBackgroundBrush" />
@@ -69,16 +97,36 @@
<StaticResource x:Key="SettingContainerWarningSeverityIconBackground"
ResourceKey="SystemFillColorCautionBrush" />
<StaticResource x:Key="SettingContainerErrorSeverityIconForeground"
ResourceKey="TextFillColorInverseBrush" />
<StaticResource x:Key="SettingContainerWarningSeverityIconForeground"
ResourceKey="TextFillColorInverseBrush" />
<StaticResource x:Key="SettingContainerTitleForeground"
ResourceKey="TextFillColorPrimaryBrush" />
<StaticResource x:Key="SettingContainerMessageForeground"
ResourceKey="TextFillColorPrimaryBrush" />
<StaticResource x:Key="SettingContainerResetButtonIconForeground"
ResourceKey="SystemAccentColorLight2" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
<FontWeight x:Key="SettingContainerTitleFontWeight">SemiBold</FontWeight>
<x:String x:Key="SettingContainerIconBackgroundGlyph">&#xF136;</x:String>
<x:String x:Key="SettingContainerErrorIconGlyph">&#xF13D;</x:String>
<x:String x:Key="SettingContainerWarningIconGlyph">&#xF13C;</x:String>
<Thickness x:Key="SettingContainerIconMargin">0,4,8,4</Thickness>
<x:Double x:Key="SettingContainerIconFontSize">16</x:Double>
<Style x:Key="StackPanelInExpanderStyle"
TargetType="StackPanel">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Padding" Value="0,12,0,12" />
</Style>
<Style x:Key="SettingContainerResetButtonStyle"
BasedOn="{StaticResource DefaultButtonStyle}"
TargetType="Button">
@@ -97,6 +145,18 @@
<Setter Property="FontFamily" Value="{ThemeResource SymbolThemeFontFamily}" />
</Style>
<Style x:Key="NonExpanderGrid"
TargetType="Grid">
<Setter Property="Background" Value="{ThemeResource ExpanderHeaderBackground}" />
<Setter Property="MinWidth" Value="{ThemeResource FlyoutThemeMinWidth}" />
<Setter Property="MinHeight" Value="64" />
<Setter Property="BorderThickness" Value="{ThemeResource ExpanderHeaderBorderThickness}" />
<Setter Property="BorderBrush" Value="{ThemeResource ExpanderHeaderBorderBrush}" />
<Setter Property="Padding" Value="16,0,8,0" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
</Style>
<Style x:Key="SettingsPageItemHeaderStyle"
BasedOn="{StaticResource BodyTextBlockStyle}"
TargetType="TextBlock">
@@ -118,7 +178,7 @@
BasedOn="{StaticResource SettingsPageItemDescriptionStyle}"
TargetType="TextBlock">
<Setter Property="MaxWidth" Value="248" />
<Setter Property="Margin" Value="0" />
<Setter Property="Margin" Value="0,0,-16,0" />
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets" />
@@ -129,9 +189,7 @@
Text="{Binding}" />
</DataTemplate>
<local:StringDefaultTemplateSelector x:Key="ExpanderPreviewTemplateSelector"
StringTemplate="{StaticResource ExpanderSettingContainerStringPreviewTemplate}" />
<!-- A setting container for a setting that has no additional options -->
<Style TargetType="local:SettingContainer">
<Setter Property="Margin" Value="0,4,0,0" />
<Setter Property="IsTabStop" Value="False" />
@@ -139,64 +197,274 @@
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:SettingContainer">
<local:SettingsCard x:Name="Card"
Content="{TemplateBinding Content}">
<local:SettingsCard.Header>
<StackPanel VerticalAlignment="Center"
Orientation="Horizontal">
<ContentControl Content="{TemplateBinding Header}"
IsTabStop="False" />
<Grid AutomationProperties.Name="{TemplateBinding Header}"
Style="{StaticResource NonExpanderGrid}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0"
Style="{StaticResource StackPanelInExpanderStyle}">
<StackPanel Orientation="Horizontal">
<TextBlock Style="{StaticResource SettingsPageItemHeaderStyle}"
Text="{TemplateBinding Header}" />
<Button x:Name="ResetButton"
Style="{StaticResource SettingContainerResetButtonStyle}">
<FontIcon Glyph="&#xE845;"
Style="{StaticResource SettingContainerFontIconStyle}" />
</Button>
</StackPanel>
</local:SettingsCard.Header>
</local:SettingsCard>
<TextBlock x:Name="HelpTextBlock"
Style="{StaticResource SettingsPageItemDescriptionStyle}"
Text="{TemplateBinding HelpText}" />
</StackPanel>
<ContentPresenter Grid.Column="1"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Content="{TemplateBinding Content}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ExpanderSettingContainerStyle"
<!-- A basic setting container displaying immutable text as content -->
<Style x:Key="SettingContainerWithTextContent"
TargetType="local:SettingContainer">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:SettingContainer">
<Grid AutomationProperties.Name="{TemplateBinding Header}"
Style="{StaticResource NonExpanderGrid}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0"
Style="{StaticResource StackPanelInExpanderStyle}">
<StackPanel Orientation="Horizontal">
<TextBlock Style="{StaticResource SettingsPageItemHeaderStyle}"
Text="{TemplateBinding Header}" />
<Button x:Name="ResetButton"
Style="{StaticResource SettingContainerResetButtonStyle}">
<FontIcon Glyph="&#xE845;"
Style="{StaticResource SettingContainerFontIconStyle}" />
</Button>
</StackPanel>
<TextBlock x:Name="HelpTextBlock"
Style="{StaticResource SettingsPageItemDescriptionStyle}"
Text="{TemplateBinding HelpText}" />
</StackPanel>
<TextBlock Grid.Column="1"
Margin="0,0,8,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Style="{ThemeResource SecondaryTextBlockStyle}"
Text="{TemplateBinding Content}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--
A setting container for a setting that has no additional options.
Includes space for an icon on the left side of the header.
XAML applies the margin/padding of the icon regardless of its
existence (which caused inconsistent padding). It's easier to just create
another style and move on.
-->
<Style x:Key="SettingContainerWithIcon"
TargetType="local:SettingContainer">
<Setter Property="Margin" Value="0,4,0,0" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="MaxWidth" Value="1000" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:SettingContainer">
<Grid AutomationProperties.Name="{TemplateBinding Header}"
Style="{StaticResource NonExpanderGrid}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<FontIcon Grid.Column="0"
Glyph="{TemplateBinding FontIconGlyph}" />
<StackPanel Grid.Column="1"
Padding="14,12,0,12"
Style="{StaticResource StackPanelInExpanderStyle}">
<StackPanel Orientation="Horizontal">
<TextBlock Style="{StaticResource SettingsPageItemHeaderStyle}"
Text="{TemplateBinding Header}" />
<Button x:Name="ResetButton"
Style="{StaticResource SettingContainerResetButtonStyle}">
<FontIcon Glyph="&#xE845;"
Style="{StaticResource SettingContainerFontIconStyle}" />
</Button>
</StackPanel>
<TextBlock x:Name="HelpTextBlock"
Style="{StaticResource SettingsPageItemDescriptionStyle}"
Text="{TemplateBinding HelpText}" />
</StackPanel>
<ContentPresenter Grid.Column="2"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Content="{TemplateBinding Content}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- A setting container which can expand -->
<Style x:Key="ExpanderSettingContainerStyle"
TargetType="local:SettingContainer">
<Setter Property="MaxWidth" Value="1000" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="AutomationProperties.AccessibilityView" Value="Raw" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:SettingContainer">
<local:SettingsExpander x:Name="Expander"
IsExpanded="{TemplateBinding StartExpanded}">
<local:SettingsExpander.Header>
<StackPanel VerticalAlignment="Center"
Orientation="Horizontal">
<ContentControl Content="{TemplateBinding Header}"
IsTabStop="False" />
<Button x:Name="ResetButton"
Style="{StaticResource SettingContainerResetButtonStyle}">
<FontIcon Glyph="&#xE845;"
Style="{StaticResource SettingContainerFontIconStyle}" />
</Button>
</StackPanel>
</local:SettingsExpander.Header>
<local:SettingsExpander.Content>
<ContentControl MaxWidth="248"
HorizontalAlignment="Right"
VerticalAlignment="Center"
HorizontalContentAlignment="Right"
Content="{TemplateBinding CurrentValue}"
ContentTemplate="{TemplateBinding CurrentValueTemplate}"
ContentTemplateSelector="{StaticResource ExpanderPreviewTemplateSelector}"
IsTabStop="False" />
</local:SettingsExpander.Content>
<local:SettingsExpander.ItemsHeader>
<ContentPresenter Padding="16,12,16,16"
Content="{TemplateBinding Content}" />
</local:SettingsExpander.ItemsHeader>
</local:SettingsExpander>
<muxc:Expander x:Name="Expander"
Margin="0,4,0,0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
Content="{TemplateBinding Content}"
IsExpanded="{TemplateBinding StartExpanded}">
<muxc:Expander.Header>
<Grid MinHeight="64">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0"
Style="{StaticResource StackPanelInExpanderStyle}">
<StackPanel Orientation="Horizontal">
<ContentPresenter Content="{TemplateBinding Header}" />
<Button x:Name="ResetButton"
Style="{StaticResource SettingContainerResetButtonStyle}">
<FontIcon Glyph="&#xE845;"
Style="{StaticResource SettingContainerFontIconStyle}" />
</Button>
</StackPanel>
<TextBlock x:Name="HelpTextBlock"
Style="{StaticResource SettingsPageItemDescriptionStyle}"
Text="{TemplateBinding HelpText}" />
</StackPanel>
<ContentPresenter Grid.Column="1"
Content="{TemplateBinding CurrentValue}"
ContentTemplate="{StaticResource ExpanderSettingContainerStringPreviewTemplate}" />
</Grid>
</muxc:Expander.Header>
</muxc:Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--
A setting container which can expand. Includes space for an icon on the left side of the header.
XAML applies the margin/padding of the icon regardless of its
existence (which caused inconsistent padding). It's easier to just create
another style and move on.
-->
<Style x:Key="ExpanderSettingContainerStyleWithIcon"
TargetType="local:SettingContainer">
<Setter Property="MaxWidth" Value="1000" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="AutomationProperties.AccessibilityView" Value="Raw" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:SettingContainer">
<muxc:Expander x:Name="Expander"
Margin="0,4,0,0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
Content="{TemplateBinding Content}"
IsExpanded="{TemplateBinding StartExpanded}">
<muxc:Expander.Header>
<Grid MinHeight="64">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<FontIcon Grid.Column="0"
Glyph="{TemplateBinding FontIconGlyph}" />
<StackPanel Grid.Column="1"
Padding="14,12,0,12"
Style="{StaticResource StackPanelInExpanderStyle}">
<StackPanel Orientation="Horizontal">
<TextBlock Style="{StaticResource SettingsPageItemHeaderStyle}"
Text="{TemplateBinding Header}" />
<Button x:Name="ResetButton"
Style="{StaticResource SettingContainerResetButtonStyle}">
<FontIcon Glyph="&#xE845;"
Style="{StaticResource SettingContainerFontIconStyle}" />
</Button>
</StackPanel>
<TextBlock x:Name="HelpTextBlock"
Style="{StaticResource SettingsPageItemDescriptionStyle}"
Text="{TemplateBinding HelpText}" />
</StackPanel>
<ContentPresenter Grid.Column="2"
Content="{TemplateBinding CurrentValue}"
ContentTemplate="{StaticResource ExpanderSettingContainerStringPreviewTemplate}" />
</Grid>
</muxc:Expander.Header>
</muxc:Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- A setting container which can expand. Supports data template override for preview -->
<Style x:Key="ExpanderSettingContainerStyleWithComplexPreview"
TargetType="local:SettingContainer">
<Setter Property="MaxWidth" Value="1000" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="AutomationProperties.AccessibilityView" Value="Raw" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:SettingContainer">
<muxc:Expander x:Name="Expander"
Margin="0,4,0,0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
Content="{TemplateBinding Content}"
IsExpanded="{TemplateBinding StartExpanded}">
<muxc:Expander.Header>
<Grid MinHeight="64">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0"
Style="{StaticResource StackPanelInExpanderStyle}">
<StackPanel Orientation="Horizontal">
<TextBlock Style="{StaticResource SettingsPageItemHeaderStyle}"
Text="{TemplateBinding Header}" />
<Button x:Name="ResetButton"
Style="{StaticResource SettingContainerResetButtonStyle}">
<FontIcon Glyph="&#xE845;"
Style="{StaticResource SettingContainerFontIconStyle}" />
</Button>
</StackPanel>
<TextBlock x:Name="HelpTextBlock"
Style="{StaticResource SettingsPageItemDescriptionStyle}"
Text="{TemplateBinding HelpText}" />
</StackPanel>
<ContentPresenter Grid.Column="1"
MaxWidth="248"
Margin="0,0,-16,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Content="{TemplateBinding CurrentValue}"
ContentTemplate="{TemplateBinding CurrentValueTemplate}" />
</Grid>
</muxc:Expander.Header>
</muxc:Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
@@ -211,19 +479,47 @@
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:SettingContainer">
<local:SettingsCard x:Name="Card"
Background="{ThemeResource SettingContainerWarningSeverityBackgroundBrush}">
<local:SettingsCard.Header>
<ContentControl Content="{TemplateBinding Header}"
IsTabStop="False" />
</local:SettingsCard.Header>
<local:SettingsCard.HeaderIcon>
<FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="{StaticResource SettingContainerIconFontSize}"
Foreground="{ThemeResource SettingContainerWarningSeverityIconBackground}"
Glyph="{StaticResource SettingContainerWarningIconGlyph}" />
</local:SettingsCard.HeaderIcon>
</local:SettingsCard>
<Grid AutomationProperties.Name="{TemplateBinding Header}"
Background="{ThemeResource SettingContainerWarningSeverityBackgroundBrush}"
Style="{StaticResource NonExpanderGrid}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Style="{StaticResource StackPanelInExpanderStyle}">
<StackPanel Orientation="Horizontal">
<Grid>
<TextBlock x:Name="IconBackground"
Grid.Column="0"
Margin="{StaticResource SettingContainerIconMargin}"
VerticalAlignment="Center"
AutomationProperties.AccessibilityView="Raw"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="{StaticResource SettingContainerIconFontSize}"
Foreground="{ThemeResource SettingContainerWarningSeverityIconBackground}"
Text="{StaticResource SettingContainerIconBackgroundGlyph}" />
<TextBlock x:Name="StandardIcon"
Grid.Column="0"
Margin="{StaticResource SettingContainerIconMargin}"
VerticalAlignment="Center"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="{StaticResource SettingContainerIconFontSize}"
Foreground="{ThemeResource SettingContainerWarningSeverityIconForeground}"
Text="{StaticResource SettingContainerWarningIconGlyph}" />
</Grid>
<TextBlock VerticalAlignment="Center"
FontWeight="{StaticResource SettingContainerTitleFontWeight}"
Foreground="{ThemeResource SettingContainerTitleForeground}"
Style="{StaticResource SettingsPageItemHeaderStyle}"
Text="{TemplateBinding Header}" />
</StackPanel>
<TextBlock x:Name="HelpTextBlock"
Foreground="{ThemeResource SettingContainerMessageForeground}"
Style="{StaticResource SettingsPageItemDescriptionStyle}"
Text="{TemplateBinding HelpText}" />
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
@@ -238,19 +534,47 @@
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:SettingContainer">
<local:SettingsCard x:Name="Card"
Background="{ThemeResource SettingContainerErrorSeverityBackgroundBrush}">
<local:SettingsCard.Header>
<ContentControl Content="{TemplateBinding Header}"
IsTabStop="False" />
</local:SettingsCard.Header>
<local:SettingsCard.HeaderIcon>
<FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="{StaticResource SettingContainerIconFontSize}"
Foreground="{ThemeResource SettingContainerErrorSeverityIconBackground}"
Glyph="{StaticResource SettingContainerErrorIconGlyph}" />
</local:SettingsCard.HeaderIcon>
</local:SettingsCard>
<Grid AutomationProperties.Name="{TemplateBinding Header}"
Background="{ThemeResource SettingContainerErrorSeverityBackgroundBrush}"
Style="{StaticResource NonExpanderGrid}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Style="{StaticResource StackPanelInExpanderStyle}">
<StackPanel Orientation="Horizontal">
<Grid>
<TextBlock x:Name="IconBackground"
Grid.Column="0"
Margin="{StaticResource SettingContainerIconMargin}"
VerticalAlignment="Center"
AutomationProperties.AccessibilityView="Raw"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="{StaticResource SettingContainerIconFontSize}"
Foreground="{ThemeResource SettingContainerErrorSeverityIconBackground}"
Text="{StaticResource SettingContainerIconBackgroundGlyph}" />
<TextBlock x:Name="StandardIcon"
Grid.Column="0"
Margin="{StaticResource SettingContainerIconMargin}"
VerticalAlignment="Center"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="{StaticResource SettingContainerIconFontSize}"
Foreground="{ThemeResource SettingContainerErrorSeverityIconForeground}"
Text="{StaticResource SettingContainerErrorIconGlyph}" />
</Grid>
<TextBlock VerticalAlignment="Center"
FontWeight="{StaticResource SettingContainerTitleFontWeight}"
Foreground="{ThemeResource SettingContainerTitleForeground}"
Style="{StaticResource SettingsPageItemHeaderStyle}"
Text="{TemplateBinding Header}" />
</StackPanel>
<TextBlock x:Name="HelpTextBlock"
Foreground="{ThemeResource SettingContainerMessageForeground}"
Style="{StaticResource SettingsPageItemDescriptionStyle}"
Text="{TemplateBinding HelpText}" />
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>

View File

@@ -1,670 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "SettingsCard.h"
#include "SettingsCard.g.cpp"
#include "SettingsCardAutomationPeer.g.cpp"
#include "StyleExtensions.h"
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::System;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Xaml::Automation;
using namespace winrt::Windows::UI::Xaml::Automation::Peers;
using namespace winrt::Windows::UI::Xaml::Controls;
using namespace winrt::Windows::UI::Xaml::Controls::Primitives;
using namespace winrt::Windows::UI::Xaml::Input;
using namespace winrt::Windows::UI::Xaml::Media;
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
DependencyProperty SettingsCard::_HeaderProperty{ nullptr };
DependencyProperty SettingsCard::_DescriptionProperty{ nullptr };
DependencyProperty SettingsCard::_HeaderIconProperty{ nullptr };
DependencyProperty SettingsCard::_ActionIconProperty{ nullptr };
DependencyProperty SettingsCard::_ActionIconToolTipProperty{ nullptr };
DependencyProperty SettingsCard::_IsClickEnabledProperty{ nullptr };
DependencyProperty SettingsCard::_IsActionIconVisibleProperty{ nullptr };
DependencyProperty SettingsCard::_ContentAlignmentProperty{ nullptr };
static constexpr std::wstring_view NormalState{ L"Normal" };
static constexpr std::wstring_view PointerOverState{ L"PointerOver" };
static constexpr std::wstring_view PressedState{ L"Pressed" };
static constexpr std::wstring_view DisabledState{ L"Disabled" };
static constexpr std::wstring_view BitmapHeaderIconEnabledState{ L"BitmapHeaderIconEnabled" };
static constexpr std::wstring_view BitmapHeaderIconDisabledState{ L"BitmapHeaderIconDisabled" };
static constexpr std::wstring_view RightState{ L"Right" };
static constexpr std::wstring_view LeftState{ L"Left" };
static constexpr std::wstring_view VerticalState{ L"Vertical" };
static constexpr std::wstring_view NoContentSpacingState{ L"NoContentSpacing" };
static constexpr std::wstring_view ContentSpacingState{ L"ContentSpacing" };
static constexpr std::wstring_view ContentAlignmentStatesGroup{ L"ContentAlignmentStates" };
static constexpr std::wstring_view ActionIconPresenterHolder{ L"PART_ActionIconPresenterHolder" };
static constexpr std::wstring_view HeaderPresenter{ L"PART_HeaderPresenter" };
static constexpr std::wstring_view DescriptionPresenter{ L"PART_DescriptionPresenter" };
static constexpr std::wstring_view HeaderIconPresenterHolder{ L"PART_HeaderIconPresenterHolder" };
static constexpr std::wstring_view ContentPresenterPart{ L"PART_ContentPresenter" };
static constexpr std::wstring_view RootGridPart{ L"PART_RootGrid" };
static constexpr double SettingsCardVerticalHeaderContentSpacing{ 8.0 };
// Returns true if the given object is null, or is a string that is empty.
// Non-string non-null objects (e.g. a TextBlock) are considered "non-empty".
static bool _isNullOrEmpty(const winrt::Windows::Foundation::IInspectable& obj)
{
if (!obj)
{
return true;
}
if (const auto pv{ obj.try_as<IPropertyValue>() }; pv && pv.Type() == PropertyType::String)
{
return unbox_value_or<hstring>(obj, hstring{}).empty();
}
return false;
}
SettingsCard::SettingsCard()
{
_InitializeProperties();
}
void SettingsCard::_InitializeProperties()
{
if (!_HeaderProperty)
{
_HeaderProperty = DependencyProperty::Register(
L"Header",
xaml_typename<IInspectable>(),
xaml_typename<Editor::SettingsCard>(),
PropertyMetadata{ nullptr, PropertyChangedCallback{ &SettingsCard::_OnHeaderChanged } });
}
if (!_DescriptionProperty)
{
_DescriptionProperty = DependencyProperty::Register(
L"Description",
xaml_typename<IInspectable>(),
xaml_typename<Editor::SettingsCard>(),
PropertyMetadata{ nullptr, PropertyChangedCallback{ &SettingsCard::_OnDescriptionChanged } });
}
if (!_HeaderIconProperty)
{
_HeaderIconProperty = DependencyProperty::Register(
L"HeaderIcon",
xaml_typename<IconElement>(),
xaml_typename<Editor::SettingsCard>(),
PropertyMetadata{ nullptr, PropertyChangedCallback{ &SettingsCard::_OnHeaderIconChanged } });
}
if (!_ActionIconProperty)
{
// No metadata default value — a fresh FontIcon is allocated per
// card in OnApplyTemplate when the user hasn't set ActionIcon
// explicitly. We cannot use a default FontIcon here because
// UIElements have a single-parent constraint (one instance can't
// be shared across cards) and a default string was rendering
// through ContentPresenter -> TextBlock, whose line-height
// padding made the Viewbox-scaled glyph visibly smaller than
// WCT's SymbolIcon default.
_ActionIconProperty = DependencyProperty::Register(
L"ActionIcon",
xaml_typename<IInspectable>(),
xaml_typename<Editor::SettingsCard>(),
PropertyMetadata{ nullptr });
}
if (!_ActionIconToolTipProperty)
{
_ActionIconToolTipProperty = DependencyProperty::Register(
L"ActionIconToolTip",
xaml_typename<hstring>(),
xaml_typename<Editor::SettingsCard>(),
PropertyMetadata{ box_value(hstring{}) });
}
if (!_IsClickEnabledProperty)
{
_IsClickEnabledProperty = DependencyProperty::Register(
L"IsClickEnabled",
xaml_typename<bool>(),
xaml_typename<Editor::SettingsCard>(),
PropertyMetadata{ box_value(false), PropertyChangedCallback{ &SettingsCard::_OnIsClickEnabledChanged } });
}
if (!_IsActionIconVisibleProperty)
{
_IsActionIconVisibleProperty = DependencyProperty::Register(
L"IsActionIconVisible",
xaml_typename<bool>(),
xaml_typename<Editor::SettingsCard>(),
PropertyMetadata{ box_value(true), PropertyChangedCallback{ &SettingsCard::_OnIsActionIconVisibleChanged } });
}
if (!_ContentAlignmentProperty)
{
_ContentAlignmentProperty = DependencyProperty::Register(
L"ContentAlignment",
xaml_typename<Editor::SettingsCardContentAlignment>(),
xaml_typename<Editor::SettingsCard>(),
PropertyMetadata{ box_value(Editor::SettingsCardContentAlignment::Right), PropertyChangedCallback{ &SettingsCard::_OnContentAlignmentChanged } });
}
}
AutomationPeer SettingsCard::OnCreateAutomationPeer()
{
return winrt::make<implementation::SettingsCardAutomationPeer>(*this);
}
// Pointer overrides: gate the ButtonBase click pipeline on IsClickEnabled.
// When IsClickEnabled=false, we do NOT call the base method, so the event
// is left unhandled and bubbles up the visual tree. This is what lets the
// SettingsExpander header (a ToggleButton hosting a SettingsCard with
// IsClickEnabled=false) toggle on a click anywhere across the header row,
// not just on the chevron. Mirrors the Community Toolkit's SettingsCard.cs.
void SettingsCard::OnPointerPressed(const winrt::Windows::UI::Xaml::Input::PointerRoutedEventArgs& e)
{
if (IsClickEnabled())
{
base_type::OnPointerPressed(e);
_GoToCommonState(PressedState, true);
}
}
void SettingsCard::OnPointerReleased(const winrt::Windows::UI::Xaml::Input::PointerRoutedEventArgs& e)
{
if (IsClickEnabled())
{
base_type::OnPointerReleased(e);
_GoToCommonState(NormalState, true);
}
}
void SettingsCard::OnApplyTemplate()
{
// Match WCT's SettingsCard.OnApplyTemplate() which calls base first so the
// template parts are fully wired up before any of our post-template setup
// (visibility, visual states, click interaction) runs.
base_type::OnApplyTemplate();
// Inject the shared implicit ToggleSwitch / Slider / ComboBox / TextBox
// dictionary so child controls in our Content slot get the Windows 11
// settings-page defaults without an explicit Style attribute. Bypasses
// the WCT Setter.Value-with-inline-ResourceDictionary pattern, which
// crashes WinUI 2 XAML load in this codebase.
StyleExtensions::EnsureImplicitStylesMergedInto(*this);
// Drop any handlers from a previous template.
_isEnabledChangedRevoker.revoke();
_contentAlignmentStatesChangedRevoker.revoke();
_DisableButtonInteraction();
if (_contentChangedToken != 0)
{
UnregisterPropertyChangedCallback(ContentControl::ContentProperty(), _contentChangedToken);
_contentChangedToken = 0;
}
_UpdateActionIconVisibility();
_UpdateHeaderVisibility();
_UpdateDescriptionVisibility();
_UpdateHeaderIconVisibility();
// Initial visual states.
_CheckInitialVisualState();
_CheckHeaderIconState();
_SetAccessibleContentName();
// Watch for Content changing later (we may need to refresh the AutomationProperties.Name on it).
_contentChangedToken = RegisterPropertyChangedCallback(ContentControl::ContentProperty(), [weakThis = get_weak()](auto&&, auto&&) {
if (const auto strongThis = weakThis.get())
{
strongThis->_SetAccessibleContentName();
}
});
// Apply click-interaction state.
if (IsClickEnabled())
{
_EnableButtonInteraction();
}
_isEnabledChangedRevoker = IsEnabledChanged(winrt::auto_revoke, [weakThis = get_weak()](auto&&, auto&&) {
if (const auto strongThis = weakThis.get())
{
strongThis->_GoToCommonState(strongThis->IsEnabled() ? NormalState : DisabledState, true);
strongThis->_CheckHeaderIconState();
}
});
}
void SettingsCard::_CheckInitialVisualState()
{
VisualStateManager::GoToState(*this, IsEnabled() ? hstring{ NormalState } : hstring{ DisabledState }, true);
_UpdateContentAlignmentState();
// Subscribe to ContentAlignmentStates so we can drive ContentSpacingStates
// whenever the alignment shifts to a stacked layout (Vertical, RightWrapped*).
if (const auto child{ GetTemplateChild(hstring{ ContentAlignmentStatesGroup }) })
{
if (const auto group{ child.try_as<VisualStateGroup>() })
{
_CheckVerticalSpacingState(group.CurrentState());
_contentAlignmentStatesChangedRevoker = group.CurrentStateChanged(winrt::auto_revoke, [weakThis = get_weak()](auto&&, const VisualStateChangedEventArgs& args) {
if (const auto strongThis = weakThis.get())
{
strongThis->_CheckVerticalSpacingState(args.NewState());
}
});
}
}
}
void SettingsCard::_CheckHeaderIconState()
{
// The Disabled common state recolors text/glyph foregrounds via the brush, but a
// BitmapIcon is an image and won't pick up the disabled brush. Lower its opacity
// instead, via the BitmapHeaderIconStates group. Mirrors the toolkit's
// SettingsCard.cs::CheckHeaderIconState.
if (HeaderIcon().try_as<BitmapIcon>())
{
VisualStateManager::GoToState(*this,
hstring{ IsEnabled() ? BitmapHeaderIconEnabledState : BitmapHeaderIconDisabledState },
true);
}
else
{
// Reset to the enabled state when a non-bitmap icon (or none) is present so the
// opacity setter doesn't stick around from a previous bitmap icon.
VisualStateManager::GoToState(*this, hstring{ BitmapHeaderIconEnabledState }, true);
}
}
void SettingsCard::_CheckVerticalSpacingState(const VisualState& state)
{
// Add row spacing whenever the content sits below the header (Vertical or RightWrapped*)
// AND there's both Content and (Header or Description) to space apart.
//
// For the Vertical case we read ContentAlignment() directly rather than
// state.Name(): our Left/Vertical visual states are empty placeholders
// (the actual layout work happens in _UpdateContentAlignmentState via
// direct C++ property writes) and an empty <VisualState> may not have
// its name register as CurrentState when GoToState fires in WinUI 2 —
// leaving stackedLayout incorrectly false. RightWrapped*, in contrast,
// are size-triggered visual states with real setters and ControlSizeTrigger,
// so their CurrentState is reliably observed.
const auto stateName{ state ? state.Name() : hstring{} };
const bool stackedLayout =
ContentAlignment() == Editor::SettingsCardContentAlignment::Vertical ||
stateName == L"RightWrapped" ||
stateName == L"RightWrappedNoIcon";
const bool hasContent{ static_cast<bool>(Content()) };
const bool hasHeaderOrDescription = !_isNullOrEmpty(Header()) || !_isNullOrEmpty(Description());
const bool shouldSpace = stackedLayout && hasContent && hasHeaderOrDescription;
VisualStateManager::GoToState(*this,
hstring{ shouldSpace ? ContentSpacingState : NoContentSpacingState },
true);
// Belt-and-suspenders for the WinUI 2 quirk: VisualState.Setters activated
// by C++ GoToState don't reliably engage. The ContentSpacing setter
// targets PART_RootGrid.RowSpacing; set it directly here as well so the
// Vertical / RightWrapped stacked-layout cards actually get the breathing
// room between header and content that WCT shows.
if (const auto child{ GetTemplateChild(hstring{ RootGridPart }) })
{
if (const auto rootGrid{ child.try_as<Grid>() })
{
rootGrid.RowSpacing(shouldSpace ? SettingsCardVerticalHeaderContentSpacing : 0.0);
}
}
}
void SettingsCard::_SetAccessibleContentName()
{
// If Header is a string and the inner Content lacks an AutomationProperties.Name, propagate the header
// into the content so screen readers can announce something meaningful when focus lands there.
const auto headerObj{ Header() };
if (!headerObj)
{
return;
}
const auto headerString{ unbox_value_or<hstring>(headerObj, hstring{}) };
if (headerString.empty())
{
return;
}
const auto contentObj{ Content() };
if (const auto element{ contentObj.try_as<UIElement>() })
{
if (Automation::AutomationProperties::GetName(element).empty())
{
// Don't override ButtonBase content (would clobber its own name) or plain text blocks.
if (!element.try_as<ButtonBase>() && !element.try_as<TextBlock>())
{
Automation::AutomationProperties::SetName(element, headerString);
}
}
}
}
void SettingsCard::_EnableButtonInteraction()
{
if (_interactionEnabled)
{
return;
}
_interactionEnabled = true;
IsTabStop(true);
_pointerEnteredRevoker = PointerEntered(winrt::auto_revoke, [weakThis = get_weak()](auto&&, auto&&) {
if (const auto strongThis = weakThis.get())
{
strongThis->_GoToCommonState(PointerOverState, true);
}
});
_pointerExitedRevoker = PointerExited(winrt::auto_revoke, [weakThis = get_weak()](auto&&, auto&&) {
if (const auto strongThis = weakThis.get())
{
strongThis->_GoToCommonState(NormalState, true);
}
});
_pointerCaptureLostRevoker = PointerCaptureLost(winrt::auto_revoke, [weakThis = get_weak()](auto&&, auto&&) {
if (const auto strongThis = weakThis.get())
{
strongThis->_GoToCommonState(NormalState, true);
}
});
_pointerCanceledRevoker = PointerCanceled(winrt::auto_revoke, [weakThis = get_weak()](auto&&, auto&&) {
if (const auto strongThis = weakThis.get())
{
strongThis->_GoToCommonState(NormalState, true);
}
});
_previewKeyDownRevoker = PreviewKeyDown(winrt::auto_revoke, [weakThis = get_weak()](auto&&, const Windows::UI::Xaml::Input::KeyRoutedEventArgs& e) {
const auto strongThis = weakThis.get();
if (!strongThis)
{
return;
}
const auto key = e.Key();
if (key == Windows::System::VirtualKey::Enter || key == Windows::System::VirtualKey::Space || key == Windows::System::VirtualKey::GamepadA)
{
const auto focused{ strongThis->_GetFocusedElement() };
if (focused && focused.try_as<Editor::SettingsCard>() == strongThis.as<Editor::SettingsCard>())
{
strongThis->_GoToCommonState(PressedState, true);
}
}
});
_previewKeyUpRevoker = PreviewKeyUp(winrt::auto_revoke, [weakThis = get_weak()](auto&&, const Windows::UI::Xaml::Input::KeyRoutedEventArgs& e) {
const auto strongThis = weakThis.get();
if (!strongThis)
{
return;
}
const auto key = e.Key();
if (key == Windows::System::VirtualKey::Enter || key == Windows::System::VirtualKey::Space || key == Windows::System::VirtualKey::GamepadA)
{
strongThis->_GoToCommonState(NormalState, true);
}
});
}
void SettingsCard::_DisableButtonInteraction()
{
_interactionEnabled = false;
IsTabStop(false);
_pointerEnteredRevoker.revoke();
_pointerExitedRevoker.revoke();
_pointerCaptureLostRevoker.revoke();
_pointerCanceledRevoker.revoke();
_previewKeyDownRevoker.revoke();
_previewKeyUpRevoker.revoke();
}
void SettingsCard::_GoToCommonState(const std::wstring_view& state, bool useTransitions)
{
VisualStateManager::GoToState(*this, hstring{ state }, useTransitions);
}
FrameworkElement SettingsCard::_GetFocusedElement()
{
if (const auto root{ XamlRoot() })
{
return FocusManager::GetFocusedElement(root).try_as<FrameworkElement>();
}
return FocusManager::GetFocusedElement().try_as<FrameworkElement>();
}
void SettingsCard::_UpdateActionIconVisibility()
{
if (const auto child{ GetTemplateChild(hstring{ ActionIconPresenterHolder }) })
{
if (const auto frameworkChild{ child.try_as<FrameworkElement>() })
{
frameworkChild.Visibility((IsClickEnabled() && IsActionIconVisible()) ? Visibility::Visible : Visibility::Collapsed);
}
}
}
void SettingsCard::_UpdateHeaderVisibility()
{
if (const auto child{ GetTemplateChild(hstring{ HeaderPresenter }) })
{
if (const auto frameworkChild{ child.try_as<FrameworkElement>() })
{
frameworkChild.Visibility(_isNullOrEmpty(Header()) ? Visibility::Collapsed : Visibility::Visible);
}
}
}
void SettingsCard::_UpdateDescriptionVisibility()
{
if (const auto child{ GetTemplateChild(hstring{ DescriptionPresenter }) })
{
if (const auto frameworkChild{ child.try_as<FrameworkElement>() })
{
frameworkChild.Visibility(_isNullOrEmpty(Description()) ? Visibility::Collapsed : Visibility::Visible);
}
}
}
void SettingsCard::_UpdateHeaderIconVisibility()
{
if (const auto child{ GetTemplateChild(hstring{ HeaderIconPresenterHolder }) })
{
if (const auto frameworkChild{ child.try_as<FrameworkElement>() })
{
frameworkChild.Visibility(HeaderIcon() ? Visibility::Visible : Visibility::Collapsed);
}
}
}
void SettingsCard::_UpdateContentAlignmentState()
{
// Map ContentAlignment to the visual state name *and* the corresponding
// direct layout values. We drive both: GoToState keeps the visual state
// machine in sync (so _CheckVerticalSpacingState sees the right CurrentState),
// but we *also* apply the layout properties directly to PART_ContentPresenter
// because in WinUI 2, attached-property changes (Grid.Row/Grid.Column) and
// HorizontalAlignment changes inside VisualState.Setters or Storyboards
// don't reliably engage when activated by programmatic VisualStateManager::GoToState
// — only by XAML StateTriggers (which is what WCT uses via tk:IsEqualStateTrigger).
// Until/unless an equivalent state trigger gets ported, the direct C++ set is
// the load-bearing path for Left/Vertical.
std::wstring_view state{ RightState };
int contentRow{ 0 };
int contentColumn{ 2 };
auto contentHA{ HorizontalAlignment::Right };
const auto alignment = ContentAlignment();
switch (alignment)
{
case Editor::SettingsCardContentAlignment::Left:
state = LeftState;
contentRow = 1;
contentColumn = 1;
contentHA = HorizontalAlignment::Left;
break;
case Editor::SettingsCardContentAlignment::Vertical:
state = VerticalState;
contentRow = 1;
contentColumn = 1;
contentHA = HorizontalAlignment::Stretch;
break;
default:
break;
}
VisualStateManager::GoToState(*this, hstring{ state }, true);
if (const auto child{ GetTemplateChild(hstring{ ContentPresenterPart }) })
{
if (const auto contentPresenter{ child.try_as<FrameworkElement>() })
{
Grid::SetRow(contentPresenter, contentRow);
Grid::SetColumn(contentPresenter, contentColumn);
contentPresenter.HorizontalAlignment(contentHA);
// Vertical mirrors WCT's TemplatedParent Binding setter: propagate
// the card's own HorizontalContentAlignment to the inner ContentPresenter
// so e.g. HorizontalContentAlignment="Left" + ContentAlignment="Vertical"
// actually left-aligns the inner content.
if (const auto cp{ contentPresenter.try_as<ContentPresenter>() })
{
cp.HorizontalContentAlignment(HorizontalContentAlignment());
}
}
}
// Left collapses the HeaderIcon column regardless of HeaderIcon content.
if (const auto child{ GetTemplateChild(hstring{ HeaderIconPresenterHolder }) })
{
if (const auto headerIconHolder{ child.try_as<FrameworkElement>() })
{
if (alignment == Editor::SettingsCardContentAlignment::Left)
{
headerIconHolder.Visibility(Visibility::Collapsed);
}
else
{
headerIconHolder.Visibility(HeaderIcon() ? Visibility::Visible : Visibility::Collapsed);
}
}
}
}
void SettingsCard::_OnHeaderChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
{
const auto obj{ d.try_as<Editor::SettingsCard>() };
const auto self = get_self<SettingsCard>(obj);
self->_UpdateHeaderVisibility();
self->_SetAccessibleContentName();
}
void SettingsCard::_OnDescriptionChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
{
const auto obj{ d.try_as<Editor::SettingsCard>() };
get_self<SettingsCard>(obj)->_UpdateDescriptionVisibility();
}
void SettingsCard::_OnHeaderIconChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
{
const auto obj{ d.try_as<Editor::SettingsCard>() };
const auto self = get_self<SettingsCard>(obj);
self->_UpdateHeaderIconVisibility();
// HeaderIcon type may have flipped between BitmapIcon and other icon types — re-evaluate
// the BitmapHeaderIcon visual state so the disabled-opacity setter is applied (or cleared).
self->_CheckHeaderIconState();
}
void SettingsCard::_OnIsClickEnabledChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
{
const auto obj{ d.try_as<Editor::SettingsCard>() };
const auto self = get_self<SettingsCard>(obj);
self->_UpdateActionIconVisibility();
if (self->IsClickEnabled())
{
self->_EnableButtonInteraction();
}
else
{
self->_DisableButtonInteraction();
}
}
void SettingsCard::_OnIsActionIconVisibleChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
{
const auto obj{ d.try_as<Editor::SettingsCard>() };
get_self<SettingsCard>(obj)->_UpdateActionIconVisibility();
}
void SettingsCard::_OnContentAlignmentChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
{
const auto obj{ d.try_as<Editor::SettingsCard>() };
get_self<SettingsCard>(obj)->_UpdateContentAlignmentState();
}
SettingsCardAutomationPeer::SettingsCardAutomationPeer(const Editor::SettingsCard& owner) :
SettingsCardAutomationPeerT<SettingsCardAutomationPeer>(owner)
{
}
AutomationControlType SettingsCardAutomationPeer::GetAutomationControlTypeCore() const
{
if (const auto card{ Owner().try_as<Editor::SettingsCard>() })
{
if (card.IsClickEnabled())
{
return AutomationControlType::Button;
}
}
return AutomationControlType::Group;
}
hstring SettingsCardAutomationPeer::GetClassNameCore() const
{
return hstring{ L"SettingsCard" };
}
hstring SettingsCardAutomationPeer::GetNameCore() const
{
if (const auto card{ Owner().try_as<Editor::SettingsCard>() })
{
if (card.IsClickEnabled())
{
if (const auto manualName{ AutomationProperties::GetName(card) }; !manualName.empty())
{
return manualName;
}
if (const auto headerString{ unbox_value_or<hstring>(card.Header(), hstring{}) }; !headerString.empty())
{
return headerString;
}
}
// Not clickable, or no header text: fall back to AutomationProperties.Name (matching
// FrameworkElementAutomationPeer's default behavior).
return AutomationProperties::GetName(card);
}
return {};
}
winrt::Windows::Foundation::IInspectable SettingsCardAutomationPeer::GetPatternCore(PatternInterface patternInterface) const
{
if (patternInterface == PatternInterface::Invoke)
{
if (const auto card{ Owner().try_as<Editor::SettingsCard>() })
{
if (card.IsClickEnabled())
{
// Only provide Invoke pattern if the card is clickable.
return *this;
}
}
return nullptr;
}
// ButtonBaseAutomationPeer only provides Invoke; everything else returns null.
return nullptr;
}
}

Some files were not shown because too many files have changed in this diff Show More