mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-19 04:31:10 +00:00
Compare commits
26 Commits
dev/pabhoj
...
dev/lhecke
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
532b3a72dc | ||
|
|
a5d916f5d3 | ||
|
|
dfcc8f3c62 | ||
|
|
e818dafa6d | ||
|
|
0c3002c1b9 | ||
|
|
7d6e0c8b8e | ||
|
|
65788d9099 | ||
|
|
671440206c | ||
|
|
482980c336 | ||
|
|
7ab5978b58 | ||
|
|
48b796f102 | ||
|
|
f22295ef2c | ||
|
|
cb0289fff2 | ||
|
|
8c20d2052d | ||
|
|
452fa87937 | ||
|
|
3979e82c2b | ||
|
|
fedf7b3b6c | ||
|
|
a04e410a39 | ||
|
|
7b841628df | ||
|
|
5b63e24c73 | ||
|
|
e7939bb4e3 | ||
|
|
bdf44322f8 | ||
|
|
f2b30b4e1e | ||
|
|
0cbb6b1f2f | ||
|
|
f14718f738 | ||
|
|
c4fbb58f69 |
1
.github/actions/spelling/expect/expect.txt
vendored
1
.github/actions/spelling/expect/expect.txt
vendored
@@ -2,6 +2,7 @@ aaaaabbb
|
||||
aabbcc
|
||||
ABANDONFONT
|
||||
abbcc
|
||||
abcc
|
||||
abgr
|
||||
ABORTIFHUNG
|
||||
ACCESSTOKEN
|
||||
|
||||
2
.github/workflows/spelling2.yml
vendored
2
.github/workflows/spelling2.yml
vendored
@@ -104,7 +104,7 @@ jobs:
|
||||
report-timing: 1
|
||||
warnings: bad-regex,binary-file,deprecated-feature,ignored-expect-variant,large-file,limited-references,no-newline-at-eof,noisy-file,non-alpha-in-dictionary,token-is-substring,unexpected-line-ending,whitespace-in-dictionary,minified-file,unsupported-configuration,no-files-to-check,unclosed-block-ignore-begin,unclosed-block-ignore-end
|
||||
experimental_apply_changes_via_bot: ${{ github.repository_owner != 'microsoft' && 1 }}
|
||||
use_sarif: ${{ (!github.event.pull_request || (github.event.pull_request.head.repo.full_name == github.repository)) && 1 }}
|
||||
use_sarif: 1
|
||||
check_extra_dictionaries: ""
|
||||
dictionary_source_prefixes: >
|
||||
{
|
||||
|
||||
@@ -14,21 +14,21 @@
|
||||
<Package
|
||||
Name="Microsoft.UI.Xaml.2.8"
|
||||
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
|
||||
Version="8.2305.5001.0"
|
||||
Version="8.2306.22001.0"
|
||||
ProcessorArchitecture="x64"
|
||||
Uri="https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.4/Microsoft.UI.Xaml.2.8.x64.appx" />
|
||||
Uri="https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.5/Microsoft.UI.Xaml.2.8.x64.appx" />
|
||||
<Package
|
||||
Name="Microsoft.UI.Xaml.2.8"
|
||||
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
|
||||
Version="8.2305.5001.0"
|
||||
Version="8.2306.22001.0"
|
||||
ProcessorArchitecture="x86"
|
||||
Uri="https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.4/Microsoft.UI.Xaml.2.8.x86.appx" />
|
||||
Uri="https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.5/Microsoft.UI.Xaml.2.8.x86.appx" />
|
||||
<Package
|
||||
Name="Microsoft.UI.Xaml.2.8"
|
||||
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
|
||||
Version="8.2305.5001.0"
|
||||
Version="8.2306.22001.0"
|
||||
ProcessorArchitecture="arm64"
|
||||
Uri="https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.4/Microsoft.UI.Xaml.2.8.arm64.appx" />
|
||||
Uri="https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.5/Microsoft.UI.Xaml.2.8.arm64.appx" />
|
||||
</Dependencies>
|
||||
|
||||
<UpdateSettings>
|
||||
|
||||
@@ -7,5 +7,8 @@
|
||||
<VersionMajor>1</VersionMajor>
|
||||
<VersionMinor>24</VersionMinor>
|
||||
<VersionInfoProductName>Windows Terminal</VersionInfoProductName>
|
||||
<VersionInfoCulture>1033</VersionInfoCulture>
|
||||
<!-- The default has a spacing problem -->
|
||||
<VersionInfoCopyRight>\xa9 Microsoft Corporation. All rights reserved.</VersionInfoCopyRight>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
||||
@@ -2376,6 +2376,16 @@
|
||||
"description": "When set to true, the terminal will focus the pane on mouse hover.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"experimental.scrollToZoom": {
|
||||
"default": true,
|
||||
"description": "When set to true, holding the Ctrl key while scrolling will increase or decrease the terminal font size.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"experimental.scrollToChangeOpacity": {
|
||||
"default": true,
|
||||
"description": "When set to true, holding the Ctrl and Shift keys while scrolling will change the window opacity.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"compatibility.allowHeadless": {
|
||||
"default": false,
|
||||
"description": "When set to true, Windows Terminal will run in the background. This allows globalSummon and quakeMode actions to work even when no windows are open.",
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<ProjectName>elevate-shim</ProjectName>
|
||||
<TargetName>elevate-shim</TargetName>
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<VersionInfoFileDescription>Windows Terminal Administrator Launch Helper</VersionInfoFileDescription>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "../TerminalApp/CommandLinePaletteItem.h"
|
||||
#include "../TerminalApp/CommandPalette.h"
|
||||
#include "../TerminalApp/BasePaletteItem.h"
|
||||
#include "CppWinrtTailored.h"
|
||||
|
||||
using namespace Microsoft::Console;
|
||||
@@ -15,6 +15,20 @@ using namespace winrt::Microsoft::Terminal::Control;
|
||||
|
||||
namespace TerminalAppLocalTests
|
||||
{
|
||||
struct StringPaletteItem : winrt::implements<StringPaletteItem, winrt::TerminalApp::IPaletteItem, winrt::Windows::UI::Xaml::Data::INotifyPropertyChanged>, winrt::TerminalApp::implementation::BasePaletteItem<StringPaletteItem, winrt::TerminalApp::PaletteItemType::CommandLine>
|
||||
{
|
||||
StringPaletteItem(std::wstring_view value) :
|
||||
_value{ value } {}
|
||||
|
||||
winrt::hstring Name() { return _value; }
|
||||
winrt::hstring Subtitle() { return {}; }
|
||||
winrt::hstring KeyChordText() { return {}; }
|
||||
winrt::hstring Icon() { return {}; }
|
||||
|
||||
private:
|
||||
winrt::hstring _value;
|
||||
};
|
||||
|
||||
class FilteredCommandTests
|
||||
{
|
||||
BEGIN_TEST_CLASS(FilteredCommandTests)
|
||||
@@ -28,74 +42,81 @@ namespace TerminalAppLocalTests
|
||||
TEST_METHOD(VerifyCompareIgnoreCase);
|
||||
};
|
||||
|
||||
static void _verifySegment(auto&& segments, uint32_t index, uint64_t start, uint64_t end)
|
||||
{
|
||||
const auto& segment{ segments.GetAt(index) };
|
||||
VERIFY_ARE_EQUAL(segment.Start, start, NoThrowString().Format(L"segment %zu", index));
|
||||
VERIFY_ARE_EQUAL(segment.End, end, NoThrowString().Format(L"segment %zu", index));
|
||||
}
|
||||
|
||||
void FilteredCommandTests::VerifyHighlighting()
|
||||
{
|
||||
auto result = RunOnUIThread([]() {
|
||||
const auto paletteItem{ winrt::make<winrt::TerminalApp::implementation::CommandLinePaletteItem>(L"AAAAAABBBBBBCCC") };
|
||||
const WEX::TestExecution::DisableVerifyExceptions disableExceptionsScope;
|
||||
|
||||
const auto paletteItem{ winrt::make<StringPaletteItem>(L"AAAAAABBBBBBCCC") };
|
||||
const auto filteredCommand = winrt::make_self<winrt::TerminalApp::implementation::FilteredCommand>(paletteItem);
|
||||
|
||||
{
|
||||
Log::Comment(L"Testing command name segmentation with no filter");
|
||||
auto segments = filteredCommand->HighlightedName().Segments();
|
||||
VERIFY_ARE_EQUAL(segments.Size(), 1u);
|
||||
VERIFY_ARE_EQUAL(segments.GetAt(0).TextSegment(), L"AAAAAABBBBBBCCC");
|
||||
VERIFY_IS_FALSE(segments.GetAt(0).IsHighlighted());
|
||||
const auto segments = filteredCommand->NameHighlights();
|
||||
|
||||
VERIFY_IS_NULL(segments); // No matches = no segments
|
||||
}
|
||||
{
|
||||
Log::Comment(L"Testing command name segmentation with empty filter");
|
||||
filteredCommand->UpdateFilter(std::make_shared<fzf::matcher::Pattern>(fzf::matcher::ParsePattern(L"")));
|
||||
auto segments = filteredCommand->HighlightedName().Segments();
|
||||
VERIFY_ARE_EQUAL(segments.Size(), 1u);
|
||||
VERIFY_ARE_EQUAL(segments.GetAt(0).TextSegment(), L"AAAAAABBBBBBCCC");
|
||||
VERIFY_IS_FALSE(segments.GetAt(0).IsHighlighted());
|
||||
const auto segments = filteredCommand->NameHighlights();
|
||||
|
||||
VERIFY_IS_NULL(segments); // No matches = no segments
|
||||
}
|
||||
{
|
||||
Log::Comment(L"Testing command name segmentation with filter equal to the string");
|
||||
filteredCommand->UpdateFilter(std::make_shared<fzf::matcher::Pattern>(fzf::matcher::ParsePattern(L"AAAAAABBBBBBCCC")));
|
||||
auto segments = filteredCommand->HighlightedName().Segments();
|
||||
const auto segments = filteredCommand->NameHighlights();
|
||||
|
||||
VERIFY_ARE_EQUAL(segments.Size(), 1u);
|
||||
VERIFY_ARE_EQUAL(segments.GetAt(0).TextSegment(), L"AAAAAABBBBBBCCC");
|
||||
VERIFY_IS_TRUE(segments.GetAt(0).IsHighlighted());
|
||||
_verifySegment(segments, 0, 0, 14); // one segment for the entire string
|
||||
}
|
||||
{
|
||||
Log::Comment(L"Testing command name segmentation with filter with first character matching");
|
||||
filteredCommand->UpdateFilter(std::make_shared<fzf::matcher::Pattern>(fzf::matcher::ParsePattern(L"A")));
|
||||
auto segments = filteredCommand->HighlightedName().Segments();
|
||||
VERIFY_ARE_EQUAL(segments.Size(), 2u);
|
||||
VERIFY_ARE_EQUAL(segments.GetAt(0).TextSegment(), L"A");
|
||||
VERIFY_IS_TRUE(segments.GetAt(0).IsHighlighted());
|
||||
VERIFY_ARE_EQUAL(segments.GetAt(1).TextSegment(), L"AAAAABBBBBBCCC");
|
||||
VERIFY_IS_FALSE(segments.GetAt(1).IsHighlighted());
|
||||
const auto segments = filteredCommand->NameHighlights();
|
||||
|
||||
VERIFY_ARE_EQUAL(segments.Size(), 1u); // only one bold segment
|
||||
_verifySegment(segments, 0, 0, 0); // it only covers the first character
|
||||
}
|
||||
{
|
||||
Log::Comment(L"Testing command name segmentation with filter with other case");
|
||||
filteredCommand->UpdateFilter(std::make_shared<fzf::matcher::Pattern>(fzf::matcher::ParsePattern(L"a")));
|
||||
auto segments = filteredCommand->HighlightedName().Segments();
|
||||
VERIFY_ARE_EQUAL(segments.Size(), 2u);
|
||||
VERIFY_ARE_EQUAL(segments.GetAt(0).TextSegment(), L"A");
|
||||
VERIFY_IS_TRUE(segments.GetAt(0).IsHighlighted());
|
||||
VERIFY_ARE_EQUAL(segments.GetAt(1).TextSegment(), L"AAAAABBBBBBCCC");
|
||||
VERIFY_IS_FALSE(segments.GetAt(1).IsHighlighted());
|
||||
const auto segments = filteredCommand->NameHighlights();
|
||||
|
||||
VERIFY_ARE_EQUAL(segments.Size(), 1u); // only one bold segment
|
||||
_verifySegment(segments, 0, 0, 0); // it only covers the first character
|
||||
}
|
||||
{
|
||||
Log::Comment(L"Testing command name segmentation with filter matching several characters");
|
||||
filteredCommand->UpdateFilter(std::make_shared<fzf::matcher::Pattern>(fzf::matcher::ParsePattern(L"ab")));
|
||||
auto segments = filteredCommand->HighlightedName().Segments();
|
||||
VERIFY_ARE_EQUAL(segments.Size(), 3u);
|
||||
VERIFY_ARE_EQUAL(segments.GetAt(0).TextSegment(), L"AAAAA");
|
||||
VERIFY_IS_FALSE(segments.GetAt(0).IsHighlighted());
|
||||
VERIFY_ARE_EQUAL(segments.GetAt(1).TextSegment(), L"AB");
|
||||
VERIFY_IS_TRUE(segments.GetAt(1).IsHighlighted());
|
||||
VERIFY_ARE_EQUAL(segments.GetAt(2).TextSegment(), L"BBBBBCCC");
|
||||
VERIFY_IS_FALSE(segments.GetAt(2).IsHighlighted());
|
||||
const auto segments = filteredCommand->NameHighlights();
|
||||
|
||||
VERIFY_ARE_EQUAL(segments.Size(), 1u); // one bold segment
|
||||
_verifySegment(segments, 0, 5, 6); // middle 'ab'
|
||||
}
|
||||
{
|
||||
Log::Comment(L"Testing command name segmentation with filter matching several regions");
|
||||
filteredCommand->UpdateFilter(std::make_shared<fzf::matcher::Pattern>(fzf::matcher::ParsePattern(L"abcc")));
|
||||
const auto segments = filteredCommand->NameHighlights();
|
||||
|
||||
VERIFY_ARE_EQUAL(segments.Size(), 2u); // two bold segments
|
||||
_verifySegment(segments, 0, 5, 6); // middle 'ab'
|
||||
_verifySegment(segments, 1, 12, 13); // start of 'cc'
|
||||
}
|
||||
{
|
||||
Log::Comment(L"Testing command name segmentation with non matching filter");
|
||||
filteredCommand->UpdateFilter(std::make_shared<fzf::matcher::Pattern>(fzf::matcher::ParsePattern(L"abcd")));
|
||||
auto segments = filteredCommand->HighlightedName().Segments();
|
||||
VERIFY_ARE_EQUAL(segments.Size(), 1u);
|
||||
VERIFY_ARE_EQUAL(segments.GetAt(0).TextSegment(), L"AAAAAABBBBBBCCC");
|
||||
VERIFY_IS_FALSE(segments.GetAt(0).IsHighlighted());
|
||||
const auto segments = filteredCommand->NameHighlights();
|
||||
|
||||
VERIFY_IS_NULL(segments); // No matches = no segments
|
||||
}
|
||||
});
|
||||
|
||||
@@ -105,7 +126,7 @@ namespace TerminalAppLocalTests
|
||||
void FilteredCommandTests::VerifyWeight()
|
||||
{
|
||||
auto result = RunOnUIThread([]() {
|
||||
const auto paletteItem{ winrt::make<winrt::TerminalApp::implementation::CommandLinePaletteItem>(L"AAAAAABBBBBBCCC") };
|
||||
const auto paletteItem{ winrt::make<StringPaletteItem>(L"AAAAAABBBBBBCCC") };
|
||||
const auto filteredCommand = winrt::make_self<winrt::TerminalApp::implementation::FilteredCommand>(paletteItem);
|
||||
|
||||
const auto weigh = [&](const wchar_t* str) {
|
||||
@@ -145,8 +166,8 @@ namespace TerminalAppLocalTests
|
||||
void FilteredCommandTests::VerifyCompare()
|
||||
{
|
||||
auto result = RunOnUIThread([]() {
|
||||
const auto paletteItem{ winrt::make<winrt::TerminalApp::implementation::CommandLinePaletteItem>(L"AAAAAABBBBBBCCC") };
|
||||
const auto paletteItem2{ winrt::make<winrt::TerminalApp::implementation::CommandLinePaletteItem>(L"BBBBBCCC") };
|
||||
const auto paletteItem{ winrt::make<StringPaletteItem>(L"AAAAAABBBBBBCCC") };
|
||||
const auto paletteItem2{ winrt::make<StringPaletteItem>(L"BBBBBCCC") };
|
||||
{
|
||||
Log::Comment(L"Testing comparison of commands with no filter");
|
||||
const auto filteredCommand = winrt::make_self<winrt::TerminalApp::implementation::FilteredCommand>(paletteItem);
|
||||
@@ -185,8 +206,8 @@ namespace TerminalAppLocalTests
|
||||
void FilteredCommandTests::VerifyCompareIgnoreCase()
|
||||
{
|
||||
auto result = RunOnUIThread([]() {
|
||||
const auto paletteItem{ winrt::make<winrt::TerminalApp::implementation::CommandLinePaletteItem>(L"a") };
|
||||
const auto paletteItem2{ winrt::make<winrt::TerminalApp::implementation::CommandLinePaletteItem>(L"B") };
|
||||
const auto paletteItem{ winrt::make<StringPaletteItem>(L"a") };
|
||||
const auto paletteItem2{ winrt::make<StringPaletteItem>(L"B") };
|
||||
{
|
||||
const auto filteredCommand = winrt::make_self<winrt::TerminalApp::implementation::FilteredCommand>(paletteItem);
|
||||
const auto filteredCommand2 = winrt::make_self<winrt::TerminalApp::implementation::FilteredCommand>(paletteItem2);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "../TerminalApp/MinMaxCloseControl.h"
|
||||
#include "../TerminalApp/TabRowControl.h"
|
||||
#include "../TerminalApp/ShortcutActionDispatch.h"
|
||||
#include "../TerminalApp/TerminalTab.h"
|
||||
#include "../TerminalApp/Tab.h"
|
||||
#include "../TerminalApp/CommandPalette.h"
|
||||
#include "../TerminalApp/ContentManager.h"
|
||||
#include "CppWinrtTailored.h"
|
||||
@@ -307,7 +307,7 @@ namespace TerminalAppLocalTests
|
||||
// reliably in the unit tests.
|
||||
Log::Comment(L"Ensure we set the first tab as the selected one.");
|
||||
auto tab = page->_tabs.GetAt(0);
|
||||
auto tabImpl = page->_GetTerminalTabImpl(tab);
|
||||
auto tabImpl = page->_GetTabImpl(tab);
|
||||
page->_tabView.SelectedItem(tabImpl->TabViewItem());
|
||||
page->_UpdatedSelectedTab(tab);
|
||||
});
|
||||
@@ -510,7 +510,7 @@ namespace TerminalAppLocalTests
|
||||
|
||||
result = RunOnUIThread([&page]() {
|
||||
VERIFY_ARE_EQUAL(1u, page->_tabs.Size());
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(1, tab->GetLeafPaneCount());
|
||||
});
|
||||
VERIFY_SUCCEEDED(result);
|
||||
@@ -520,7 +520,7 @@ namespace TerminalAppLocalTests
|
||||
page->_SplitPane(nullptr, SplitDirection::Automatic, 0.5f, page->_MakePane(nullptr, page->_GetFocusedTab(), nullptr));
|
||||
|
||||
VERIFY_ARE_EQUAL(1u, page->_tabs.Size());
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(2, tab->GetLeafPaneCount());
|
||||
});
|
||||
VERIFY_SUCCEEDED(result);
|
||||
@@ -538,7 +538,7 @@ namespace TerminalAppLocalTests
|
||||
page->_SplitPane(nullptr, SplitDirection::Automatic, 0.5f, page->_MakePane(nullptr, page->_GetFocusedTab(), nullptr));
|
||||
|
||||
VERIFY_ARE_EQUAL(1u, page->_tabs.Size());
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(3,
|
||||
tab->GetLeafPaneCount(),
|
||||
L"We should successfully duplicate a pane hosting a deleted profile.");
|
||||
@@ -706,7 +706,7 @@ namespace TerminalAppLocalTests
|
||||
SplitPaneArgs args{ SplitType::Duplicate };
|
||||
ActionEventArgs eventArgs{ args };
|
||||
page->_HandleSplitPane(nullptr, eventArgs);
|
||||
auto firstTab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto firstTab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
|
||||
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||
VERIFY_IS_FALSE(firstTab->IsZoomed());
|
||||
@@ -717,7 +717,7 @@ namespace TerminalAppLocalTests
|
||||
result = RunOnUIThread([&page]() {
|
||||
ActionEventArgs eventArgs{};
|
||||
page->_HandleTogglePaneZoom(nullptr, eventArgs);
|
||||
auto firstTab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto firstTab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||
VERIFY_IS_TRUE(firstTab->IsZoomed());
|
||||
});
|
||||
@@ -727,7 +727,7 @@ namespace TerminalAppLocalTests
|
||||
result = RunOnUIThread([&page]() {
|
||||
ActionEventArgs eventArgs{};
|
||||
page->_HandleTogglePaneZoom(nullptr, eventArgs);
|
||||
auto firstTab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto firstTab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||
VERIFY_IS_FALSE(firstTab->IsZoomed());
|
||||
});
|
||||
@@ -744,7 +744,7 @@ namespace TerminalAppLocalTests
|
||||
SplitPaneArgs args{ SplitType::Duplicate };
|
||||
ActionEventArgs eventArgs{ args };
|
||||
page->_HandleSplitPane(nullptr, eventArgs);
|
||||
auto firstTab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto firstTab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
|
||||
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||
VERIFY_IS_FALSE(firstTab->IsZoomed());
|
||||
@@ -758,7 +758,7 @@ namespace TerminalAppLocalTests
|
||||
|
||||
page->_HandleTogglePaneZoom(nullptr, eventArgs);
|
||||
|
||||
auto firstTab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto firstTab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||
VERIFY_IS_TRUE(firstTab->IsZoomed());
|
||||
});
|
||||
@@ -772,7 +772,7 @@ namespace TerminalAppLocalTests
|
||||
|
||||
page->_HandleMoveFocus(nullptr, eventArgs);
|
||||
|
||||
auto firstTab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto firstTab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||
VERIFY_IS_TRUE(firstTab->IsZoomed());
|
||||
});
|
||||
@@ -789,7 +789,7 @@ namespace TerminalAppLocalTests
|
||||
SplitPaneArgs args{ SplitType::Duplicate };
|
||||
ActionEventArgs eventArgs{ args };
|
||||
page->_HandleSplitPane(nullptr, eventArgs);
|
||||
auto firstTab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto firstTab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
|
||||
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||
VERIFY_IS_FALSE(firstTab->IsZoomed());
|
||||
@@ -803,7 +803,7 @@ namespace TerminalAppLocalTests
|
||||
|
||||
page->_HandleTogglePaneZoom(nullptr, eventArgs);
|
||||
|
||||
auto firstTab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto firstTab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(2, firstTab->GetLeafPaneCount());
|
||||
VERIFY_IS_TRUE(firstTab->IsZoomed());
|
||||
});
|
||||
@@ -816,7 +816,7 @@ namespace TerminalAppLocalTests
|
||||
|
||||
page->_HandleClosePane(nullptr, eventArgs);
|
||||
|
||||
auto firstTab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto firstTab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_IS_FALSE(firstTab->IsZoomed());
|
||||
});
|
||||
VERIFY_SUCCEEDED(result);
|
||||
@@ -827,7 +827,7 @@ namespace TerminalAppLocalTests
|
||||
Log::Comment(L"Check to ensure there's only one pane left.");
|
||||
|
||||
result = RunOnUIThread([&page]() {
|
||||
auto firstTab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto firstTab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(1, firstTab->GetLeafPaneCount());
|
||||
VERIFY_IS_FALSE(firstTab->IsZoomed());
|
||||
});
|
||||
@@ -850,7 +850,7 @@ namespace TerminalAppLocalTests
|
||||
uint32_t firstId = 0, secondId = 0, thirdId = 0, fourthId = 0;
|
||||
TestOnUIThread([&]() {
|
||||
VERIFY_ARE_EQUAL(1u, page->_tabs.Size());
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
firstId = tab->_activePane->Id().value();
|
||||
// We start with 1 tab, split vertically to get
|
||||
// -------------------
|
||||
@@ -876,7 +876,7 @@ namespace TerminalAppLocalTests
|
||||
// | | |
|
||||
// -------------------
|
||||
page->_SplitPane(nullptr, SplitDirection::Down, 0.5f, page->_MakePane(nullptr, page->_GetFocusedTab(), nullptr));
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
// Split again to make the 3rd tab
|
||||
thirdId = tab->_activePane->Id().value();
|
||||
});
|
||||
@@ -896,13 +896,13 @@ namespace TerminalAppLocalTests
|
||||
// | | |
|
||||
// -------------------
|
||||
page->_SplitPane(nullptr, SplitDirection::Down, 0.5f, page->_MakePane(nullptr, page->_GetFocusedTab(), nullptr));
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
fourthId = tab->_activePane->Id().value();
|
||||
});
|
||||
|
||||
Sleep(250);
|
||||
TestOnUIThread([&]() {
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(4, tab->GetLeafPaneCount());
|
||||
// just to be complete, make sure we actually have 4 different ids
|
||||
VERIFY_ARE_NOT_EQUAL(firstId, fourthId);
|
||||
@@ -936,7 +936,7 @@ namespace TerminalAppLocalTests
|
||||
Sleep(250);
|
||||
|
||||
TestOnUIThread([&]() {
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(4, tab->GetLeafPaneCount());
|
||||
// Our currently focused pane should be `4`
|
||||
VERIFY_ARE_EQUAL(fourthId, tab->_activePane->Id().value());
|
||||
@@ -967,7 +967,7 @@ namespace TerminalAppLocalTests
|
||||
Sleep(250);
|
||||
|
||||
TestOnUIThread([&]() {
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(4, tab->GetLeafPaneCount());
|
||||
// Our currently focused pane should be `4`
|
||||
VERIFY_ARE_EQUAL(fourthId, tab->_activePane->Id().value());
|
||||
@@ -998,7 +998,7 @@ namespace TerminalAppLocalTests
|
||||
Sleep(250);
|
||||
|
||||
TestOnUIThread([&]() {
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(4, tab->GetLeafPaneCount());
|
||||
// Our currently focused pane should be `4`
|
||||
VERIFY_ARE_EQUAL(fourthId, tab->_activePane->Id().value());
|
||||
@@ -1029,7 +1029,7 @@ namespace TerminalAppLocalTests
|
||||
Sleep(250);
|
||||
|
||||
TestOnUIThread([&]() {
|
||||
auto tab = page->_GetTerminalTabImpl(page->_tabs.GetAt(0));
|
||||
auto tab = page->_GetTabImpl(page->_tabs.GetAt(0));
|
||||
VERIFY_ARE_EQUAL(4, tab->GetLeafPaneCount());
|
||||
// Our currently focused pane should be `4`
|
||||
VERIFY_ARE_EQUAL(fourthId, tab->_activePane->Id().value());
|
||||
@@ -1174,16 +1174,16 @@ namespace TerminalAppLocalTests
|
||||
|
||||
Log::Comment(L"give alphabetical names to all switch tab actions");
|
||||
TestOnUIThread([&page]() {
|
||||
page->_GetTerminalTabImpl(page->_tabs.GetAt(0))->Title(L"a");
|
||||
page->_GetTabImpl(page->_tabs.GetAt(0))->Title(L"a");
|
||||
});
|
||||
TestOnUIThread([&page]() {
|
||||
page->_GetTerminalTabImpl(page->_tabs.GetAt(1))->Title(L"b");
|
||||
page->_GetTabImpl(page->_tabs.GetAt(1))->Title(L"b");
|
||||
});
|
||||
TestOnUIThread([&page]() {
|
||||
page->_GetTerminalTabImpl(page->_tabs.GetAt(2))->Title(L"c");
|
||||
page->_GetTabImpl(page->_tabs.GetAt(2))->Title(L"c");
|
||||
});
|
||||
TestOnUIThread([&page]() {
|
||||
page->_GetTerminalTabImpl(page->_tabs.GetAt(3))->Title(L"d");
|
||||
page->_GetTabImpl(page->_tabs.GetAt(3))->Title(L"d");
|
||||
});
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<SubSystem>Console</SubSystem>
|
||||
<!-- suppress a bunch of Windows Universal properties from cppwinrt.props -->
|
||||
<OpenConsoleUniversalApp>false</OpenConsoleUniversalApp>
|
||||
<VersionInfoFileDescription>Windows Terminal Open Here Shell Extension</VersionInfoFileDescription>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="NuGet Dependencies">
|
||||
<TerminalCppWinrt>true</TerminalCppWinrt>
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "ActionPaletteItem.h"
|
||||
#include <LibraryResources.h>
|
||||
|
||||
#include "ActionPaletteItem.g.cpp"
|
||||
|
||||
using namespace winrt;
|
||||
using namespace winrt::TerminalApp;
|
||||
using namespace winrt::Windows::UI::Core;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::System;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
ActionPaletteItem::ActionPaletteItem(const Microsoft::Terminal::Settings::Model::Command& command, const winrt::hstring keyChordText) :
|
||||
_Command(command)
|
||||
{
|
||||
Name(command.Name());
|
||||
KeyChordText(keyChordText);
|
||||
Icon(command.IconPath());
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "PaletteItem.h"
|
||||
#include "ActionPaletteItem.g.h"
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct ActionPaletteItem : ActionPaletteItemT<ActionPaletteItem, PaletteItem>
|
||||
{
|
||||
ActionPaletteItem() = default;
|
||||
ActionPaletteItem(const Microsoft::Terminal::Settings::Model::Command& command, const winrt::hstring keyChordText);
|
||||
|
||||
WINRT_PROPERTY(Microsoft::Terminal::Settings::Model::Command, Command, nullptr);
|
||||
|
||||
private:
|
||||
Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker _commandChangedRevoker;
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::TerminalApp::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(ActionPaletteItem);
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "PaletteItem.idl";
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
[default_interface] runtimeclass ActionPaletteItem : PaletteItem
|
||||
{
|
||||
ActionPaletteItem(Microsoft.Terminal.Settings.Model.Command command, String keyChordText);
|
||||
|
||||
Microsoft.Terminal.Settings.Model.Command Command { get; };
|
||||
}
|
||||
}
|
||||
@@ -243,6 +243,8 @@
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
</ResourceDictionary>
|
||||
|
||||
<ResourceDictionary Source="ms-resource:///Files/TerminalApp/HighlightedTextControlStyle.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
|
||||
|
||||
@@ -41,13 +41,13 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
return _GetActiveControl();
|
||||
}
|
||||
winrt::com_ptr<TerminalTab> TerminalPage::_senderOrFocusedTab(const IInspectable& sender)
|
||||
winrt::com_ptr<Tab> TerminalPage::_senderOrFocusedTab(const IInspectable& sender)
|
||||
{
|
||||
if (sender)
|
||||
{
|
||||
if (auto tab{ sender.try_as<TerminalApp::TerminalTab>() })
|
||||
if (auto tab = sender.try_as<TerminalApp::Tab>())
|
||||
{
|
||||
return _GetTerminalTabImpl(tab);
|
||||
return _GetTabImpl(tab);
|
||||
}
|
||||
}
|
||||
return _GetFocusedTabImpl();
|
||||
@@ -193,17 +193,17 @@ namespace winrt::TerminalApp::implementation
|
||||
void TerminalPage::_HandleCloseOtherPanes(const IInspectable& sender,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
if (const auto& terminalTab{ _senderOrFocusedTab(sender) })
|
||||
if (const auto& activeTab{ _senderOrFocusedTab(sender) })
|
||||
{
|
||||
const auto activePane = terminalTab->GetActivePane();
|
||||
if (terminalTab->GetRootPane() != activePane)
|
||||
const auto activePane = activeTab->GetActivePane();
|
||||
if (activeTab->GetRootPane() != activePane)
|
||||
{
|
||||
_UnZoomIfNeeded();
|
||||
|
||||
// Accumulate list of all unfocused leaf panes, ignore read-only panes
|
||||
std::vector<uint32_t> unfocusedPaneIds;
|
||||
const auto activePaneId = activePane->Id();
|
||||
terminalTab->GetRootPane()->WalkTree([&](auto&& p) {
|
||||
activeTab->GetRootPane()->WalkTree([&](auto&& p) {
|
||||
const auto id = p->Id();
|
||||
if (id.has_value() && id != activePaneId && !p->ContainsReadOnly())
|
||||
{
|
||||
@@ -215,7 +215,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
// Start by removing the panes that were least recently added
|
||||
sort(begin(unfocusedPaneIds), end(unfocusedPaneIds), std::less<uint32_t>());
|
||||
_ClosePanes(terminalTab->get_weak(), std::move(unfocusedPaneIds));
|
||||
_ClosePanes(activeTab->get_weak(), std::move(unfocusedPaneIds));
|
||||
args.Handled(true);
|
||||
return;
|
||||
}
|
||||
@@ -281,9 +281,9 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
const auto& duplicateFromTab{ realArgs.SplitMode() == SplitType::Duplicate ? _GetFocusedTab() : nullptr };
|
||||
|
||||
const auto& terminalTab{ _senderOrFocusedTab(sender) };
|
||||
const auto& activeTab{ _senderOrFocusedTab(sender) };
|
||||
|
||||
_SplitPane(terminalTab,
|
||||
_SplitPane(activeTab,
|
||||
realArgs.SplitDirection(),
|
||||
// This is safe, we're already filtering so the value is (0, 1)
|
||||
realArgs.SplitSize(),
|
||||
@@ -302,14 +302,14 @@ namespace winrt::TerminalApp::implementation
|
||||
void TerminalPage::_HandleTogglePaneZoom(const IInspectable& sender,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
if (const auto terminalTab{ _senderOrFocusedTab(sender) })
|
||||
if (const auto activeTab{ _senderOrFocusedTab(sender) })
|
||||
{
|
||||
// Don't do anything if there's only one pane. It's already zoomed.
|
||||
if (terminalTab->GetLeafPaneCount() > 1)
|
||||
if (activeTab->GetLeafPaneCount() > 1)
|
||||
{
|
||||
// Togging the zoom on the tab will cause the tab to inform us of
|
||||
// the new root Content for this tab.
|
||||
terminalTab->ToggleZoom();
|
||||
activeTab->ToggleZoom();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -783,7 +783,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
// Since _RemoveTabs is asynchronous, create a snapshot of the tabs we want to remove
|
||||
std::vector<winrt::TerminalApp::TabBase> tabsToRemove;
|
||||
std::vector<winrt::TerminalApp::Tab> tabsToRemove;
|
||||
if (index > 0)
|
||||
{
|
||||
std::copy(begin(_tabs), begin(_tabs) + index, std::back_inserter(tabsToRemove));
|
||||
@@ -822,7 +822,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
// Since _RemoveTabs is asynchronous, create a snapshot of the tabs we want to remove
|
||||
std::vector<winrt::TerminalApp::TabBase> tabsToRemove;
|
||||
std::vector<winrt::TerminalApp::Tab> tabsToRemove;
|
||||
std::copy(begin(_tabs) + index + 1, end(_tabs), std::back_inserter(tabsToRemove));
|
||||
_RemoveTabs(tabsToRemove);
|
||||
|
||||
@@ -1559,7 +1559,6 @@ namespace winrt::TerminalApp::implementation
|
||||
activeTab->ToggleBroadcastInput();
|
||||
args.Handled(true);
|
||||
}
|
||||
// If the focused tab wasn't a TerminalTab, then leave handled=false
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleRestartConnection(const IInspectable& sender,
|
||||
|
||||
40
src/cascadia/TerminalApp/BasePaletteItem.h
Normal file
40
src/cascadia/TerminalApp/BasePaletteItem.h
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
template<typename T, winrt::TerminalApp::PaletteItemType Ty>
|
||||
struct BasePaletteItem
|
||||
{
|
||||
public:
|
||||
winrt::TerminalApp::PaletteItemType Type() { return Ty; }
|
||||
|
||||
Windows::UI::Xaml::Controls::IconElement ResolvedIcon()
|
||||
{
|
||||
const auto icon{ static_cast<T*>(this)->Icon() };
|
||||
if (!icon.empty())
|
||||
{
|
||||
const auto resolvedIcon{ Microsoft::Terminal::UI::IconPathConverter::IconWUX(icon) };
|
||||
resolvedIcon.Width(16);
|
||||
resolvedIcon.Height(16);
|
||||
return resolvedIcon;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
til::property_changed_event PropertyChanged;
|
||||
|
||||
protected:
|
||||
void BaseRaisePropertyChanged(wil::zwstring_view property)
|
||||
{
|
||||
PropertyChanged.raise(*static_cast<T*>(this), winrt::Windows::UI::Xaml::Data::PropertyChangedEventArgs{ property });
|
||||
}
|
||||
|
||||
void InvalidateResolvedIcon()
|
||||
{
|
||||
BaseRaisePropertyChanged(L"ResolvedIcon");
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,267 +0,0 @@
|
||||
#include "ColorHelper.h"
|
||||
|
||||
using namespace winrt::TerminalApp;
|
||||
|
||||
// Method Description:
|
||||
// Determines whether or not a given color is light
|
||||
// Arguments:
|
||||
// - color: this color is going to be examined whether it
|
||||
// is light or not
|
||||
// Return Value:
|
||||
// - true if light, false if dark
|
||||
bool ColorHelper::IsBrightColor(const winrt::Windows::UI::Color& color)
|
||||
{
|
||||
// https://www.w3.org/TR/AERT#color-contrast
|
||||
auto brightness = (color.R * 299 + color.G * 587 + color.B * 114) / 1000.f;
|
||||
return brightness > 128.f;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Converts a rgb color to an hsl one
|
||||
// Arguments:
|
||||
// - color: the rgb color, which is going to be converted
|
||||
// Return Value:
|
||||
// - a hsl color with the following ranges
|
||||
// - H: [0.f -360.f]
|
||||
// - L: [0.f - 1.f] (rounded to the third decimal place)
|
||||
// - S: [0.f - 1.f] (rounded to the third decimal place)
|
||||
HSL ColorHelper::RgbToHsl(const winrt::Windows::UI::Color& color)
|
||||
{
|
||||
// https://www.rapidtables.com/convert/color/rgb-to-hsl.html
|
||||
auto epsilon = std::numeric_limits<float>::epsilon();
|
||||
auto r = color.R / 255.f;
|
||||
auto g = color.G / 255.f;
|
||||
auto b = color.B / 255.f;
|
||||
|
||||
auto max = std::max(r, std::max(g, b));
|
||||
auto min = std::min(r, std::min(g, b));
|
||||
|
||||
auto delta = max - min;
|
||||
|
||||
auto h = 0.f;
|
||||
auto s = 0.f;
|
||||
auto l = (max + min) / 2;
|
||||
|
||||
if (delta < epsilon || max < epsilon) /* delta == 0 || max == 0*/
|
||||
{
|
||||
l = std::roundf(l * 1000) / 1000;
|
||||
return HSL{ h, s, l };
|
||||
}
|
||||
|
||||
s = l > 0.5 ? delta / (2 - max - min) : delta / (max + min);
|
||||
|
||||
if (max - r < epsilon) // max == r
|
||||
{
|
||||
h = (g - b) / delta + (g < b ? 6 : 0);
|
||||
}
|
||||
else if (max - g < epsilon) // max == g
|
||||
{
|
||||
h = (b - r) / delta + 2;
|
||||
}
|
||||
else if (max - b < epsilon) // max == b
|
||||
{
|
||||
h = (r - g) / delta + 4;
|
||||
}
|
||||
|
||||
// three decimal places after the comma ought
|
||||
// to be enough for everybody - Bill Gates, 1981
|
||||
auto finalH = std::roundf(h * 60);
|
||||
auto finalS = std::roundf(s * 1000) / 1000;
|
||||
auto finalL = std::roundf(l * 1000) / 1000;
|
||||
|
||||
return HSL{ finalH, finalS, finalL };
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Converts a hsl color to rgb one
|
||||
// Arguments:
|
||||
// - color: the hsl color, which is going to be converted
|
||||
// Return Value:
|
||||
// - the rgb color (r,g,b - [0, 255] range)
|
||||
winrt::Windows::UI::Color ColorHelper::HslToRgb(const HSL& color)
|
||||
{
|
||||
auto epsilon = std::numeric_limits<float>::epsilon();
|
||||
|
||||
auto h = (color.H - 1.f > epsilon) ? color.H / 360.f : color.H;
|
||||
auto s = (color.S - 1.f > epsilon) ? color.S / 100.f : color.S;
|
||||
auto l = (color.L - 1.f > epsilon) ? color.L / 100.f : color.L;
|
||||
|
||||
auto r = l;
|
||||
auto g = l;
|
||||
auto b = l;
|
||||
|
||||
if (s > epsilon)
|
||||
{
|
||||
auto q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||
auto p = 2 * l - q;
|
||||
r = HueToRgb(p, q, h + 1.f / 3.f);
|
||||
g = HueToRgb(p, q, h);
|
||||
b = HueToRgb(p, q, h - 1.f / 3.f);
|
||||
}
|
||||
|
||||
auto finalR = static_cast<uint8_t>(std::roundf(r * 255));
|
||||
auto finalG = static_cast<uint8_t>(std::roundf(g * 255));
|
||||
auto finalB = static_cast<uint8_t>(std::roundf(b * 255));
|
||||
uint8_t finalA = 255; //opaque
|
||||
|
||||
return winrt::Windows::UI::ColorHelper::FromArgb(finalA, finalR, finalG, finalB);
|
||||
}
|
||||
|
||||
float ColorHelper::HueToRgb(float p, float q, float t)
|
||||
{
|
||||
auto epsilon = std::numeric_limits<float>::epsilon();
|
||||
|
||||
if (t < 0)
|
||||
t += 1;
|
||||
if (t > 1)
|
||||
t -= 1;
|
||||
if (t - (1.f / 6.f) < epsilon)
|
||||
return p + (q - p) * 6 * t;
|
||||
if (t - .5f < epsilon)
|
||||
return q;
|
||||
if (t - 2.f / 3.f < epsilon)
|
||||
return p + (q - p) * (2.f / 3.f - t) * 6;
|
||||
return p;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Lightens a color by a given amount
|
||||
// Arguments:
|
||||
// - color: the color which is going to be lightened
|
||||
// - amount: the lighten amount (0-100)
|
||||
// Return Value:
|
||||
// - the lightened color in RGB format
|
||||
winrt::Windows::UI::Color ColorHelper::Lighten(const winrt::Windows::UI::Color& color, float amount /* = 10.f*/)
|
||||
{
|
||||
auto hsl = RgbToHsl(color);
|
||||
hsl.L += amount / 100;
|
||||
hsl.L = std::clamp(hsl.L, 0.f, 1.f);
|
||||
return HslToRgb(hsl);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Darkens a color by a given amount
|
||||
// Arguments:
|
||||
// - color: the color which is going to be darkened
|
||||
// - amount: the darken amount (0-100)
|
||||
// Return Value:
|
||||
// - the darkened color in RGB format
|
||||
winrt::Windows::UI::Color ColorHelper::Darken(const winrt::Windows::UI::Color& color, float amount /* = 10.f*/)
|
||||
{
|
||||
auto hsl = RgbToHsl(color);
|
||||
hsl.L -= amount / 100;
|
||||
hsl.L = std::clamp(hsl.L, 0.f, 1.f);
|
||||
return HslToRgb(hsl);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Gets an accent color to a given color. Basically, generates
|
||||
// 16 shades of the color and finds the first which has a good
|
||||
// contrast according to https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef (WCAG Version 2)
|
||||
// Readability ratio of 3.5 seems to look quite nicely
|
||||
// Arguments:
|
||||
// - color: the color for which we need an accent
|
||||
// Return Value:
|
||||
// - the accent color in RGB format
|
||||
winrt::Windows::UI::Color ColorHelper::GetAccentColor(const winrt::Windows::UI::Color& color)
|
||||
{
|
||||
auto accentColor = RgbToHsl(color);
|
||||
|
||||
if (accentColor.S < 0.15)
|
||||
{
|
||||
accentColor.S = 0.15f;
|
||||
}
|
||||
|
||||
constexpr auto shadeCount = 16;
|
||||
constexpr auto shadeStep = 1.f / shadeCount;
|
||||
auto shades = std::map<float, HSL>();
|
||||
for (auto i = 0; i < 15; i++)
|
||||
{
|
||||
auto shade = HSL{ accentColor.H, accentColor.S, i * shadeStep };
|
||||
auto contrast = GetReadability(shade, accentColor);
|
||||
shades.insert(std::make_pair(contrast, shade));
|
||||
}
|
||||
|
||||
// 3f is quite nice if the whole non-client area is painted
|
||||
constexpr auto readability = 1.75f;
|
||||
for (auto shade : shades)
|
||||
{
|
||||
if (shade.first >= readability)
|
||||
{
|
||||
return HslToRgb(shade.second);
|
||||
}
|
||||
}
|
||||
return HslToRgb(shades.end()->second);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Gets the readability of two colors according to
|
||||
// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef (WCAG Version 2)
|
||||
// Arguments:
|
||||
// - firstColor: the first color for the readability check (hsl)
|
||||
// - secondColor: the second color for the readability check (hsl)
|
||||
// Return Value:
|
||||
// - the readability of the colors according to (WCAG Version 2)
|
||||
float ColorHelper::GetReadability(const HSL& first, const HSL& second)
|
||||
{
|
||||
return GetReadability(HslToRgb(first), HslToRgb(second));
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Gets the readability of two colors according to
|
||||
// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef (WCAG Version 2)
|
||||
// Arguments:
|
||||
// - firstColor: the first color for the readability check (rgb)
|
||||
// - secondColor: the second color for the readability check (rgb)
|
||||
// Return Value:
|
||||
// - the readability of the colors according to (WCAG Version 2)
|
||||
float ColorHelper::GetReadability(const winrt::Windows::UI::Color& first, const winrt::Windows::UI::Color& second)
|
||||
{
|
||||
auto l1 = GetLuminance(first);
|
||||
auto l2 = GetLuminance(second);
|
||||
|
||||
return (std::max(l1, l2) + 0.05f) / std::min(l1, l2) + 0.05f;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// Calculates the luminance of a given color according to
|
||||
// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
|
||||
// Arguments:
|
||||
// - color: its luminance is going to be calculated
|
||||
// Return Value:
|
||||
// - the luminance of the color
|
||||
float ColorHelper::GetLuminance(const winrt::Windows::UI::Color& color)
|
||||
{
|
||||
auto epsilon = std::numeric_limits<float>::epsilon();
|
||||
float R, G, B;
|
||||
auto RsRGB = color.R / 255.f;
|
||||
auto GsRGB = color.G / 255.f;
|
||||
auto BsRGB = color.B / 255.f;
|
||||
|
||||
if (RsRGB - 0.03928f <= epsilon)
|
||||
{
|
||||
R = RsRGB / 12.92f;
|
||||
}
|
||||
else
|
||||
{
|
||||
R = std::pow(((RsRGB + 0.055f) / 1.055f), 2.4f);
|
||||
}
|
||||
if (GsRGB - 0.03928f <= epsilon)
|
||||
{
|
||||
G = GsRGB / 12.92f;
|
||||
}
|
||||
else
|
||||
{
|
||||
G = std::pow(((GsRGB + 0.055f) / 1.055f), 2.4f);
|
||||
}
|
||||
if (BsRGB - 0.03928f <= epsilon)
|
||||
{
|
||||
B = BsRGB / 12.92f;
|
||||
}
|
||||
else
|
||||
{
|
||||
B = std::pow(((BsRGB + 0.055f) / 1.055f), 2.4f);
|
||||
}
|
||||
auto luminance = (0.2126f * R) + (0.7152f * G) + (0.0722f * B);
|
||||
return std::roundf(luminance * 10000) / 10000.f;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <winrt/Windows.UI.h>
|
||||
|
||||
namespace winrt::TerminalApp
|
||||
{
|
||||
class HSL
|
||||
{
|
||||
public:
|
||||
float H;
|
||||
float S;
|
||||
float L;
|
||||
};
|
||||
|
||||
class ColorHelper
|
||||
{
|
||||
public:
|
||||
static bool IsBrightColor(const Windows::UI::Color& color);
|
||||
static HSL RgbToHsl(const Windows::UI::Color& color);
|
||||
static Windows::UI::Color HslToRgb(const HSL& color);
|
||||
static Windows::UI::Color Lighten(const Windows::UI::Color& color, float amount = 10.f);
|
||||
static Windows::UI::Color Darken(const Windows::UI::Color& color, float amount = 10.f);
|
||||
static Windows::UI::Color GetAccentColor(const Windows::UI::Color& color);
|
||||
static float GetLuminance(const Windows::UI::Color& color);
|
||||
static float GetReadability(const Windows::UI::Color& first, const Windows::UI::Color& second);
|
||||
static float GetReadability(const HSL& first, const HSL& second);
|
||||
|
||||
private:
|
||||
static float HueToRgb(float p, float q, float t);
|
||||
};
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "CommandLinePaletteItem.h"
|
||||
#include <LibraryResources.h>
|
||||
|
||||
#include "CommandLinePaletteItem.g.cpp"
|
||||
|
||||
using namespace winrt;
|
||||
using namespace winrt::TerminalApp;
|
||||
using namespace winrt::Windows::UI::Core;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::System;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
CommandLinePaletteItem::CommandLinePaletteItem(const winrt::hstring& commandLine) :
|
||||
_CommandLine(commandLine)
|
||||
{
|
||||
Name(commandLine);
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "PaletteItem.h"
|
||||
#include "CommandLinePaletteItem.g.h"
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct CommandLinePaletteItem : CommandLinePaletteItemT<CommandLinePaletteItem, PaletteItem>
|
||||
{
|
||||
CommandLinePaletteItem() = default;
|
||||
CommandLinePaletteItem(const winrt::hstring& commandLine);
|
||||
|
||||
WINRT_PROPERTY(winrt::hstring, CommandLine);
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::TerminalApp::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(CommandLinePaletteItem);
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import "PaletteItem.idl";
|
||||
import "TabBase.idl";
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
[default_interface] runtimeclass CommandLinePaletteItem : PaletteItem
|
||||
{
|
||||
CommandLinePaletteItem(String commandLine);
|
||||
|
||||
String CommandLine { get; };
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,8 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "ActionPaletteItem.h"
|
||||
#include "TabPaletteItem.h"
|
||||
#include "CommandLinePaletteItem.h"
|
||||
#include "CommandPalette.h"
|
||||
#include "CommandPaletteItems.h"
|
||||
#include <LibraryResources.h>
|
||||
|
||||
#include "CommandPalette.g.cpp"
|
||||
@@ -233,9 +231,11 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
else if (_currentMode == CommandPaletteMode::ActionMode && filteredCommand != nullptr)
|
||||
{
|
||||
if (const auto actionPaletteItem{ filteredCommand.Item().try_as<winrt::TerminalApp::ActionPaletteItem>() })
|
||||
const auto item{ filteredCommand.Item() };
|
||||
if (item.Type() == PaletteItemType::Action)
|
||||
{
|
||||
PreviewAction.raise(*this, actionPaletteItem.Command());
|
||||
const auto actionPaletteItem{ winrt::get_self<ActionPaletteItem>(item) };
|
||||
PreviewAction.raise(*this, actionPaletteItem->Command());
|
||||
}
|
||||
}
|
||||
else if (_currentMode == CommandPaletteMode::CommandlineMode)
|
||||
@@ -555,10 +555,11 @@ namespace winrt::TerminalApp::implementation
|
||||
const auto enteredItem = listViewItem.Content();
|
||||
if (const auto filteredCommand{ enteredItem.try_as<winrt::TerminalApp::FilteredCommand>() })
|
||||
{
|
||||
if (const auto actionPaletteItem{ filteredCommand.Item().try_as<winrt::TerminalApp::ActionPaletteItem>() })
|
||||
const auto item{ filteredCommand.Item() };
|
||||
if (item.Type() == PaletteItemType::Action)
|
||||
{
|
||||
// immediately preview the hovered command
|
||||
PreviewAction.raise(*this, actionPaletteItem.Command());
|
||||
const auto actionPaletteItem{ winrt::get_self<ActionPaletteItem>(item) };
|
||||
PreviewAction.raise(*this, actionPaletteItem->Command());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -589,9 +590,11 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
if (_currentMode == CommandPaletteMode::ActionMode && filteredCommand)
|
||||
{
|
||||
if (const auto actionPaletteItem{ filteredCommand.Item().try_as<winrt::TerminalApp::ActionPaletteItem>() })
|
||||
const auto item{ filteredCommand.Item() };
|
||||
if (item.Type() == PaletteItemType::Action)
|
||||
{
|
||||
PreviewAction.raise(*this, actionPaletteItem.Command());
|
||||
const auto actionPaletteItem{ winrt::get_self<ActionPaletteItem>(item) };
|
||||
PreviewAction.raise(*this, actionPaletteItem->Command());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -617,7 +620,7 @@ namespace winrt::TerminalApp::implementation
|
||||
const auto selectedCommand = selectedList.GetAt(0);
|
||||
if (const auto filteredCmd = selectedCommand.try_as<TerminalApp::FilteredCommand>())
|
||||
{
|
||||
if (const auto paletteItem = filteredCmd.Item().try_as<TerminalApp::PaletteItem>())
|
||||
if (const auto paletteItem = filteredCmd.Item())
|
||||
{
|
||||
automationPeer.RaiseNotificationEvent(
|
||||
Automation::Peers::AutomationNotificationKind::ItemAdded,
|
||||
@@ -652,10 +655,13 @@ namespace winrt::TerminalApp::implementation
|
||||
if (_nestedActionStack.Size() > 0)
|
||||
{
|
||||
const auto newPreviousAction{ _nestedActionStack.GetAt(_nestedActionStack.Size() - 1) };
|
||||
const auto actionPaletteItem{ newPreviousAction.Item().try_as<winrt::TerminalApp::ActionPaletteItem>() };
|
||||
|
||||
ParentCommandName(actionPaletteItem.Command().Name());
|
||||
_updateCurrentNestedCommands(actionPaletteItem.Command());
|
||||
const auto item{ newPreviousAction.Item() };
|
||||
if (item.Type() == PaletteItemType::Action)
|
||||
{
|
||||
const auto actionPaletteItem{ winrt::get_self<ActionPaletteItem>(item) };
|
||||
ParentCommandName(actionPaletteItem->Command().Name());
|
||||
_updateCurrentNestedCommands(actionPaletteItem->Command());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -757,16 +763,19 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
else if (filteredCommand)
|
||||
{
|
||||
if (const auto actionPaletteItem{ filteredCommand.Item().try_as<winrt::TerminalApp::ActionPaletteItem>() })
|
||||
auto item{ filteredCommand.Item() };
|
||||
if (item.Type() == PaletteItemType::Action)
|
||||
{
|
||||
if (actionPaletteItem.Command().HasNestedCommands())
|
||||
const auto actionPaletteItem{ winrt::get_self<ActionPaletteItem>(item) };
|
||||
auto command{ actionPaletteItem->Command() };
|
||||
if (command.HasNestedCommands())
|
||||
{
|
||||
// If this Command had subcommands, then don't dispatch the
|
||||
// action. Instead, display a new list of commands for the user
|
||||
// to pick from.
|
||||
_nestedActionStack.Append(filteredCommand);
|
||||
ParentCommandName(actionPaletteItem.Command().Name());
|
||||
_updateCurrentNestedCommands(actionPaletteItem.Command());
|
||||
ParentCommandName(command.Name());
|
||||
_updateCurrentNestedCommands(command);
|
||||
|
||||
_updateUIForStackChange();
|
||||
}
|
||||
@@ -785,9 +794,9 @@ namespace winrt::TerminalApp::implementation
|
||||
// But make an exception for the Toggle Command Palette action: we don't want the dispatch
|
||||
// make the command palette - that was just closed - visible again.
|
||||
// All other actions can just be dispatched.
|
||||
if (actionPaletteItem.Command().ActionAndArgs().Action() != ShortcutAction::ToggleCommandPalette)
|
||||
if (command.ActionAndArgs().Action() != ShortcutAction::ToggleCommandPalette)
|
||||
{
|
||||
DispatchCommandRequested.raise(*this, actionPaletteItem.Command());
|
||||
DispatchCommandRequested.raise(*this, command);
|
||||
}
|
||||
|
||||
TraceLoggingWrite(
|
||||
@@ -837,9 +846,11 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
if (filteredCommand)
|
||||
{
|
||||
if (const auto tabPaletteItem{ filteredCommand.Item().try_as<winrt::TerminalApp::TabPaletteItem>() })
|
||||
const auto item{ filteredCommand.Item() };
|
||||
if (item.Type() == PaletteItemType::Tab)
|
||||
{
|
||||
if (const auto tab{ tabPaletteItem.Tab() })
|
||||
const auto tabPaletteItem{ winrt::get_self<TabPaletteItem>(item) };
|
||||
if (const auto tab{ tabPaletteItem->Tab() })
|
||||
{
|
||||
SwitchToTabRequested.raise(*this, tab);
|
||||
}
|
||||
@@ -867,9 +878,11 @@ namespace winrt::TerminalApp::implementation
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
|
||||
if (const auto commandLinePaletteItem{ filteredCommand.value().Item().try_as<winrt::TerminalApp::CommandLinePaletteItem>() })
|
||||
const auto item{ filteredCommand->Item() };
|
||||
if (item.Type() == PaletteItemType::CommandLine)
|
||||
{
|
||||
CommandLineExecutionRequested.raise(*this, commandLinePaletteItem.CommandLine());
|
||||
const auto commandLinePaletteItem{ winrt::get_self<CommandLinePaletteItem>(item) };
|
||||
CommandLineExecutionRequested.raise(*this, commandLinePaletteItem->CommandLine());
|
||||
_close();
|
||||
}
|
||||
}
|
||||
@@ -1059,7 +1072,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void CommandPalette::_bindTabs(
|
||||
const Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::TabBase>& source,
|
||||
const Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::Tab>& source,
|
||||
const Windows::Foundation::Collections::IVector<winrt::TerminalApp::FilteredCommand>& target)
|
||||
{
|
||||
target.Clear();
|
||||
@@ -1071,7 +1084,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
void CommandPalette::SetTabs(const Collections::IObservableVector<TabBase>& tabs, const Collections::IObservableVector<TabBase>& mruTabs)
|
||||
void CommandPalette::SetTabs(const Collections::IObservableVector<Tab>& tabs, const Collections::IObservableVector<Tab>& mruTabs)
|
||||
{
|
||||
_bindTabs(tabs, _tabActions);
|
||||
_bindTabs(mruTabs, _mruTabActions);
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::FilteredCommand> FilteredActions();
|
||||
|
||||
void SetTabs(const Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::TabBase>& tabs, const Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::TabBase>& mruTabs);
|
||||
void SetTabs(const Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::Tab>& tabs, const Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::Tab>& mruTabs);
|
||||
void SetActionMap(const Microsoft::Terminal::Settings::Model::IActionMapView& actionMap);
|
||||
|
||||
bool OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, const bool down);
|
||||
@@ -48,7 +48,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void EnableTabSearchMode();
|
||||
|
||||
til::property_changed_event PropertyChanged;
|
||||
til::typed_event<winrt::TerminalApp::CommandPalette, winrt::TerminalApp::TabBase> SwitchToTabRequested;
|
||||
til::typed_event<winrt::TerminalApp::CommandPalette, winrt::TerminalApp::Tab> SwitchToTabRequested;
|
||||
til::typed_event<winrt::TerminalApp::CommandPalette, winrt::hstring> CommandLineExecutionRequested;
|
||||
til::typed_event<winrt::TerminalApp::CommandPalette, Microsoft::Terminal::Settings::Model::Command> DispatchCommandRequested;
|
||||
til::typed_event<Windows::Foundation::IInspectable, Microsoft::Terminal::Settings::Model::Command> PreviewAction;
|
||||
@@ -135,7 +135,7 @@ namespace winrt::TerminalApp::implementation
|
||||
Microsoft::Terminal::Settings::Model::TabSwitcherMode _tabSwitcherMode;
|
||||
uint32_t _switcherStartIdx;
|
||||
|
||||
void _bindTabs(const Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::TabBase>& source, const Windows::Foundation::Collections::IVector<winrt::TerminalApp::FilteredCommand>& target);
|
||||
void _bindTabs(const Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::Tab>& source, const Windows::Foundation::Collections::IVector<winrt::TerminalApp::FilteredCommand>& target);
|
||||
void _anchorKeyUpHandler();
|
||||
|
||||
winrt::Windows::UI::Xaml::Controls::ListView::SizeChanged_revoker _sizeChangedRevoker;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "TabBase.idl";
|
||||
import "Tab.idl";
|
||||
import "HighlightedTextControl.idl";
|
||||
import "FilteredCommand.idl";
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace TerminalApp
|
||||
|
||||
Windows.Foundation.Collections.IObservableVector<FilteredCommand> FilteredActions { get; };
|
||||
|
||||
void SetTabs(Windows.Foundation.Collections.IObservableVector<TabBase> tabs, Windows.Foundation.Collections.IObservableVector<TabBase> mruTabs);
|
||||
void SetTabs(Windows.Foundation.Collections.IObservableVector<Tab> tabs, Windows.Foundation.Collections.IObservableVector<Tab> mruTabs);
|
||||
|
||||
void SetActionMap(Microsoft.Terminal.Settings.Model.IActionMapView actionMap);
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace TerminalApp
|
||||
void EnableTabSwitcherMode(UInt32 startIdx, Microsoft.Terminal.Settings.Model.TabSwitcherMode tabSwitcherMode);
|
||||
void EnableTabSearchMode();
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<CommandPalette, TabBase> SwitchToTabRequested;
|
||||
event Windows.Foundation.TypedEventHandler<CommandPalette, Tab> SwitchToTabRequested;
|
||||
event Windows.Foundation.TypedEventHandler<CommandPalette, Microsoft.Terminal.Settings.Model.Command> DispatchCommandRequested;
|
||||
event Windows.Foundation.TypedEventHandler<CommandPalette, String> CommandLineExecutionRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Microsoft.Terminal.Settings.Model.Command> PreviewAction;
|
||||
|
||||
@@ -44,6 +44,12 @@
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource CardStrokeColorDefaultBrush}" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SubtitleTextStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="10" />
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemBaseMediumColor}" />
|
||||
</Style>
|
||||
|
||||
<DataTemplate x:Key="ListItemTemplate"
|
||||
x:DataType="local:FilteredCommand">
|
||||
<ListViewItem HorizontalContentAlignment="Stretch"
|
||||
@@ -71,10 +77,19 @@
|
||||
Height="16"
|
||||
Content="{x:Bind Item.ResolvedIcon, Mode=OneWay}" />
|
||||
|
||||
<local:HighlightedTextControl Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
Text="{x:Bind HighlightedName, Mode=OneWay}" />
|
||||
<StackPanel Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
Orientation="Vertical">
|
||||
<local:HighlightedTextControl HorizontalAlignment="Left"
|
||||
HighlightedRuns="{x:Bind NameHighlights, Mode=OneWay}"
|
||||
Text="{x:Bind Item.Name, Mode=OneWay}" />
|
||||
<local:HighlightedTextControl HorizontalAlignment="Left"
|
||||
HighlightedRuns="{x:Bind SubtitleHighlights, Mode=OneWay}"
|
||||
Text="{x:Bind Item.Subtitle, Mode=OneWay}"
|
||||
TextBlockStyle="{StaticResource SubtitleTextStyle}"
|
||||
Visibility="{x:Bind HasSubtitle, Mode=OneWay}" />
|
||||
|
||||
</StackPanel>
|
||||
<!--
|
||||
The block for the key chord is only visible
|
||||
when there's actual text set as the label.
|
||||
@@ -121,9 +136,19 @@
|
||||
Height="16"
|
||||
Content="{x:Bind Item.ResolvedIcon, Mode=OneWay}" />
|
||||
|
||||
<local:HighlightedTextControl Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
Text="{x:Bind HighlightedName, Mode=OneWay}" />
|
||||
<StackPanel Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
Orientation="Vertical">
|
||||
<local:HighlightedTextControl HorizontalAlignment="Left"
|
||||
HighlightedRuns="{x:Bind NameHighlights, Mode=OneWay}"
|
||||
Text="{x:Bind Item.Name, Mode=OneWay}" />
|
||||
<local:HighlightedTextControl HorizontalAlignment="Left"
|
||||
HighlightedRuns="{x:Bind SubtitleHighlights, Mode=OneWay}"
|
||||
Text="{x:Bind Item.Subtitle, Mode=OneWay}"
|
||||
TextBlockStyle="{StaticResource SubtitleTextStyle}"
|
||||
Visibility="{x:Bind HasSubtitle, Mode=OneWay}" />
|
||||
|
||||
</StackPanel>
|
||||
|
||||
<!--
|
||||
The block for the key chord is only visible
|
||||
@@ -192,7 +217,8 @@
|
||||
|
||||
<local:HighlightedTextControl Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
Text="{x:Bind HighlightedName, Mode=OneWay}" />
|
||||
HighlightedRuns="{x:Bind NameHighlights, Mode=OneWay}"
|
||||
Text="{x:Bind Item.Name, Mode=OneWay}" />
|
||||
|
||||
<StackPanel Grid.Column="2"
|
||||
HorizontalAlignment="Right"
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "TabPaletteItem.h"
|
||||
#include "TerminalTab.h"
|
||||
#include "Tab.h"
|
||||
|
||||
#include <LibraryResources.h>
|
||||
|
||||
#include "TabPaletteItem.g.cpp"
|
||||
#include "CommandPaletteItems.h"
|
||||
|
||||
using namespace winrt;
|
||||
using namespace winrt::TerminalApp;
|
||||
@@ -19,42 +19,31 @@ using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
TabPaletteItem::TabPaletteItem(const winrt::TerminalApp::TabBase& tab) :
|
||||
_tab(tab)
|
||||
TabPaletteItem::TabPaletteItem(const winrt::TerminalApp::Tab& tab) :
|
||||
_tab{ tab }
|
||||
{
|
||||
Name(tab.Title());
|
||||
Icon(tab.Icon());
|
||||
|
||||
_tabChangedRevoker = tab.PropertyChanged(winrt::auto_revoke, [weakThis{ get_weak() }](auto& sender, auto& e) {
|
||||
auto item{ weakThis.get() };
|
||||
auto senderTab{ sender.try_as<winrt::TerminalApp::TabBase>() };
|
||||
|
||||
if (item && senderTab)
|
||||
_tabChangedRevoker = tab.PropertyChanged(winrt::auto_revoke, [=](auto& sender, auto& e) {
|
||||
if (auto senderTab{ sender.try_as<winrt::TerminalApp::Tab>() })
|
||||
{
|
||||
auto changedProperty = e.PropertyName();
|
||||
if (changedProperty == L"Title")
|
||||
{
|
||||
item->Name(senderTab.Title());
|
||||
BaseRaisePropertyChanged(L"Name");
|
||||
}
|
||||
else if (changedProperty == L"Icon")
|
||||
{
|
||||
item->Icon(senderTab.Icon());
|
||||
BaseRaisePropertyChanged(L"Icon");
|
||||
InvalidateResolvedIcon();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (const auto terminalTab{ tab.try_as<winrt::TerminalApp::TerminalTab>() })
|
||||
if (const auto status = tab.TabStatus())
|
||||
{
|
||||
const auto status = terminalTab.TabStatus();
|
||||
TabStatus(status);
|
||||
|
||||
_tabStatusChangedRevoker = status.PropertyChanged(winrt::auto_revoke, [weakThis{ get_weak() }](auto& /*sender*/, auto& /*e*/) {
|
||||
_tabStatusChangedRevoker = status.PropertyChanged(winrt::auto_revoke, [=](auto& /*sender*/, auto& /*e*/) {
|
||||
// Sometimes nested bindings do not get updated,
|
||||
// thus let's notify property changed on TabStatus when one of its properties changes
|
||||
if (auto item{ weakThis.get() })
|
||||
{
|
||||
item->PropertyChanged.raise(*item, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"TabStatus" });
|
||||
}
|
||||
BaseRaisePropertyChanged(L"TabStatus");
|
||||
});
|
||||
}
|
||||
}
|
||||
159
src/cascadia/TerminalApp/CommandPaletteItems.h
Normal file
159
src/cascadia/TerminalApp/CommandPaletteItems.h
Normal file
@@ -0,0 +1,159 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BasePaletteItem.h"
|
||||
#include "TabPaletteItem.g.h"
|
||||
|
||||
#include "../inc/cppwinrt_utils.h"
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct ActionPaletteItem :
|
||||
public winrt::implements<ActionPaletteItem, IPaletteItem, winrt::Windows::UI::Xaml::Data::INotifyPropertyChanged>,
|
||||
BasePaletteItem<ActionPaletteItem, winrt::TerminalApp::PaletteItemType::Action>
|
||||
{
|
||||
ActionPaletteItem(const Microsoft::Terminal::Settings::Model::Command& command, const winrt::hstring keyChordText) :
|
||||
_Command{ command }, _name{ command.Name() }, _keyChordText{ keyChordText }
|
||||
{
|
||||
static bool shouldShowSubtitles = [] {
|
||||
try
|
||||
{
|
||||
const auto context{ winrt::Windows::ApplicationModel::Resources::Core::ResourceContext::GetForViewIndependentUse() };
|
||||
const auto qualifiers{ context.QualifierValues() };
|
||||
if (const auto language{ qualifiers.TryLookup(L"language") })
|
||||
{
|
||||
return !til::starts_with_insensitive_ascii(*language, L"en-");
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_CAUGHT_EXCEPTION();
|
||||
}
|
||||
return false;
|
||||
}();
|
||||
|
||||
if (shouldShowSubtitles)
|
||||
{
|
||||
const auto subtitle = _Command.LanguageNeutralName();
|
||||
if (subtitle != _name)
|
||||
{
|
||||
_subtitle = std::move(subtitle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
winrt::hstring Name()
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
winrt::hstring Subtitle()
|
||||
{
|
||||
return _subtitle;
|
||||
}
|
||||
|
||||
winrt::hstring KeyChordText()
|
||||
{
|
||||
return _keyChordText;
|
||||
}
|
||||
|
||||
winrt::hstring Icon()
|
||||
{
|
||||
return _Command.IconPath();
|
||||
}
|
||||
|
||||
WINRT_PROPERTY(Microsoft::Terminal::Settings::Model::Command, Command, nullptr);
|
||||
|
||||
private:
|
||||
Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker _commandChangedRevoker;
|
||||
winrt::hstring _name;
|
||||
winrt::hstring _subtitle;
|
||||
winrt::hstring _keyChordText;
|
||||
};
|
||||
|
||||
struct CommandLinePaletteItem :
|
||||
public winrt::implements<CommandLinePaletteItem, IPaletteItem, winrt::Windows::UI::Xaml::Data::INotifyPropertyChanged>,
|
||||
BasePaletteItem<CommandLinePaletteItem, winrt::TerminalApp::PaletteItemType::CommandLine>
|
||||
{
|
||||
CommandLinePaletteItem(const winrt::hstring& commandLine) :
|
||||
_CommandLine{ commandLine } {}
|
||||
|
||||
winrt::hstring Name()
|
||||
{
|
||||
return _CommandLine;
|
||||
}
|
||||
|
||||
winrt::hstring Subtitle()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
winrt::hstring KeyChordText()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
winrt::hstring Icon()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
WINRT_PROPERTY(winrt::hstring, CommandLine);
|
||||
};
|
||||
|
||||
struct TabPaletteItem :
|
||||
public TabPaletteItemT<TabPaletteItem>,
|
||||
BasePaletteItem<TabPaletteItem, winrt::TerminalApp::PaletteItemType::Tab>
|
||||
{
|
||||
TabPaletteItem(const winrt::TerminalApp::Tab& tab);
|
||||
|
||||
winrt::TerminalApp::Tab Tab() const noexcept
|
||||
{
|
||||
return _tab.get();
|
||||
}
|
||||
|
||||
winrt::hstring Name()
|
||||
{
|
||||
if (auto tab = _tab.get())
|
||||
{
|
||||
return tab.Title();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
winrt::hstring Subtitle()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
winrt::hstring KeyChordText()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
winrt::hstring Icon()
|
||||
{
|
||||
if (auto tab = _tab.get())
|
||||
{
|
||||
return tab.Icon();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
winrt::TerminalApp::TerminalTabStatus TabStatus()
|
||||
{
|
||||
if (auto tab = _tab.get())
|
||||
{
|
||||
return tab.TabStatus();
|
||||
}
|
||||
return { nullptr };
|
||||
}
|
||||
|
||||
private:
|
||||
winrt::weak_ref<winrt::TerminalApp::Tab> _tab;
|
||||
Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker _tabChangedRevoker;
|
||||
Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker _tabStatusChangedRevoker;
|
||||
};
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include "pch.h"
|
||||
#include "CommandPalette.h"
|
||||
#include "HighlightedText.h"
|
||||
#include <LibraryResources.h>
|
||||
#include "fzf/fzf.h"
|
||||
|
||||
@@ -20,32 +19,23 @@ using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
// This class is a wrapper of PaletteItem, that is used as an item of a filterable list in CommandPalette.
|
||||
// This class is a wrapper of IPaletteItem, that is used as an item of a filterable list in CommandPalette.
|
||||
// It manages a highlighted text that is computed by matching search filter characters to item name
|
||||
FilteredCommand::FilteredCommand(const winrt::TerminalApp::PaletteItem& item)
|
||||
FilteredCommand::FilteredCommand(const winrt::TerminalApp::IPaletteItem& item) :
|
||||
_Item{ item }, _Weight{ 0 }
|
||||
{
|
||||
// Actually implement the ctor in _constructFilteredCommand
|
||||
_constructFilteredCommand(item);
|
||||
}
|
||||
|
||||
// We need to actually implement the ctor in a separate helper. This is
|
||||
// because we have a FilteredTask class which derives from FilteredCommand.
|
||||
// HOWEVER, for cppwinrt ~ r e a s o n s ~, it doesn't actually derive from
|
||||
// FilteredCommand directly, so we can't just use the FilteredCommand ctor
|
||||
// directly in the base class.
|
||||
void FilteredCommand::_constructFilteredCommand(const winrt::TerminalApp::PaletteItem& item)
|
||||
{
|
||||
_Item = item;
|
||||
_Weight = 0;
|
||||
|
||||
_update();
|
||||
|
||||
// Recompute the highlighted name if the item name changes
|
||||
_itemChangedRevoker = _Item.PropertyChanged(winrt::auto_revoke, [weakThis{ get_weak() }](auto& /*sender*/, auto& e) {
|
||||
auto filteredCommand{ weakThis.get() };
|
||||
if (filteredCommand && e.PropertyName() == L"Name")
|
||||
// Our Item will not change, so we don't need to update the revoker if it does.
|
||||
_itemChangedRevoker = _Item.as<winrt::Windows::UI::Xaml::Data::INotifyPropertyChanged>().PropertyChanged(winrt::auto_revoke, [=](auto& /*sender*/, auto& e) {
|
||||
const auto property{ e.PropertyName() };
|
||||
if (property == L"Name")
|
||||
{
|
||||
filteredCommand->_update();
|
||||
_update();
|
||||
}
|
||||
else if (property == L"Subtitle")
|
||||
{
|
||||
_update();
|
||||
PropertyChanged.raise(*this, winrt::Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"HasSubtitle" });
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -61,49 +51,63 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
void FilteredCommand::_update()
|
||||
bool FilteredCommand::HasSubtitle()
|
||||
{
|
||||
std::vector<winrt::TerminalApp::HighlightedTextSegment> segments;
|
||||
const auto commandName = _Item.Name();
|
||||
return !_Item.Subtitle().empty();
|
||||
}
|
||||
|
||||
static std::tuple<std::vector<winrt::TerminalApp::HighlightedRun>, int32_t> _matchedSegmentsAndWeight(const std::shared_ptr<fzf::matcher::Pattern>& pattern, const winrt::hstring& haystack)
|
||||
{
|
||||
std::vector<winrt::TerminalApp::HighlightedRun> segments;
|
||||
int32_t weight = 0;
|
||||
|
||||
if (!_pattern || _pattern->terms.empty())
|
||||
if (pattern && !pattern->terms.empty())
|
||||
{
|
||||
segments.emplace_back(winrt::TerminalApp::HighlightedTextSegment(commandName, false));
|
||||
if (auto match = fzf::matcher::Match(haystack, *pattern.get()); match)
|
||||
{
|
||||
auto& matchResult = *match;
|
||||
weight = matchResult.Score;
|
||||
segments.resize(matchResult.Runs.size());
|
||||
std::transform(matchResult.Runs.begin(), matchResult.Runs.end(), segments.begin(), [](auto&& run) -> winrt::TerminalApp::HighlightedRun {
|
||||
return { run.Start, run.End };
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (auto match = fzf::matcher::Match(commandName, *_pattern.get()); !match)
|
||||
return { std::move(segments), weight };
|
||||
}
|
||||
|
||||
void FilteredCommand::_update()
|
||||
{
|
||||
auto itemName = _Item.Name();
|
||||
auto [segments, weight] = _matchedSegmentsAndWeight(_pattern, itemName);
|
||||
decltype(segments) subtitleSegments;
|
||||
|
||||
if (HasSubtitle())
|
||||
{
|
||||
segments.emplace_back(winrt::TerminalApp::HighlightedTextSegment(commandName, false));
|
||||
auto itemSubtitle = _Item.Subtitle();
|
||||
int32_t subtitleWeight = 0;
|
||||
std::tie(subtitleSegments, subtitleWeight) = _matchedSegmentsAndWeight(_pattern, itemSubtitle);
|
||||
weight = std::max(weight, subtitleWeight);
|
||||
}
|
||||
|
||||
if (segments.empty())
|
||||
{
|
||||
NameHighlights(nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& matchResult = *match;
|
||||
weight = matchResult.Score;
|
||||
|
||||
size_t lastPos = 0;
|
||||
for (const auto& run : matchResult.Runs)
|
||||
{
|
||||
const auto& [start, end] = run;
|
||||
if (start > lastPos)
|
||||
{
|
||||
hstring nonMatch{ til::safe_slice_abs(commandName, lastPos, start) };
|
||||
segments.emplace_back(winrt::TerminalApp::HighlightedTextSegment(nonMatch, false));
|
||||
}
|
||||
|
||||
hstring matchSeg{ til::safe_slice_abs(commandName, start, end + 1) };
|
||||
segments.emplace_back(winrt::TerminalApp::HighlightedTextSegment(matchSeg, true));
|
||||
|
||||
lastPos = end + 1;
|
||||
}
|
||||
|
||||
if (lastPos < commandName.size())
|
||||
{
|
||||
hstring tail{ til::safe_slice_abs(commandName, lastPos, SIZE_T_MAX) };
|
||||
segments.emplace_back(winrt::TerminalApp::HighlightedTextSegment(tail, false));
|
||||
}
|
||||
NameHighlights(winrt::single_threaded_vector(std::move(segments)));
|
||||
}
|
||||
|
||||
if (subtitleSegments.empty())
|
||||
{
|
||||
SubtitleHighlights(nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
SubtitleHighlights(winrt::single_threaded_vector(std::move(subtitleSegments)));
|
||||
}
|
||||
|
||||
HighlightedName(winrt::make<HighlightedText>(winrt::single_threaded_observable_vector(std::move(segments))));
|
||||
Weight(weight);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,19 +18,19 @@ namespace winrt::TerminalApp::implementation
|
||||
struct FilteredCommand : FilteredCommandT<FilteredCommand>
|
||||
{
|
||||
FilteredCommand() = default;
|
||||
FilteredCommand(const winrt::TerminalApp::PaletteItem& item);
|
||||
FilteredCommand(const winrt::TerminalApp::IPaletteItem& item);
|
||||
|
||||
virtual void UpdateFilter(std::shared_ptr<fzf::matcher::Pattern> pattern);
|
||||
void UpdateFilter(std::shared_ptr<fzf::matcher::Pattern> pattern);
|
||||
|
||||
static int Compare(const winrt::TerminalApp::FilteredCommand& first, const winrt::TerminalApp::FilteredCommand& second);
|
||||
|
||||
til::property_changed_event PropertyChanged;
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::TerminalApp::PaletteItem, Item, PropertyChanged.raise, nullptr);
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::TerminalApp::HighlightedText, HighlightedName, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(int, Weight, PropertyChanged.raise);
|
||||
bool HasSubtitle();
|
||||
|
||||
protected:
|
||||
void _constructFilteredCommand(const winrt::TerminalApp::PaletteItem& item);
|
||||
til::property_changed_event PropertyChanged;
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::TerminalApp::IPaletteItem, Item, PropertyChanged.raise, nullptr);
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::Windows::Foundation::Collections::IVector<winrt::TerminalApp::HighlightedRun>, NameHighlights, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::Windows::Foundation::Collections::IVector<winrt::TerminalApp::HighlightedRun>, SubtitleHighlights, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(int, Weight, PropertyChanged.raise);
|
||||
|
||||
private:
|
||||
std::shared_ptr<fzf::matcher::Pattern> _pattern;
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "PaletteItem.idl";
|
||||
import "IPaletteItem.idl";
|
||||
import "HighlightedTextControl.idl";
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
[default_interface] unsealed runtimeclass FilteredCommand : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
runtimeclass FilteredCommand : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
FilteredCommand();
|
||||
FilteredCommand(PaletteItem item);
|
||||
FilteredCommand(IPaletteItem item);
|
||||
|
||||
PaletteItem Item { get; };
|
||||
HighlightedText HighlightedName { get; };
|
||||
IPaletteItem Item { get; };
|
||||
IVector<HighlightedRun> NameHighlights { get; };
|
||||
IVector<HighlightedRun> SubtitleHighlights { get; };
|
||||
Boolean HasSubtitle { get; };
|
||||
Int32 Weight;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "HighlightedText.h"
|
||||
#include "HighlightedTextSegment.g.cpp"
|
||||
#include "HighlightedText.g.cpp"
|
||||
|
||||
using namespace winrt;
|
||||
using namespace winrt::TerminalApp;
|
||||
using namespace winrt::Windows::UI::Core;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::System;
|
||||
using namespace winrt::Windows::UI::Text;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
HighlightedTextSegment::HighlightedTextSegment(const winrt::hstring& textSegment, bool isHighlighted) :
|
||||
_TextSegment(textSegment),
|
||||
_IsHighlighted(isHighlighted)
|
||||
{
|
||||
}
|
||||
|
||||
HighlightedText::HighlightedText(const Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::HighlightedTextSegment>& segments) :
|
||||
_Segments(segments)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "HighlightedTextSegment.g.h"
|
||||
#include "HighlightedText.g.h"
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct HighlightedTextSegment : HighlightedTextSegmentT<HighlightedTextSegment>
|
||||
{
|
||||
HighlightedTextSegment() = default;
|
||||
HighlightedTextSegment(const winrt::hstring& text, bool isHighlighted);
|
||||
|
||||
til::property_changed_event PropertyChanged;
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, TextSegment, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, IsHighlighted, PropertyChanged.raise);
|
||||
};
|
||||
|
||||
struct HighlightedText : HighlightedTextT<HighlightedText>
|
||||
{
|
||||
HighlightedText() = default;
|
||||
HighlightedText(const Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::HighlightedTextSegment>& segments);
|
||||
|
||||
til::property_changed_event PropertyChanged;
|
||||
WINRT_OBSERVABLE_PROPERTY(Windows::Foundation::Collections::IObservableVector<winrt::TerminalApp::HighlightedTextSegment>, Segments, PropertyChanged.raise);
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::TerminalApp::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(HighlightedTextSegment);
|
||||
BASIC_FACTORY(HighlightedText);
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
[default_interface] runtimeclass HighlightedTextSegment : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
HighlightedTextSegment();
|
||||
HighlightedTextSegment(String text, Boolean isMatched);
|
||||
|
||||
String TextSegment { get; };
|
||||
Boolean IsHighlighted { get; };
|
||||
}
|
||||
|
||||
[default_interface] runtimeclass HighlightedText : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
HighlightedText();
|
||||
HighlightedText(Windows.Foundation.Collections.IObservableVector<HighlightedTextSegment> segments);
|
||||
|
||||
Windows.Foundation.Collections.IObservableVector<HighlightedTextSegment> Segments;
|
||||
}
|
||||
}
|
||||
@@ -22,70 +22,152 @@ namespace winrt::TerminalApp::implementation
|
||||
// Our control exposes a "Text" property to be used with Data Binding
|
||||
// To allow this we need to register a Dependency Property Identifier to be used by the property system
|
||||
// (https://docs.microsoft.com/en-us/windows/uwp/xaml-platform/custom-dependency-properties)
|
||||
DependencyProperty HighlightedTextControl::_textProperty = DependencyProperty::Register(
|
||||
L"Text",
|
||||
xaml_typename<winrt::TerminalApp::HighlightedText>(),
|
||||
xaml_typename<winrt::TerminalApp::HighlightedTextControl>(),
|
||||
PropertyMetadata(nullptr, HighlightedTextControl::_onTextChanged));
|
||||
DependencyProperty HighlightedTextControl::_TextProperty{ nullptr };
|
||||
DependencyProperty HighlightedTextControl::_HighlightedRunsProperty{ nullptr };
|
||||
DependencyProperty HighlightedTextControl::_TextBlockStyleProperty{ nullptr };
|
||||
DependencyProperty HighlightedTextControl::_HighlightedRunStyleProperty{ nullptr };
|
||||
|
||||
HighlightedTextControl::HighlightedTextControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
_InitializeProperties();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Returns the Identifier of the "Text" dependency property
|
||||
DependencyProperty HighlightedTextControl::TextProperty()
|
||||
void HighlightedTextControl::_InitializeProperties()
|
||||
{
|
||||
return _textProperty;
|
||||
static auto [[maybe_unused]] registered = [] {
|
||||
_TextProperty = DependencyProperty::Register(
|
||||
L"Text",
|
||||
xaml_typename<winrt::hstring>(),
|
||||
xaml_typename<winrt::TerminalApp::HighlightedTextControl>(),
|
||||
PropertyMetadata(nullptr, HighlightedTextControl::_onPropertyChanged));
|
||||
|
||||
_HighlightedRunsProperty = DependencyProperty::Register(
|
||||
L"HighlightedRuns",
|
||||
xaml_typename<winrt::Windows::Foundation::Collections::IVector<winrt::TerminalApp::HighlightedRun>>(),
|
||||
xaml_typename<winrt::TerminalApp::HighlightedTextControl>(),
|
||||
PropertyMetadata(nullptr, HighlightedTextControl::_onPropertyChanged));
|
||||
|
||||
_TextBlockStyleProperty = DependencyProperty::Register(
|
||||
L"TextBlockStyle",
|
||||
xaml_typename<winrt::Windows::UI::Xaml::Style>(),
|
||||
xaml_typename<winrt::TerminalApp::HighlightedTextControl>(),
|
||||
PropertyMetadata{ nullptr });
|
||||
|
||||
_HighlightedRunStyleProperty = DependencyProperty::Register(
|
||||
L"HighlightedRunStyle",
|
||||
xaml_typename<winrt::Windows::UI::Xaml::Style>(),
|
||||
xaml_typename<winrt::TerminalApp::HighlightedTextControl>(),
|
||||
PropertyMetadata(nullptr, HighlightedTextControl::_onPropertyChanged));
|
||||
|
||||
return true;
|
||||
}();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Returns the TextBlock view used to render the highlighted text
|
||||
// Can be used when the Text property change is triggered by the event system to update the view
|
||||
// We need to expose it rather than simply bind a data source because we update the runs in code-behind
|
||||
Controls::TextBlock HighlightedTextControl::TextView()
|
||||
{
|
||||
return _textView();
|
||||
}
|
||||
|
||||
winrt::TerminalApp::HighlightedText HighlightedTextControl::Text()
|
||||
{
|
||||
return winrt::unbox_value<winrt::TerminalApp::HighlightedText>(GetValue(_textProperty));
|
||||
}
|
||||
|
||||
void HighlightedTextControl::Text(const winrt::TerminalApp::HighlightedText& value)
|
||||
{
|
||||
SetValue(_textProperty, winrt::box_value(value));
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - This callback is triggered when the Text property is changed. Responsible for updating the view
|
||||
// Arguments:
|
||||
// - o - dependency object that was modified, expected to be an instance of this control
|
||||
// - e - event arguments of the property changed event fired by the event system upon Text property change.
|
||||
// The new value is expected to be an instance of HighlightedText
|
||||
void HighlightedTextControl::_onTextChanged(const DependencyObject& o, const DependencyPropertyChangedEventArgs& e)
|
||||
void HighlightedTextControl::_onPropertyChanged(const DependencyObject& o, const DependencyPropertyChangedEventArgs& /*e*/)
|
||||
{
|
||||
const auto control = o.try_as<winrt::TerminalApp::HighlightedTextControl>();
|
||||
const auto highlightedText = e.NewValue().try_as<winrt::TerminalApp::HighlightedText>();
|
||||
|
||||
if (control && highlightedText)
|
||||
if (control)
|
||||
{
|
||||
// Replace all the runs on the TextBlock
|
||||
// Use IsHighlighted to decide if the run should be highlighted.
|
||||
// To do - export the highlighting style into XAML
|
||||
const auto inlinesCollection = control.TextView().Inlines();
|
||||
inlinesCollection.Clear();
|
||||
winrt::get_self<HighlightedTextControl>(control)->_updateTextAndStyle();
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& match : highlightedText.Segments())
|
||||
void HighlightedTextControl::OnApplyTemplate()
|
||||
{
|
||||
_updateTextAndStyle();
|
||||
}
|
||||
|
||||
static void _applyStyleToObject(const winrt::Windows::UI::Xaml::Style& style, const winrt::Windows::UI::Xaml::DependencyObject& object)
|
||||
{
|
||||
if (!style)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static const auto fontWeightProperty{ winrt::Windows::UI::Xaml::Documents::TextElement::FontWeightProperty() };
|
||||
|
||||
const auto setters{ style.Setters() };
|
||||
for (auto&& setterBase : setters)
|
||||
{
|
||||
const auto setter = setterBase.as<winrt::Windows::UI::Xaml::Setter>();
|
||||
const auto property = setter.Property();
|
||||
auto value = setter.Value();
|
||||
|
||||
if (property == fontWeightProperty) [[unlikely]]
|
||||
{
|
||||
const auto matchText = match.TextSegment();
|
||||
const auto fontWeight = match.IsHighlighted() ? FontWeights::Bold() : FontWeights::Normal();
|
||||
// BODGY - The XAML compiler emits a boxed int32, but the dependency property
|
||||
// here expects a boxed FontWeight (which also requires a u16. heh.)
|
||||
// FontWeight is one of the few properties that is broken like this, and on Run it's the
|
||||
// only one... so we can trivially check this case.
|
||||
const auto weight{ winrt::unbox_value_or<int32_t>(value, static_cast<int32_t>(400)) };
|
||||
value = winrt::box_value(winrt::Windows::UI::Text::FontWeight{ static_cast<uint16_t>(weight) });
|
||||
}
|
||||
|
||||
object.SetValue(property, value);
|
||||
}
|
||||
}
|
||||
|
||||
void HighlightedTextControl::_updateTextAndStyle()
|
||||
{
|
||||
const auto textBlock = GetTemplateChild(L"TextView").try_as<winrt::Windows::UI::Xaml::Controls::TextBlock>();
|
||||
if (!textBlock)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto text = Text();
|
||||
const auto runs = HighlightedRuns();
|
||||
|
||||
const auto inlinesCollection = textBlock.Inlines();
|
||||
inlinesCollection.Clear();
|
||||
|
||||
// The code below constructs local hstring instances because hstring is required to be null-terminated
|
||||
// and slicing _does not_ guarantee null termination. Passing a sliced wstring_view directly into run.Text()
|
||||
// (which is a winrt::param::hstring--different thing!--will result in an exception when the sliced portion
|
||||
// is not null-terminated.
|
||||
if (!text.empty())
|
||||
{
|
||||
size_t lastPos = 0;
|
||||
if (runs && runs.Size())
|
||||
{
|
||||
const auto runStyle = HighlightedRunStyle();
|
||||
|
||||
for (const auto& [start, end] : runs)
|
||||
{
|
||||
if (start > lastPos)
|
||||
{
|
||||
const hstring nonMatch{ til::safe_slice_abs(text, lastPos, static_cast<size_t>(start)) };
|
||||
Documents::Run run;
|
||||
run.Text(nonMatch);
|
||||
inlinesCollection.Append(run);
|
||||
}
|
||||
|
||||
const hstring matchSeg{ til::safe_slice_abs(text, static_cast<size_t>(start), static_cast<size_t>(end + 1)) };
|
||||
Documents::Run run;
|
||||
run.Text(matchSeg);
|
||||
|
||||
if (runStyle) [[unlikely]]
|
||||
{
|
||||
_applyStyleToObject(runStyle, run);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Default style: bold
|
||||
run.FontWeight(FontWeights::Bold());
|
||||
}
|
||||
inlinesCollection.Append(run);
|
||||
|
||||
lastPos = static_cast<size_t>(end + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// This will also be true if there are no runs at all
|
||||
if (lastPos < text.size())
|
||||
{
|
||||
// checking lastPos here prevents a needless deep copy of the whole text in the no-match case
|
||||
const hstring tail{ lastPos == 0 ? text : hstring{ til::safe_slice_abs(text, lastPos, SIZE_T_MAX) } };
|
||||
Documents::Run run;
|
||||
run.Text(matchText);
|
||||
run.FontWeight(fontWeight);
|
||||
run.Text(tail);
|
||||
inlinesCollection.Append(run);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "winrt/Microsoft.UI.Xaml.Controls.h"
|
||||
|
||||
#include "HighlightedTextControl.g.h"
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
@@ -13,16 +11,17 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
HighlightedTextControl();
|
||||
|
||||
static Windows::UI::Xaml::DependencyProperty TextProperty();
|
||||
void OnApplyTemplate();
|
||||
|
||||
winrt::TerminalApp::HighlightedText Text();
|
||||
void Text(const winrt::TerminalApp::HighlightedText& value);
|
||||
|
||||
Windows::UI::Xaml::Controls::TextBlock TextView();
|
||||
DEPENDENCY_PROPERTY(winrt::hstring, Text);
|
||||
DEPENDENCY_PROPERTY(winrt::Windows::Foundation::Collections::IVector<winrt::TerminalApp::HighlightedRun>, HighlightedRuns);
|
||||
DEPENDENCY_PROPERTY(winrt::Windows::UI::Xaml::Style, TextBlockStyle);
|
||||
DEPENDENCY_PROPERTY(winrt::Windows::UI::Xaml::Style, HighlightedRunStyle);
|
||||
|
||||
private:
|
||||
static Windows::UI::Xaml::DependencyProperty _textProperty;
|
||||
static void _onTextChanged(const Windows::UI::Xaml::DependencyObject& o, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
static void _InitializeProperties();
|
||||
static void _onPropertyChanged(const Windows::UI::Xaml::DependencyObject& o, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
void _updateTextAndStyle();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,28 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "HighlightedText.idl";
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
struct HighlightedRun
|
||||
{
|
||||
UInt64 Start;
|
||||
UInt64 End;
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass HighlightedTextControl : Windows.UI.Xaml.Controls.Control
|
||||
{
|
||||
HighlightedTextControl();
|
||||
|
||||
String Text;
|
||||
Windows.UI.Xaml.DependencyProperty TextProperty { get; };
|
||||
HighlightedText Text;
|
||||
Windows.UI.Xaml.Controls.TextBlock TextView { get; };
|
||||
|
||||
IVector<HighlightedRun> HighlightedRuns;
|
||||
Windows.UI.Xaml.DependencyProperty HighlightedRunsProperty { get; };
|
||||
|
||||
Windows.UI.Xaml.Style TextBlockStyle;
|
||||
Windows.UI.Xaml.DependencyProperty TextBlockStyleProperty { get; };
|
||||
|
||||
Windows.UI.Xaml.Style HighlightedRunStyle;
|
||||
Windows.UI.Xaml.DependencyProperty HighlightedRunStyleProperty { get; };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
<UserControl x:Class="TerminalApp.HighlightedTextControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
Background="Transparent"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<TextBlock x:Name="_textView" />
|
||||
</UserControl>
|
||||
23
src/cascadia/TerminalApp/HighlightedTextControlStyle.xaml
Normal file
23
src/cascadia/TerminalApp/HighlightedTextControlStyle.xaml
Normal file
@@ -0,0 +1,23 @@
|
||||
<!--
|
||||
Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information.
|
||||
-->
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:TerminalApp"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Style TargetType="local:HighlightedTextControl">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:HighlightedTextControl">
|
||||
<TextBlock x:Name="TextView"
|
||||
Style="{TemplateBinding TextBlockStyle}" />
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
29
src/cascadia/TerminalApp/IPaletteItem.idl
Normal file
29
src/cascadia/TerminalApp/IPaletteItem.idl
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "TerminalTabStatus.idl";
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
enum PaletteItemType
|
||||
{
|
||||
Action,
|
||||
CommandLine,
|
||||
Tab,
|
||||
};
|
||||
|
||||
interface IPaletteItem requires Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
PaletteItemType Type { get; };
|
||||
String Name { get; };
|
||||
String Subtitle { get; };
|
||||
String KeyChordText { get; };
|
||||
String Icon { get; };
|
||||
Windows.UI.Xaml.Controls.IconElement ResolvedIcon { get; };
|
||||
}
|
||||
|
||||
runtimeclass TabPaletteItem : [default] IPaletteItem, Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
TerminalTabStatus TabStatus{ get; };
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include <LibraryResources.h>
|
||||
#include "PaletteItem.h"
|
||||
#include "PaletteItem.g.cpp"
|
||||
|
||||
using namespace winrt;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Core;
|
||||
using namespace winrt::Microsoft::Terminal::Control;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::Windows::System;
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
Controls::IconElement PaletteItem::ResolvedIcon()
|
||||
{
|
||||
const auto icon = Microsoft::Terminal::UI::IconPathConverter::IconWUX(Icon());
|
||||
icon.Width(16);
|
||||
icon.Height(16);
|
||||
return icon;
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
#include "PaletteItem.g.h"
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct PaletteItem : PaletteItemT<PaletteItem>
|
||||
{
|
||||
public:
|
||||
Windows::UI::Xaml::Controls::IconElement ResolvedIcon();
|
||||
|
||||
til::property_changed_event PropertyChanged;
|
||||
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Name, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Icon, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, KeyChordText, PropertyChanged.raise);
|
||||
};
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
unsealed runtimeclass PaletteItem : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
String Name;
|
||||
String KeyChordText;
|
||||
String Icon;
|
||||
Windows.UI.Xaml.Controls.IconElement ResolvedIcon { get; };
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,11 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "TabPaletteItem.h"
|
||||
#include "PaletteItemTemplateSelector.h"
|
||||
#include "PaletteItemTemplateSelector.g.cpp"
|
||||
|
||||
#include "CommandPaletteItems.h"
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
Windows::UI::Xaml::DataTemplate PaletteItemTemplateSelector::SelectTemplateCore(const winrt::Windows::Foundation::IInspectable& item, const winrt::Windows::UI::Xaml::DependencyObject& /*container*/)
|
||||
@@ -26,16 +27,22 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
if (const auto filteredCommand{ item.try_as<winrt::TerminalApp::FilteredCommand>() })
|
||||
{
|
||||
if (filteredCommand.Item().try_as<winrt::TerminalApp::TabPaletteItem>())
|
||||
switch (filteredCommand.Item().Type())
|
||||
{
|
||||
case PaletteItemType::Tab:
|
||||
return TabItemTemplate();
|
||||
}
|
||||
else if (const auto actionPaletteItem{ filteredCommand.Item().try_as<winrt::TerminalApp::ActionPaletteItem>() })
|
||||
case PaletteItemType::Action:
|
||||
{
|
||||
if (actionPaletteItem.Command().HasNestedCommands())
|
||||
const auto actionPaletteItem{ winrt::get_self<ActionPaletteItem>(filteredCommand.Item()) };
|
||||
if (actionPaletteItem->Command().HasNestedCommands())
|
||||
{
|
||||
return NestedItemTemplate();
|
||||
}
|
||||
break; // Fall back to the general template
|
||||
}
|
||||
case PaletteItemType::CommandLine:
|
||||
default:
|
||||
break; // Fall back to the general template
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2429,7 +2429,7 @@ std::optional<uint32_t> Pane::Id() noexcept
|
||||
|
||||
// Method Description:
|
||||
// - Sets this pane's ID
|
||||
// - Panes are given IDs upon creation by TerminalTab
|
||||
// - Panes are given IDs upon creation by Tab
|
||||
// Arguments:
|
||||
// - The number to set this pane's ID to
|
||||
void Pane::Id(uint32_t id) noexcept
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace TerminalAppLocalTests
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct TerminalTab;
|
||||
struct Tab;
|
||||
}
|
||||
|
||||
enum class Borders : int
|
||||
@@ -398,6 +398,6 @@ private:
|
||||
LayoutSizeNode& operator=(const LayoutSizeNode& other);
|
||||
};
|
||||
|
||||
friend struct winrt::TerminalApp::implementation::TerminalTab;
|
||||
friend struct winrt::TerminalApp::implementation::Tab;
|
||||
friend class ::TerminalAppLocalTests::TabTests;
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "FilteredTask.g.h"
|
||||
#include "BasicPaneEvents.h"
|
||||
#include "FilteredCommand.h"
|
||||
#include "ActionPaletteItem.h"
|
||||
#include "CommandPaletteItems.h"
|
||||
#include <LibraryResources.h>
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
@@ -62,7 +62,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
FilteredTask(const winrt::Microsoft::Terminal::Settings::Model::Command& command)
|
||||
{
|
||||
_filteredCommand = winrt::make_self<implementation::FilteredCommand>(winrt::make<winrt::TerminalApp::implementation::ActionPaletteItem>(command, winrt::hstring{}));
|
||||
_filteredCommand = winrt::make_self<implementation::FilteredCommand>(winrt::make<ActionPaletteItem>(command, winrt::hstring{}));
|
||||
_command = command;
|
||||
|
||||
// The Children() method must always return a non-null vector
|
||||
@@ -92,14 +92,13 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
winrt::hstring Input()
|
||||
{
|
||||
if (const auto& actionItem{ _filteredCommand->Item().try_as<winrt::TerminalApp::ActionPaletteItem>() })
|
||||
// **SAFETY GUARANTEE** We constructed this filtered command ourselves; we know what's inside it.
|
||||
const auto actionItem{ winrt::get_self<ActionPaletteItem>(_filteredCommand->Item()) };
|
||||
if (const auto& command{ actionItem->Command() })
|
||||
{
|
||||
if (const auto& command{ actionItem.Command() })
|
||||
if (const auto& sendInput{ command.ActionAndArgs().Args().try_as<winrt::Microsoft::Terminal::Settings::Model::SendInputArgs>() })
|
||||
{
|
||||
if (const auto& sendInput{ command.ActionAndArgs().Args().try_as<winrt::Microsoft::Terminal::Settings::Model::SendInputArgs>() })
|
||||
{
|
||||
return winrt::hstring{ til::visualize_nonspace_control_codes(std::wstring{ sendInput.Input() }) };
|
||||
}
|
||||
return winrt::hstring{ til::visualize_nonspace_control_codes(std::wstring{ sendInput.Input() }) };
|
||||
}
|
||||
}
|
||||
return winrt::hstring{};
|
||||
|
||||
@@ -170,8 +170,9 @@
|
||||
|
||||
<local:HighlightedTextControl Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
HighlightedRuns="{x:Bind FilteredCommand.NameHighlights, Mode=OneWay}"
|
||||
IsTabStop="False"
|
||||
Text="{x:Bind FilteredCommand.HighlightedName, Mode=OneWay}" />
|
||||
Text="{x:Bind FilteredCommand.Item.Name, Mode=OneWay}" />
|
||||
|
||||
<!--
|
||||
BODGY: I can't choose different templates if this item is nested or not.
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "ActionPaletteItem.h"
|
||||
#include "CommandLinePaletteItem.h"
|
||||
#include "SuggestionsControl.h"
|
||||
#include <LibraryResources.h>
|
||||
|
||||
#include "CommandPaletteItems.h"
|
||||
|
||||
#include "SuggestionsControl.g.cpp"
|
||||
#include "../../types/inc/utils.hpp"
|
||||
|
||||
@@ -282,9 +282,11 @@ namespace winrt::TerminalApp::implementation
|
||||
if (filteredCommand != nullptr &&
|
||||
isVisible)
|
||||
{
|
||||
if (const auto actionPaletteItem{ filteredCommand.Item().try_as<winrt::TerminalApp::ActionPaletteItem>() })
|
||||
const auto item{ filteredCommand.Item() };
|
||||
if (item.Type() == PaletteItemType::Action)
|
||||
{
|
||||
const auto& cmd = actionPaletteItem.Command();
|
||||
const auto actionPaletteItem{ winrt::get_self<ActionPaletteItem>(item) };
|
||||
const auto& cmd = actionPaletteItem->Command();
|
||||
PreviewAction.raise(*this, cmd);
|
||||
|
||||
const auto description{ cmd.Description() };
|
||||
@@ -575,7 +577,7 @@ namespace winrt::TerminalApp::implementation
|
||||
const auto selectedCommand = selectedList.GetAt(0);
|
||||
if (const auto filteredCmd = selectedCommand.try_as<TerminalApp::FilteredCommand>())
|
||||
{
|
||||
if (const auto paletteItem = filteredCmd.Item().try_as<TerminalApp::PaletteItem>())
|
||||
if (const auto paletteItem = filteredCmd.Item())
|
||||
{
|
||||
automationPeer.RaiseNotificationEvent(
|
||||
Automation::Peers::AutomationNotificationKind::ItemAdded,
|
||||
@@ -609,10 +611,14 @@ namespace winrt::TerminalApp::implementation
|
||||
if (_nestedActionStack.Size() > 0)
|
||||
{
|
||||
const auto newPreviousAction{ _nestedActionStack.GetAt(_nestedActionStack.Size() - 1) };
|
||||
const auto actionPaletteItem{ newPreviousAction.Item().try_as<winrt::TerminalApp::ActionPaletteItem>() };
|
||||
const auto item{ newPreviousAction.Item() };
|
||||
if (item.Type() == PaletteItemType::Action)
|
||||
{
|
||||
const auto actionPaletteItem{ winrt::get_self<ActionPaletteItem>(item) };
|
||||
|
||||
ParentCommandName(actionPaletteItem.Command().Name());
|
||||
_updateCurrentNestedCommands(actionPaletteItem.Command());
|
||||
ParentCommandName(actionPaletteItem->Command().Name());
|
||||
_updateCurrentNestedCommands(actionPaletteItem->Command());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -693,16 +699,19 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
if (filteredCommand)
|
||||
{
|
||||
if (const auto actionPaletteItem{ filteredCommand.Item().try_as<winrt::TerminalApp::ActionPaletteItem>() })
|
||||
const auto item{ filteredCommand.Item() };
|
||||
if (item.Type() == PaletteItemType::Action)
|
||||
{
|
||||
if (actionPaletteItem.Command().HasNestedCommands())
|
||||
const auto actionPaletteItem{ winrt::get_self<ActionPaletteItem>(item) };
|
||||
const auto command{ actionPaletteItem->Command() };
|
||||
if (command.HasNestedCommands())
|
||||
{
|
||||
// If this Command had subcommands, then don't dispatch the
|
||||
// action. Instead, display a new list of commands for the user
|
||||
// to pick from.
|
||||
_nestedActionStack.Append(filteredCommand);
|
||||
ParentCommandName(actionPaletteItem.Command().Name());
|
||||
_updateCurrentNestedCommands(actionPaletteItem.Command());
|
||||
ParentCommandName(command.Name());
|
||||
_updateCurrentNestedCommands(command);
|
||||
|
||||
_updateUIForStackChange();
|
||||
}
|
||||
@@ -722,9 +731,9 @@ namespace winrt::TerminalApp::implementation
|
||||
// "ToggleCommandPalette" actions. We may want to do the
|
||||
// same with "Suggestions" actions in the future, should we
|
||||
// ever allow non-sendInput actions.
|
||||
DispatchCommandRequested.raise(*this, actionPaletteItem.Command());
|
||||
DispatchCommandRequested.raise(*this, command);
|
||||
|
||||
if (const auto& sendInputCmd = actionPaletteItem.Command().ActionAndArgs().Args().try_as<SendInputArgs>())
|
||||
if (const auto& sendInputCmd = command.ActionAndArgs().Args().try_as<SendInputArgs>())
|
||||
{
|
||||
if (til::starts_with(sendInputCmd.Input(), L"winget"))
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "TabBase.idl";
|
||||
import "HighlightedTextControl.idl";
|
||||
import "FilteredCommand.idl";
|
||||
|
||||
|
||||
@@ -57,7 +57,8 @@
|
||||
|
||||
<local:HighlightedTextControl Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
Text="{x:Bind HighlightedName, Mode=OneWay}" />
|
||||
HighlightedRuns="{x:Bind NameHighlights, Mode=OneWay}"
|
||||
Text="{x:Bind Item.Name, Mode=OneWay}" />
|
||||
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
@@ -84,7 +85,8 @@
|
||||
|
||||
<local:HighlightedTextControl Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
Text="{x:Bind HighlightedName, Mode=OneWay}" />
|
||||
HighlightedRuns="{x:Bind NameHighlights, Mode=OneWay}"
|
||||
Text="{x:Bind Item.Name, Mode=OneWay}" />
|
||||
|
||||
<FontIcon Grid.Column="2"
|
||||
HorizontalAlignment="Right"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,8 +4,8 @@
|
||||
#pragma once
|
||||
#include "Pane.h"
|
||||
#include "ColorPickupFlyout.h"
|
||||
#include "TabBase.h"
|
||||
#include "TerminalTab.g.h"
|
||||
#include "Tab.h"
|
||||
#include "Tab.g.h"
|
||||
|
||||
// fwdecl unittest classes
|
||||
namespace TerminalAppLocalTests
|
||||
@@ -15,10 +15,10 @@ namespace TerminalAppLocalTests
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct TerminalTab : TerminalTabT<TerminalTab, TabBase>
|
||||
struct Tab : TabT<Tab>
|
||||
{
|
||||
public:
|
||||
TerminalTab(std::shared_ptr<Pane> rootPane);
|
||||
Tab(std::shared_ptr<Pane> rootPane);
|
||||
|
||||
// Called after construction to perform the necessary setup, which relies on weak_ptr
|
||||
void Initialize();
|
||||
@@ -27,7 +27,7 @@ namespace winrt::TerminalApp::implementation
|
||||
winrt::Microsoft::Terminal::Settings::Model::Profile GetFocusedProfile() const noexcept;
|
||||
winrt::TerminalApp::IPaneContent GetActiveContent() const;
|
||||
|
||||
void Focus(winrt::Windows::UI::Xaml::FocusState focusState) override;
|
||||
void Focus(winrt::Windows::UI::Xaml::FocusState focusState);
|
||||
|
||||
void Scroll(const int delta);
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void UpdateSettings(const winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings& settings);
|
||||
void UpdateTitle();
|
||||
|
||||
void Shutdown() override;
|
||||
void Shutdown();
|
||||
void ClosePane();
|
||||
|
||||
void SetTabText(winrt::hstring title);
|
||||
@@ -69,7 +69,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void ResetTabText();
|
||||
void ActivateTabRenamer();
|
||||
|
||||
virtual std::optional<winrt::Windows::UI::Color> GetTabColor() override;
|
||||
std::optional<winrt::Windows::UI::Color> GetTabColor();
|
||||
void SetRuntimeTabColor(const winrt::Windows::UI::Color& color);
|
||||
void ResetRuntimeTabColor();
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void EnterZoom();
|
||||
void ExitZoom();
|
||||
|
||||
std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs> BuildStartupActions(BuildStartupKind kind) const override;
|
||||
std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs> BuildStartupActions(BuildStartupKind kind) const;
|
||||
|
||||
int GetLeafPaneCount() const noexcept;
|
||||
|
||||
@@ -98,16 +98,62 @@ namespace winrt::TerminalApp::implementation
|
||||
return _tabStatus;
|
||||
}
|
||||
|
||||
void SetDispatch(const winrt::TerminalApp::ShortcutActionDispatch& dispatch);
|
||||
|
||||
void UpdateTabViewIndex(const uint32_t idx, const uint32_t numTabs);
|
||||
void SetActionMap(const Microsoft::Terminal::Settings::Model::IActionMapView& actionMap);
|
||||
|
||||
void ThemeColor(const winrt::Microsoft::Terminal::Settings::Model::ThemeColor& focused,
|
||||
const winrt::Microsoft::Terminal::Settings::Model::ThemeColor& unfocused,
|
||||
const til::color& tabRowColor);
|
||||
|
||||
Microsoft::Terminal::Settings::Model::TabCloseButtonVisibility CloseButtonVisibility();
|
||||
void CloseButtonVisibility(Microsoft::Terminal::Settings::Model::TabCloseButtonVisibility visible);
|
||||
|
||||
til::event<winrt::delegate<void()>> RequestFocusActiveControl;
|
||||
|
||||
til::event<winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>> Closed;
|
||||
til::event<winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>> CloseRequested;
|
||||
til::property_changed_event PropertyChanged;
|
||||
|
||||
til::typed_event<TerminalApp::TerminalPaneContent> RestartTerminalRequested;
|
||||
|
||||
til::typed_event<TerminalApp::TerminalTab, IInspectable> ActivePaneChanged;
|
||||
til::typed_event<TerminalApp::Tab, IInspectable> ActivePaneChanged;
|
||||
til::event<winrt::delegate<>> TabRaiseVisualBell;
|
||||
til::typed_event<IInspectable, IInspectable> TaskbarProgressChanged;
|
||||
|
||||
// The TabViewIndex is the index this Tab object resides in TerminalPage's _tabs vector.
|
||||
WINRT_PROPERTY(uint32_t, TabViewIndex, 0);
|
||||
// The TabViewNumTabs is the number of Tab objects in TerminalPage's _tabs vector.
|
||||
WINRT_PROPERTY(uint32_t, TabViewNumTabs, 0);
|
||||
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Title, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Icon, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, ReadOnly, PropertyChanged.raise, false);
|
||||
WINRT_PROPERTY(winrt::Microsoft::UI::Xaml::Controls::TabViewItem, TabViewItem, nullptr);
|
||||
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::Windows::UI::Xaml::FrameworkElement, Content, PropertyChanged.raise, nullptr);
|
||||
|
||||
private:
|
||||
static constexpr double HeaderRenameBoxWidthDefault{ 165 };
|
||||
static constexpr double HeaderRenameBoxWidthTitleLength{ std::numeric_limits<double>::infinity() };
|
||||
|
||||
winrt::Windows::UI::Xaml::FocusState _focusState{ winrt::Windows::UI::Xaml::FocusState::Unfocused };
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _closeOtherTabsMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _closeTabsAfterMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _moveToNewWindowMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _moveRightMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _moveLeftMenuItem{};
|
||||
winrt::TerminalApp::ShortcutActionDispatch _dispatch;
|
||||
Microsoft::Terminal::Settings::Model::IActionMapView _actionMap{ nullptr };
|
||||
winrt::hstring _keyChord{};
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::ThemeColor _themeColor{ nullptr };
|
||||
winrt::Microsoft::Terminal::Settings::Model::ThemeColor _unfocusedThemeColor{ nullptr };
|
||||
til::color _tabRowColor;
|
||||
|
||||
Microsoft::Terminal::Settings::Model::TabCloseButtonVisibility _closeButtonVisibility{ Microsoft::Terminal::Settings::Model::TabCloseButtonVisibility::Always };
|
||||
|
||||
std::shared_ptr<Pane> _rootPane{ nullptr };
|
||||
std::shared_ptr<Pane> _activePane{ nullptr };
|
||||
std::shared_ptr<Pane> _zoomedPane{ nullptr };
|
||||
@@ -163,12 +209,10 @@ namespace winrt::TerminalApp::implementation
|
||||
SafeDispatcherTimer _bellIndicatorTimer;
|
||||
void _BellIndicatorTimerTick(const Windows::Foundation::IInspectable& sender, const Windows::Foundation::IInspectable& e);
|
||||
|
||||
void _MakeTabViewItem() override;
|
||||
|
||||
void _UpdateHeaderControlMaxWidth();
|
||||
|
||||
void _CreateContextMenu() override;
|
||||
virtual winrt::hstring _CreateToolTipTitle() override;
|
||||
void _CreateContextMenu();
|
||||
winrt::hstring _CreateToolTipTitle();
|
||||
|
||||
void _DetachEventHandlersFromContent(const uint32_t paneId);
|
||||
void _AttachEventHandlersToContent(const uint32_t paneId, const winrt::TerminalApp::IPaneContent& content);
|
||||
@@ -187,7 +231,23 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void _DuplicateTab();
|
||||
|
||||
virtual winrt::Windows::UI::Xaml::Media::Brush _BackgroundBrush() override;
|
||||
winrt::Windows::UI::Xaml::Media::Brush _BackgroundBrush();
|
||||
|
||||
void _MakeTabViewItem();
|
||||
|
||||
void _AppendMoveMenuItems(winrt::Windows::UI::Xaml::Controls::MenuFlyout flyout);
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutSubItem _AppendCloseMenuItems(winrt::Windows::UI::Xaml::Controls::MenuFlyout flyout);
|
||||
void _EnableMenuItems();
|
||||
void _UpdateSwitchToTabKeyChord();
|
||||
void _UpdateToolTip();
|
||||
|
||||
void _RecalculateAndApplyTabColor();
|
||||
void _ApplyTabColorOnUIThread(const winrt::Windows::UI::Color& color);
|
||||
void _ClearTabBackgroundColor();
|
||||
void _RefreshVisualState();
|
||||
|
||||
bool _focused() const noexcept;
|
||||
void _updateIsClosable();
|
||||
|
||||
void _addBroadcastHandlers(const winrt::Microsoft::Terminal::Control::TermControl& control, ContentEventTokens& events);
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
import "ShortcutActionDispatch.idl";
|
||||
import "TerminalTabStatus.idl";
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
unsealed runtimeclass TabBase : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
runtimeclass Tab : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
String Title { get; };
|
||||
String Icon { get; };
|
||||
@@ -14,6 +15,9 @@ namespace TerminalApp
|
||||
Microsoft.UI.Xaml.Controls.TabViewItem TabViewItem { get; };
|
||||
Windows.UI.Xaml.FrameworkElement Content { get; };
|
||||
|
||||
// May be Null
|
||||
TerminalTabStatus TabStatus { get; };
|
||||
|
||||
UInt32 TabViewIndex;
|
||||
UInt32 TabViewNumTabs;
|
||||
|
||||
@@ -1,753 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include <LibraryResources.h>
|
||||
#include "TabBase.h"
|
||||
#include "TabBase.g.cpp"
|
||||
#include "Utils.h"
|
||||
#include "ColorHelper.h"
|
||||
|
||||
using namespace winrt;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Core;
|
||||
using namespace winrt::Microsoft::Terminal::Control;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::Windows::System;
|
||||
|
||||
namespace winrt
|
||||
{
|
||||
namespace MUX = Microsoft::UI::Xaml;
|
||||
namespace WUX = Windows::UI::Xaml;
|
||||
}
|
||||
|
||||
#define ASSERT_UI_THREAD() assert(TabViewItem().Dispatcher().HasThreadAccess())
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
|
||||
// Method Description:
|
||||
// - Prepares this tab for being removed from the UI hierarchy
|
||||
void TabBase::Shutdown()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
// NOTE: `TerminalPage::_HandleCloseTabRequested` relies on the content being null after this call.
|
||||
Content(nullptr);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Creates a context menu attached to the tab.
|
||||
// Currently contains elements allowing the user to close the selected tab
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TabBase::_CreateContextMenu()
|
||||
{
|
||||
auto weakThis{ get_weak() };
|
||||
|
||||
// Build the menu
|
||||
Controls::MenuFlyout contextMenuFlyout;
|
||||
// GH#5750 - When the context menu is dismissed with ESC, toss the focus
|
||||
// back to our control.
|
||||
contextMenuFlyout.Closed([weakThis](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
tab->RequestFocusActiveControl.raise();
|
||||
}
|
||||
});
|
||||
_AppendMoveMenuItems(contextMenuFlyout);
|
||||
_AppendCloseMenuItems(contextMenuFlyout);
|
||||
TabViewItem().ContextFlyout(contextMenuFlyout);
|
||||
}
|
||||
|
||||
void TabBase::_AppendMoveMenuItems(winrt::Windows::UI::Xaml::Controls::MenuFlyout flyout)
|
||||
{
|
||||
auto weakThis{ get_weak() };
|
||||
|
||||
// Move to new window
|
||||
{
|
||||
Controls::FontIcon moveTabToNewWindowTabSymbol;
|
||||
moveTabToNewWindowTabSymbol.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
|
||||
moveTabToNewWindowTabSymbol.Glyph(L"\xE8A7");
|
||||
|
||||
_moveToNewWindowMenuItem.Click([weakThis](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
MoveTabArgs args{ L"new", MoveTabDirection::Forward };
|
||||
ActionAndArgs actionAndArgs{ ShortcutAction::MoveTab, args };
|
||||
tab->_dispatch.DoAction(*tab, actionAndArgs);
|
||||
}
|
||||
});
|
||||
_moveToNewWindowMenuItem.Text(RS_(L"MoveTabToNewWindowText"));
|
||||
_moveToNewWindowMenuItem.Icon(moveTabToNewWindowTabSymbol);
|
||||
|
||||
const auto moveTabToNewWindowToolTip = RS_(L"MoveTabToNewWindowToolTip");
|
||||
WUX::Controls::ToolTipService::SetToolTip(_moveToNewWindowMenuItem, box_value(moveTabToNewWindowToolTip));
|
||||
Automation::AutomationProperties::SetHelpText(_moveToNewWindowMenuItem, moveTabToNewWindowToolTip);
|
||||
}
|
||||
|
||||
// Move left
|
||||
{
|
||||
_moveLeftMenuItem.Click([weakThis](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
MoveTabArgs args{ hstring{}, MoveTabDirection::Backward };
|
||||
ActionAndArgs actionAndArgs{ ShortcutAction::MoveTab, args };
|
||||
tab->_dispatch.DoAction(*tab, actionAndArgs);
|
||||
}
|
||||
});
|
||||
_moveLeftMenuItem.Text(RS_(L"TabMoveLeft"));
|
||||
}
|
||||
|
||||
// Move right
|
||||
{
|
||||
_moveRightMenuItem.Click([weakThis](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
MoveTabArgs args{ hstring{}, MoveTabDirection::Forward };
|
||||
ActionAndArgs actionAndArgs{ ShortcutAction::MoveTab, args };
|
||||
tab->_dispatch.DoAction(*tab, actionAndArgs);
|
||||
}
|
||||
});
|
||||
_moveRightMenuItem.Text(RS_(L"TabMoveRight"));
|
||||
}
|
||||
|
||||
// Create a sub-menu for our extended move tab items.
|
||||
Controls::MenuFlyoutSubItem moveSubMenu;
|
||||
moveSubMenu.Text(RS_(L"TabMoveSubMenu"));
|
||||
moveSubMenu.Items().Append(_moveToNewWindowMenuItem);
|
||||
moveSubMenu.Items().Append(_moveRightMenuItem);
|
||||
moveSubMenu.Items().Append(_moveLeftMenuItem);
|
||||
flyout.Items().Append(moveSubMenu);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Append the close menu items to the context menu flyout
|
||||
// Arguments:
|
||||
// - flyout - the menu flyout to which the close items must be appended
|
||||
// Return Value:
|
||||
// - the sub-item that we use for all the nested "close" entries. This
|
||||
// enables subclasses to add their own entries to this menu.
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutSubItem TabBase::_AppendCloseMenuItems(winrt::Windows::UI::Xaml::Controls::MenuFlyout flyout)
|
||||
{
|
||||
auto weakThis{ get_weak() };
|
||||
|
||||
// Close tabs after
|
||||
_closeTabsAfterMenuItem.Click([weakThis](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
CloseTabsAfterArgs args{ tab->_TabViewIndex };
|
||||
ActionAndArgs closeTabsAfter{ ShortcutAction::CloseTabsAfter, args };
|
||||
tab->_dispatch.DoAction(*tab, closeTabsAfter);
|
||||
}
|
||||
});
|
||||
_closeTabsAfterMenuItem.Text(RS_(L"TabCloseAfter"));
|
||||
const auto closeTabsAfterToolTip = RS_(L"TabCloseAfterToolTip");
|
||||
|
||||
WUX::Controls::ToolTipService::SetToolTip(_closeTabsAfterMenuItem, box_value(closeTabsAfterToolTip));
|
||||
Automation::AutomationProperties::SetHelpText(_closeTabsAfterMenuItem, closeTabsAfterToolTip);
|
||||
|
||||
// Close other tabs
|
||||
_closeOtherTabsMenuItem.Click([weakThis](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
CloseOtherTabsArgs args{ tab->_TabViewIndex };
|
||||
ActionAndArgs closeOtherTabs{ ShortcutAction::CloseOtherTabs, args };
|
||||
tab->_dispatch.DoAction(*tab, closeOtherTabs);
|
||||
}
|
||||
});
|
||||
_closeOtherTabsMenuItem.Text(RS_(L"TabCloseOther"));
|
||||
const auto closeOtherTabsToolTip = RS_(L"TabCloseOtherToolTip");
|
||||
|
||||
WUX::Controls::ToolTipService::SetToolTip(_closeOtherTabsMenuItem, box_value(closeOtherTabsToolTip));
|
||||
Automation::AutomationProperties::SetHelpText(_closeOtherTabsMenuItem, closeOtherTabsToolTip);
|
||||
|
||||
// Close
|
||||
Controls::MenuFlyoutItem closeTabMenuItem;
|
||||
Controls::FontIcon closeSymbol;
|
||||
closeSymbol.FontFamily(Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
|
||||
closeSymbol.Glyph(L"\xE711");
|
||||
|
||||
closeTabMenuItem.Click([weakThis](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
tab->CloseRequested.raise(nullptr, nullptr);
|
||||
}
|
||||
});
|
||||
closeTabMenuItem.Text(RS_(L"TabClose"));
|
||||
closeTabMenuItem.Icon(closeSymbol);
|
||||
const auto closeTabToolTip = RS_(L"TabCloseToolTip");
|
||||
|
||||
WUX::Controls::ToolTipService::SetToolTip(closeTabMenuItem, box_value(closeTabToolTip));
|
||||
Automation::AutomationProperties::SetHelpText(closeTabMenuItem, closeTabToolTip);
|
||||
|
||||
// Create a sub-menu for our extended close items.
|
||||
Controls::MenuFlyoutSubItem closeSubMenu;
|
||||
closeSubMenu.Text(RS_(L"TabCloseSubMenu"));
|
||||
closeSubMenu.Items().Append(_closeTabsAfterMenuItem);
|
||||
closeSubMenu.Items().Append(_closeOtherTabsMenuItem);
|
||||
flyout.Items().Append(closeSubMenu);
|
||||
|
||||
flyout.Items().Append(closeTabMenuItem);
|
||||
|
||||
return closeSubMenu;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Enable menu items based on tab index and total number of tabs
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TabBase::_EnableMenuItems()
|
||||
{
|
||||
const auto tabIndex = TabViewIndex();
|
||||
const auto numOfTabs = TabViewNumTabs();
|
||||
|
||||
// enabled if there are other tabs
|
||||
_closeOtherTabsMenuItem.IsEnabled(numOfTabs > 1);
|
||||
|
||||
// enabled if there are other tabs on the right
|
||||
_closeTabsAfterMenuItem.IsEnabled(tabIndex < numOfTabs - 1);
|
||||
|
||||
// enabled if not left-most tab
|
||||
_moveLeftMenuItem.IsEnabled(tabIndex > 0);
|
||||
|
||||
// enabled if not last tab
|
||||
_moveRightMenuItem.IsEnabled(tabIndex < numOfTabs - 1);
|
||||
}
|
||||
|
||||
void TabBase::UpdateTabViewIndex(const uint32_t idx, const uint32_t numTabs)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
TabViewIndex(idx);
|
||||
TabViewNumTabs(numTabs);
|
||||
_EnableMenuItems();
|
||||
_UpdateSwitchToTabKeyChord();
|
||||
}
|
||||
|
||||
void TabBase::SetDispatch(const winrt::TerminalApp::ShortcutActionDispatch& dispatch)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_dispatch = dispatch;
|
||||
}
|
||||
|
||||
void TabBase::SetActionMap(const Microsoft::Terminal::Settings::Model::IActionMapView& actionMap)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_actionMap = actionMap;
|
||||
_UpdateSwitchToTabKeyChord();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets the key chord resulting in switch to the current tab.
|
||||
// Updates tool tip if required
|
||||
// Arguments:
|
||||
// - keyChord - string representation of the key chord that switches to the current tab
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TabBase::_UpdateSwitchToTabKeyChord()
|
||||
{
|
||||
const auto id = fmt::format(FMT_COMPILE(L"Terminal.SwitchToTab{}"), _TabViewIndex);
|
||||
const auto keyChord{ _actionMap.GetKeyBindingForAction(id) };
|
||||
const auto keyChordText = keyChord ? KeyChordSerialization::ToString(keyChord) : L"";
|
||||
|
||||
if (_keyChord == keyChordText)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_keyChord = keyChordText;
|
||||
_UpdateToolTip();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Creates a text for the title run in the tool tip by returning tab title
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - The value to populate in the title run of the tool tip
|
||||
winrt::hstring TabBase::_CreateToolTipTitle()
|
||||
{
|
||||
return _Title;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets tab tool tip to a concatenation of title and key chord
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TabBase::_UpdateToolTip()
|
||||
{
|
||||
auto titleRun = WUX::Documents::Run();
|
||||
titleRun.Text(_CreateToolTipTitle());
|
||||
|
||||
auto textBlock = WUX::Controls::TextBlock{};
|
||||
textBlock.TextWrapping(WUX::TextWrapping::Wrap);
|
||||
textBlock.TextAlignment(WUX::TextAlignment::Center);
|
||||
textBlock.Inlines().Append(titleRun);
|
||||
|
||||
if (!_keyChord.empty())
|
||||
{
|
||||
auto keyChordRun = WUX::Documents::Run();
|
||||
keyChordRun.Text(_keyChord);
|
||||
keyChordRun.FontStyle(winrt::Windows::UI::Text::FontStyle::Italic);
|
||||
textBlock.Inlines().Append(WUX::Documents::LineBreak{});
|
||||
textBlock.Inlines().Append(keyChordRun);
|
||||
}
|
||||
|
||||
WUX::Controls::ToolTip toolTip{};
|
||||
toolTip.Content(textBlock);
|
||||
WUX::Controls::ToolTipService::SetToolTip(TabViewItem(), toolTip);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Initializes a TabViewItem for this Tab instance.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TabBase::_MakeTabViewItem()
|
||||
{
|
||||
TabViewItem(::winrt::MUX::Controls::TabViewItem{});
|
||||
|
||||
// GH#3609 If the tab was tapped, and no one else was around to handle
|
||||
// it, then ask our parent to toss focus into the active control.
|
||||
TabViewItem().Tapped([weakThis{ get_weak() }](auto&&, auto&&) {
|
||||
if (auto tab{ weakThis.get() })
|
||||
{
|
||||
tab->RequestFocusActiveControl.raise();
|
||||
}
|
||||
});
|
||||
|
||||
// BODGY: When the tab is drag/dropped, the TabView gets a
|
||||
// TabDragStarting. However, the way it is implemented[^1], the
|
||||
// TabViewItem needs either an Item or a Content for the event to
|
||||
// include the correct TabViewItem. Otherwise, it will just return the
|
||||
// first TabViewItem in the TabView with the same Content as the dragged
|
||||
// tab (which, if the Content is null, will be the _first_ tab).
|
||||
//
|
||||
// So here, we'll stick an empty border in, just so that every tab has a
|
||||
// Content which is not equal to the others.
|
||||
//
|
||||
// [^1]: microsoft-ui-xaml/blob/92fbfcd55f05c92ac65569f5d284c5b36492091e/dev/TabView/TabView.cpp#L751-L758
|
||||
TabViewItem().Content(winrt::WUX::Controls::Border{});
|
||||
}
|
||||
|
||||
std::optional<winrt::Windows::UI::Color> TabBase::GetTabColor()
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void TabBase::ThemeColor(const winrt::Microsoft::Terminal::Settings::Model::ThemeColor& focused,
|
||||
const winrt::Microsoft::Terminal::Settings::Model::ThemeColor& unfocused,
|
||||
const til::color& tabRowColor)
|
||||
{
|
||||
ASSERT_UI_THREAD();
|
||||
|
||||
_themeColor = focused;
|
||||
_unfocusedThemeColor = unfocused;
|
||||
_tabRowColor = tabRowColor;
|
||||
_RecalculateAndApplyTabColor();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - This function dispatches a function to the UI thread to recalculate
|
||||
// what this tab's current background color should be. If a color is set,
|
||||
// it will apply the given color to the tab's background. Otherwise, it
|
||||
// will clear the tab's background color.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TabBase::_RecalculateAndApplyTabColor()
|
||||
{
|
||||
// GetTabColor will return the color set by the color picker, or the
|
||||
// color specified in the profile. If neither of those were set,
|
||||
// then look to _themeColor to see if there's a value there.
|
||||
// Otherwise, clear our color, falling back to the TabView defaults.
|
||||
const auto currentColor = GetTabColor();
|
||||
if (currentColor.has_value())
|
||||
{
|
||||
_ApplyTabColorOnUIThread(currentColor.value());
|
||||
}
|
||||
else if (_themeColor != nullptr)
|
||||
{
|
||||
// Safely get the active control's brush.
|
||||
const Media::Brush terminalBrush{ _BackgroundBrush() };
|
||||
|
||||
if (const auto themeBrush{ _themeColor.Evaluate(Application::Current().Resources(), terminalBrush, false) })
|
||||
{
|
||||
// ThemeColor.Evaluate will get us a Brush (because the
|
||||
// TermControl could have an acrylic BG, for example). Take
|
||||
// that brush, and get the color out of it. We don't really
|
||||
// want to have the tab items themselves be acrylic.
|
||||
_ApplyTabColorOnUIThread(til::color{ ThemeColor::ColorFromBrush(themeBrush) });
|
||||
}
|
||||
else
|
||||
{
|
||||
_ClearTabBackgroundColor();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_ClearTabBackgroundColor();
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Applies the given color to the background of this tab's TabViewItem.
|
||||
// - Sets the tab foreground color depending on the luminance of
|
||||
// the background color
|
||||
// - This method should only be called on the UI thread.
|
||||
// Arguments:
|
||||
// - color: the color the user picked for their tab
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TabBase::_ApplyTabColorOnUIThread(const winrt::Windows::UI::Color& color)
|
||||
{
|
||||
Media::SolidColorBrush selectedTabBrush{};
|
||||
Media::SolidColorBrush deselectedTabBrush{};
|
||||
Media::SolidColorBrush fontBrush{};
|
||||
Media::SolidColorBrush deselectedFontBrush{};
|
||||
Media::SolidColorBrush secondaryFontBrush{};
|
||||
Media::SolidColorBrush hoverTabBrush{};
|
||||
Media::SolidColorBrush subtleFillColorSecondaryBrush;
|
||||
Media::SolidColorBrush subtleFillColorTertiaryBrush;
|
||||
|
||||
// calculate the luminance of the current color and select a font
|
||||
// color based on that
|
||||
// see https://www.w3.org/TR/WCAG20/#relativeluminancedef
|
||||
if (TerminalApp::ColorHelper::IsBrightColor(color))
|
||||
{
|
||||
auto subtleFillColorSecondary = winrt::Windows::UI::Colors::Black();
|
||||
subtleFillColorSecondary.A = 0x09;
|
||||
subtleFillColorSecondaryBrush.Color(subtleFillColorSecondary);
|
||||
auto subtleFillColorTertiary = winrt::Windows::UI::Colors::Black();
|
||||
subtleFillColorTertiary.A = 0x06;
|
||||
subtleFillColorTertiaryBrush.Color(subtleFillColorTertiary);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto subtleFillColorSecondary = winrt::Windows::UI::Colors::White();
|
||||
subtleFillColorSecondary.A = 0x0F;
|
||||
subtleFillColorSecondaryBrush.Color(subtleFillColorSecondary);
|
||||
auto subtleFillColorTertiary = winrt::Windows::UI::Colors::White();
|
||||
subtleFillColorTertiary.A = 0x0A;
|
||||
subtleFillColorTertiaryBrush.Color(subtleFillColorTertiary);
|
||||
}
|
||||
|
||||
// The tab font should be based on the evaluated appearance of the tab color layered on tab row.
|
||||
const auto layeredTabColor = til::color{ color }.layer_over(_tabRowColor);
|
||||
if (TerminalApp::ColorHelper::IsBrightColor(layeredTabColor))
|
||||
{
|
||||
fontBrush.Color(winrt::Windows::UI::Colors::Black());
|
||||
auto secondaryFontColor = winrt::Windows::UI::Colors::Black();
|
||||
// For alpha value see: https://github.com/microsoft/microsoft-ui-xaml/blob/7a33ad772d77d908aa6b316ec24e6d2eb3ebf571/dev/CommonStyles/Common_themeresources_any.xaml#L269
|
||||
secondaryFontColor.A = 0x9E;
|
||||
secondaryFontBrush.Color(secondaryFontColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
fontBrush.Color(winrt::Windows::UI::Colors::White());
|
||||
auto secondaryFontColor = winrt::Windows::UI::Colors::White();
|
||||
// For alpha value see: https://github.com/microsoft/microsoft-ui-xaml/blob/7a33ad772d77d908aa6b316ec24e6d2eb3ebf571/dev/CommonStyles/Common_themeresources_any.xaml#L14
|
||||
secondaryFontColor.A = 0xC5;
|
||||
secondaryFontBrush.Color(secondaryFontColor);
|
||||
}
|
||||
|
||||
selectedTabBrush.Color(color);
|
||||
|
||||
// Start with the current tab color, set to Opacity=.3
|
||||
til::color deselectedTabColor{ color };
|
||||
deselectedTabColor = deselectedTabColor.with_alpha(77); // 255 * .3 = 77
|
||||
|
||||
// If we DON'T have a color set from the color picker, or the profile's
|
||||
// tabColor, but we do have a unfocused color in the theme, use the
|
||||
// unfocused theme color here instead.
|
||||
if (!GetTabColor().has_value() &&
|
||||
_unfocusedThemeColor != nullptr)
|
||||
{
|
||||
// Safely get the active control's brush.
|
||||
const Media::Brush terminalBrush{ _BackgroundBrush() };
|
||||
|
||||
// Get the color of the brush.
|
||||
if (const auto themeBrush{ _unfocusedThemeColor.Evaluate(Application::Current().Resources(), terminalBrush, false) })
|
||||
{
|
||||
// We did figure out the brush. Get the color out of it. If it
|
||||
// was "accent" or "terminalBackground", then we're gonna set
|
||||
// the alpha to .3 manually here.
|
||||
// (ThemeColor::UnfocusedTabOpacity will do this for us). If the
|
||||
// user sets both unfocused and focused tab.background to
|
||||
// terminalBackground, this will allow for some differentiation
|
||||
// (and is generally just sensible).
|
||||
deselectedTabColor = til::color{ ThemeColor::ColorFromBrush(themeBrush) }.with_alpha(_unfocusedThemeColor.UnfocusedTabOpacity());
|
||||
}
|
||||
}
|
||||
|
||||
// currently if a tab has a custom color, a deselected state is
|
||||
// signified by using the same color with a bit of transparency
|
||||
deselectedTabBrush.Color(deselectedTabColor.with_alpha(255));
|
||||
deselectedTabBrush.Opacity(deselectedTabColor.a / 255.f);
|
||||
|
||||
hoverTabBrush.Color(color);
|
||||
hoverTabBrush.Opacity(0.6);
|
||||
|
||||
// Account for the color of the tab row when setting the color of text
|
||||
// on inactive tabs. Consider:
|
||||
// * black active tabs
|
||||
// * on a white tab row
|
||||
// * with a transparent inactive tab color
|
||||
//
|
||||
// We don't want that to result in white text on a white tab row for
|
||||
// inactive tabs.
|
||||
const auto deselectedActualColor = deselectedTabColor.layer_over(_tabRowColor);
|
||||
if (TerminalApp::ColorHelper::IsBrightColor(deselectedActualColor))
|
||||
{
|
||||
deselectedFontBrush.Color(winrt::Windows::UI::Colors::Black());
|
||||
}
|
||||
else
|
||||
{
|
||||
deselectedFontBrush.Color(winrt::Windows::UI::Colors::White());
|
||||
}
|
||||
|
||||
// Add the empty theme dictionaries
|
||||
const auto& tabItemThemeResources{ TabViewItem().Resources().ThemeDictionaries() };
|
||||
ResourceDictionary lightThemeDictionary;
|
||||
ResourceDictionary darkThemeDictionary;
|
||||
ResourceDictionary highContrastThemeDictionary;
|
||||
tabItemThemeResources.Insert(winrt::box_value(L"Light"), lightThemeDictionary);
|
||||
tabItemThemeResources.Insert(winrt::box_value(L"Dark"), darkThemeDictionary);
|
||||
tabItemThemeResources.Insert(winrt::box_value(L"HighContrast"), highContrastThemeDictionary);
|
||||
|
||||
// Apply the color to the tab
|
||||
TabViewItem().Background(deselectedTabBrush);
|
||||
|
||||
// Now actually set the resources we want in them.
|
||||
// Before, we used to put these on the ResourceDictionary directly.
|
||||
// However, HighContrast mode may require some adjustments. So let's just add
|
||||
// all three so we can make those adjustments on the HighContrast version.
|
||||
for (const auto& [k, v] : tabItemThemeResources)
|
||||
{
|
||||
const bool isHighContrast = winrt::unbox_value<hstring>(k) == L"HighContrast";
|
||||
const auto& currentDictionary = v.as<ResourceDictionary>();
|
||||
|
||||
// TabViewItem.Background
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderBackground"), deselectedTabBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderBackgroundSelected"), selectedTabBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderBackgroundPointerOver"), isHighContrast ? fontBrush : hoverTabBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderBackgroundPressed"), selectedTabBrush);
|
||||
|
||||
// TabViewItem.Foreground (aka text)
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderForeground"), deselectedFontBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderForegroundSelected"), fontBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderForegroundPointerOver"), isHighContrast ? selectedTabBrush : fontBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderForegroundPressed"), fontBrush);
|
||||
|
||||
// TabViewItem.CloseButton.Foreground (aka X)
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonForeground"), deselectedFontBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonForegroundPressed"), isHighContrast ? deselectedFontBrush : secondaryFontBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonForegroundPointerOver"), isHighContrast ? deselectedFontBrush : fontBrush);
|
||||
|
||||
// TabViewItem.CloseButton.Foreground _when_ interacting with the tab
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderPressedCloseButtonForeground"), fontBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderPointerOverCloseButtonForeground"), isHighContrast ? selectedTabBrush : fontBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderSelectedCloseButtonForeground"), fontBrush);
|
||||
|
||||
// TabViewItem.CloseButton.Background (aka X button)
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonBackgroundPressed"), isHighContrast ? selectedTabBrush : subtleFillColorTertiaryBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonBackgroundPointerOver"), isHighContrast ? selectedTabBrush : subtleFillColorSecondaryBrush);
|
||||
|
||||
// A few miscellaneous resources that WinUI said may be removed in the future
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewButtonForegroundActiveTab"), fontBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewButtonForegroundPressed"), fontBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewButtonForegroundPointerOver"), fontBrush);
|
||||
|
||||
// Add a few extra ones for high contrast mode
|
||||
// BODGY: contrary to the docs, Insert() seems to throw if the value already exists
|
||||
// Make sure you don't touch any that already exist here!
|
||||
if (isHighContrast)
|
||||
{
|
||||
// TabViewItem.CloseButton.Border: in HC mode, the border makes the button more clearly visible
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonBorderBrushPressed"), fontBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonBorderBrushPointerOver"), fontBrush);
|
||||
currentDictionary.Insert(winrt::box_value(L"TabViewItemHeaderCloseButtonBorderBrushSelected"), fontBrush);
|
||||
}
|
||||
}
|
||||
|
||||
_RefreshVisualState();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Clear out any color we've set for the TabViewItem.
|
||||
// - This method should only be called on the UI thread.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TabBase::_ClearTabBackgroundColor()
|
||||
{
|
||||
static const winrt::hstring keys[] = {
|
||||
// TabViewItem.Background
|
||||
L"TabViewItemHeaderBackground",
|
||||
L"TabViewItemHeaderBackgroundSelected",
|
||||
L"TabViewItemHeaderBackgroundPointerOver",
|
||||
L"TabViewItemHeaderBackgroundPressed",
|
||||
|
||||
// TabViewItem.Foreground (aka text)
|
||||
L"TabViewItemHeaderForeground",
|
||||
L"TabViewItemHeaderForegroundSelected",
|
||||
L"TabViewItemHeaderForegroundPointerOver",
|
||||
L"TabViewItemHeaderForegroundPressed",
|
||||
|
||||
// TabViewItem.CloseButton.Foreground (aka X)
|
||||
L"TabViewItemHeaderCloseButtonForeground",
|
||||
L"TabViewItemHeaderForegroundSelected",
|
||||
L"TabViewItemHeaderCloseButtonForegroundPointerOver",
|
||||
L"TabViewItemHeaderCloseButtonForegroundPressed",
|
||||
|
||||
// TabViewItem.CloseButton.Foreground _when_ interacting with the tab
|
||||
L"TabViewItemHeaderPressedCloseButtonForeground",
|
||||
L"TabViewItemHeaderPointerOverCloseButtonForeground",
|
||||
L"TabViewItemHeaderSelectedCloseButtonForeground",
|
||||
|
||||
// TabViewItem.CloseButton.Background (aka X button)
|
||||
L"TabViewItemHeaderCloseButtonBackground",
|
||||
L"TabViewItemHeaderCloseButtonBackgroundPressed",
|
||||
L"TabViewItemHeaderCloseButtonBackgroundPointerOver",
|
||||
|
||||
// A few miscellaneous resources that WinUI said may be removed in the future
|
||||
L"TabViewButtonForegroundActiveTab",
|
||||
L"TabViewButtonForegroundPressed",
|
||||
L"TabViewButtonForegroundPointerOver",
|
||||
|
||||
// TabViewItem.CloseButton.Border: in HC mode, the border makes the button more clearly visible
|
||||
L"TabViewItemHeaderCloseButtonBorderBrushPressed",
|
||||
L"TabViewItemHeaderCloseButtonBorderBrushPointerOver",
|
||||
L"TabViewItemHeaderCloseButtonBorderBrushSelected"
|
||||
};
|
||||
|
||||
const auto& tabItemThemeResources{ TabViewItem().Resources().ThemeDictionaries() };
|
||||
|
||||
// simply clear any of the colors in the tab's dict
|
||||
for (const auto& keyString : keys)
|
||||
{
|
||||
const auto key = winrt::box_value(keyString);
|
||||
for (const auto& [_, v] : tabItemThemeResources)
|
||||
{
|
||||
const auto& themeDictionary = v.as<ResourceDictionary>();
|
||||
themeDictionary.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
// GH#11382 DON'T set the background to null. If you do that, then the
|
||||
// tab won't be hit testable at all. Transparent, however, is a totally
|
||||
// valid hit test target. That makes sense.
|
||||
TabViewItem().Background(WUX::Media::SolidColorBrush{ Windows::UI::Colors::Transparent() });
|
||||
|
||||
_RefreshVisualState();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// BODGY
|
||||
// - Toggles the requested theme of the tab view item,
|
||||
// so that changes to the tab color are reflected immediately
|
||||
// - Prior to MUX 2.8, we only toggled the visual state here, but that seemingly
|
||||
// doesn't work in 2.8.
|
||||
// - Just changing the Theme also doesn't seem to work by itself - there
|
||||
// seems to be a way for the tab to set the deselected foreground onto
|
||||
// itself as it becomes selected. If the mouse isn't over the tab, that
|
||||
// can result in mismatched fg/bg's (see GH#15184). So that's right, we
|
||||
// need to do both.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TabBase::_RefreshVisualState()
|
||||
{
|
||||
const auto& item{ TabViewItem() };
|
||||
|
||||
const auto& reqTheme = TabViewItem().RequestedTheme();
|
||||
item.RequestedTheme(ElementTheme::Light);
|
||||
item.RequestedTheme(ElementTheme::Dark);
|
||||
item.RequestedTheme(reqTheme);
|
||||
|
||||
if (TabViewItem().IsSelected())
|
||||
{
|
||||
VisualStateManager::GoToState(item, L"Normal", true);
|
||||
VisualStateManager::GoToState(item, L"Selected", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
VisualStateManager::GoToState(item, L"Selected", true);
|
||||
VisualStateManager::GoToState(item, L"Normal", true);
|
||||
}
|
||||
}
|
||||
|
||||
TabCloseButtonVisibility TabBase::CloseButtonVisibility()
|
||||
{
|
||||
return _closeButtonVisibility;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - set our internal state to track if we were requested to have a visible
|
||||
// tab close button or not.
|
||||
// - This is called every time the active tab changes. That way, the changes
|
||||
// in focused tab can be reflected for the "ActiveOnly" state.
|
||||
void TabBase::CloseButtonVisibility(TabCloseButtonVisibility visibility)
|
||||
{
|
||||
_closeButtonVisibility = visibility;
|
||||
_updateIsClosable();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Update our close button's visibility, to reflect both the ReadOnly
|
||||
// state of the tab content, and also if if we were told to have a visible
|
||||
// close button at all.
|
||||
// - the tab being read-only takes precedence. That will always suppress
|
||||
// the close button.
|
||||
// - Otherwise we'll use the state set in CloseButtonVisibility to control
|
||||
// the tab's visibility.
|
||||
void TabBase::_updateIsClosable()
|
||||
{
|
||||
bool isClosable = true;
|
||||
|
||||
if (ReadOnly())
|
||||
{
|
||||
isClosable = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (_closeButtonVisibility)
|
||||
{
|
||||
case TabCloseButtonVisibility::Never:
|
||||
isClosable = false;
|
||||
break;
|
||||
case TabCloseButtonVisibility::Hover:
|
||||
isClosable = true;
|
||||
break;
|
||||
case TabCloseButtonVisibility::ActiveOnly:
|
||||
isClosable = _focused();
|
||||
break;
|
||||
default:
|
||||
isClosable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
TabViewItem().IsClosable(isClosable);
|
||||
}
|
||||
|
||||
bool TabBase::_focused() const noexcept
|
||||
{
|
||||
return _focusState != FocusState::Unfocused;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
#include "TabBase.g.h"
|
||||
|
||||
// fwdecl unittest classes
|
||||
namespace TerminalAppLocalTests
|
||||
{
|
||||
class TabTests;
|
||||
};
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct TabBase : TabBaseT<TabBase>
|
||||
{
|
||||
public:
|
||||
virtual void Focus(winrt::Windows::UI::Xaml::FocusState focusState) = 0;
|
||||
|
||||
virtual void Shutdown();
|
||||
void SetDispatch(const winrt::TerminalApp::ShortcutActionDispatch& dispatch);
|
||||
|
||||
void UpdateTabViewIndex(const uint32_t idx, const uint32_t numTabs);
|
||||
void SetActionMap(const Microsoft::Terminal::Settings::Model::IActionMapView& actionMap);
|
||||
virtual std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs> BuildStartupActions(BuildStartupKind kind) const = 0;
|
||||
|
||||
virtual std::optional<winrt::Windows::UI::Color> GetTabColor();
|
||||
void ThemeColor(const winrt::Microsoft::Terminal::Settings::Model::ThemeColor& focused,
|
||||
const winrt::Microsoft::Terminal::Settings::Model::ThemeColor& unfocused,
|
||||
const til::color& tabRowColor);
|
||||
|
||||
Microsoft::Terminal::Settings::Model::TabCloseButtonVisibility CloseButtonVisibility();
|
||||
void CloseButtonVisibility(Microsoft::Terminal::Settings::Model::TabCloseButtonVisibility visible);
|
||||
|
||||
til::event<winrt::delegate<void()>> RequestFocusActiveControl;
|
||||
|
||||
til::event<winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>> Closed;
|
||||
til::event<winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>> CloseRequested;
|
||||
til::property_changed_event PropertyChanged;
|
||||
|
||||
// The TabViewIndex is the index this Tab object resides in TerminalPage's _tabs vector.
|
||||
WINRT_PROPERTY(uint32_t, TabViewIndex, 0);
|
||||
// The TabViewNumTabs is the number of Tab objects in TerminalPage's _tabs vector.
|
||||
WINRT_PROPERTY(uint32_t, TabViewNumTabs, 0);
|
||||
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Title, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Icon, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(bool, ReadOnly, PropertyChanged.raise, false);
|
||||
WINRT_PROPERTY(winrt::Microsoft::UI::Xaml::Controls::TabViewItem, TabViewItem, nullptr);
|
||||
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::Windows::UI::Xaml::FrameworkElement, Content, PropertyChanged.raise, nullptr);
|
||||
|
||||
protected:
|
||||
winrt::Windows::UI::Xaml::FocusState _focusState{ winrt::Windows::UI::Xaml::FocusState::Unfocused };
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _closeOtherTabsMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _closeTabsAfterMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _moveToNewWindowMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _moveRightMenuItem{};
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _moveLeftMenuItem{};
|
||||
winrt::TerminalApp::ShortcutActionDispatch _dispatch;
|
||||
Microsoft::Terminal::Settings::Model::IActionMapView _actionMap{ nullptr };
|
||||
winrt::hstring _keyChord{};
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::ThemeColor _themeColor{ nullptr };
|
||||
winrt::Microsoft::Terminal::Settings::Model::ThemeColor _unfocusedThemeColor{ nullptr };
|
||||
til::color _tabRowColor;
|
||||
|
||||
Microsoft::Terminal::Settings::Model::TabCloseButtonVisibility _closeButtonVisibility{ Microsoft::Terminal::Settings::Model::TabCloseButtonVisibility::Always };
|
||||
|
||||
virtual void _CreateContextMenu();
|
||||
virtual winrt::hstring _CreateToolTipTitle();
|
||||
|
||||
virtual void _MakeTabViewItem();
|
||||
|
||||
void _AppendMoveMenuItems(winrt::Windows::UI::Xaml::Controls::MenuFlyout flyout);
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyoutSubItem _AppendCloseMenuItems(winrt::Windows::UI::Xaml::Controls::MenuFlyout flyout);
|
||||
void _EnableMenuItems();
|
||||
void _UpdateSwitchToTabKeyChord();
|
||||
void _UpdateToolTip();
|
||||
|
||||
void _RecalculateAndApplyTabColor();
|
||||
void _ApplyTabColorOnUIThread(const winrt::Windows::UI::Color& color);
|
||||
void _ClearTabBackgroundColor();
|
||||
void _RefreshVisualState();
|
||||
virtual winrt::Windows::UI::Xaml::Media::Brush _BackgroundBrush() = 0;
|
||||
|
||||
bool _focused() const noexcept;
|
||||
void _updateIsClosable();
|
||||
|
||||
friend class ::TerminalAppLocalTests::TabTests;
|
||||
};
|
||||
}
|
||||
@@ -18,7 +18,6 @@
|
||||
#include <LibraryResources.h>
|
||||
|
||||
#include "TabRowControl.h"
|
||||
#include "ColorHelper.h"
|
||||
#include "DebugTapConnection.h"
|
||||
#include "..\TerminalSettingsModel\FileUtils.h"
|
||||
|
||||
@@ -99,7 +98,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// Arguments:
|
||||
// - newTabImpl: the uninitialized tab.
|
||||
// - insertPosition: Optional parameter to indicate the position of tab.
|
||||
void TerminalPage::_InitializeTab(winrt::com_ptr<TerminalTab> newTabImpl, uint32_t insertPosition)
|
||||
void TerminalPage::_InitializeTab(winrt::com_ptr<Tab> newTabImpl, uint32_t insertPosition)
|
||||
{
|
||||
newTabImpl->Initialize();
|
||||
|
||||
@@ -206,11 +205,11 @@ namespace winrt::TerminalApp::implementation
|
||||
// Arguments:
|
||||
// - pane: The pane to use as the root.
|
||||
// - insertPosition: Optional parameter to indicate the position of tab.
|
||||
TerminalApp::TerminalTab TerminalPage::_CreateNewTabFromPane(std::shared_ptr<Pane> pane, uint32_t insertPosition)
|
||||
TerminalApp::Tab TerminalPage::_CreateNewTabFromPane(std::shared_ptr<Pane> pane, uint32_t insertPosition)
|
||||
{
|
||||
if (pane)
|
||||
{
|
||||
auto newTabImpl = winrt::make_self<TerminalTab>(pane);
|
||||
auto newTabImpl = winrt::make_self<Tab>(pane);
|
||||
_InitializeTab(newTabImpl, insertPosition);
|
||||
return *newTabImpl;
|
||||
}
|
||||
@@ -222,7 +221,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// tab's icon to that icon.
|
||||
// Arguments:
|
||||
// - tab: the Tab to update the title for.
|
||||
void TerminalPage::_UpdateTabIcon(TerminalTab& tab)
|
||||
void TerminalPage::_UpdateTabIcon(Tab& tab)
|
||||
{
|
||||
if (const auto content{ tab.GetActiveContent() })
|
||||
{
|
||||
@@ -272,9 +271,9 @@ namespace winrt::TerminalApp::implementation
|
||||
// - Duplicates the current focused tab
|
||||
void TerminalPage::_DuplicateFocusedTab()
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto activeTab{ _GetFocusedTabImpl() })
|
||||
{
|
||||
_DuplicateTab(*terminalTab);
|
||||
_DuplicateTab(*activeTab);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,7 +281,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - Duplicates specified tab
|
||||
// Arguments:
|
||||
// - tab: tab to duplicate
|
||||
void TerminalPage::_DuplicateTab(const TerminalTab& tab)
|
||||
void TerminalPage::_DuplicateTab(const Tab& tab)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -315,7 +314,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - Exports the content of the Terminal Buffer inside the tab
|
||||
// Arguments:
|
||||
// - tab: tab to export
|
||||
safe_void_coroutine TerminalPage::_ExportTab(const TerminalTab& tab, winrt::hstring filepath)
|
||||
safe_void_coroutine TerminalPage::_ExportTab(const Tab& tab, winrt::hstring filepath)
|
||||
{
|
||||
// This will be used to set up the file picker "filter", to select .txt
|
||||
// files by default.
|
||||
@@ -401,7 +400,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - Removes the tab (both TerminalControl and XAML) after prompting for approval
|
||||
// Arguments:
|
||||
// - tab: the tab to remove
|
||||
winrt::Windows::Foundation::IAsyncAction TerminalPage::_HandleCloseTabRequested(winrt::TerminalApp::TabBase tab)
|
||||
winrt::Windows::Foundation::IAsyncAction TerminalPage::_HandleCloseTabRequested(winrt::TerminalApp::Tab tab)
|
||||
{
|
||||
if (tab.ReadOnly())
|
||||
{
|
||||
@@ -414,7 +413,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
auto t = winrt::get_self<implementation::TabBase>(tab);
|
||||
auto t = winrt::get_self<implementation::Tab>(tab);
|
||||
auto actions = t->BuildStartupActions(BuildStartupKind::None);
|
||||
_AddPreviouslyClosedPaneOrTab(std::move(actions));
|
||||
|
||||
@@ -425,7 +424,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - Removes the tab (both TerminalControl and XAML)
|
||||
// Arguments:
|
||||
// - tab: the tab to remove
|
||||
void TerminalPage::_RemoveTab(const winrt::TerminalApp::TabBase& tab)
|
||||
void TerminalPage::_RemoveTab(const winrt::TerminalApp::Tab& tab)
|
||||
{
|
||||
uint32_t tabIndex{};
|
||||
if (!_tabs.IndexOf(tab, tabIndex))
|
||||
@@ -597,7 +596,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - tab - tab to select
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalPage::_OnSwitchToTabRequested(const IInspectable& /*sender*/, const winrt::TerminalApp::TabBase& tab)
|
||||
void TerminalPage::_OnSwitchToTabRequested(const IInspectable& /*sender*/, const winrt::TerminalApp::Tab& tab)
|
||||
{
|
||||
uint32_t index{};
|
||||
if (_tabs.IndexOf(tab, index))
|
||||
@@ -628,7 +627,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// no tab is currently selected, returns nullopt.
|
||||
// Return Value:
|
||||
// - the index of the currently focused tab if there is one, else nullopt
|
||||
std::optional<uint32_t> TerminalPage::_GetTabIndex(const TerminalApp::TabBase& tab) const noexcept
|
||||
std::optional<uint32_t> TerminalPage::_GetTabIndex(const TerminalApp::Tab& tab) const noexcept
|
||||
{
|
||||
uint32_t i;
|
||||
if (_tabs.IndexOf(tab, i))
|
||||
@@ -641,7 +640,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// Method Description:
|
||||
// - returns the currently focused tab. This might return null,
|
||||
// so make sure to check the result!
|
||||
winrt::TerminalApp::TabBase TerminalPage::_GetFocusedTab() const noexcept
|
||||
winrt::TerminalApp::Tab TerminalPage::_GetFocusedTab() const noexcept
|
||||
{
|
||||
if (auto index{ _GetFocusedTabIndex() })
|
||||
{
|
||||
@@ -653,11 +652,11 @@ namespace winrt::TerminalApp::implementation
|
||||
// Method Description:
|
||||
// - returns a com_ptr to the currently focused tab implementation. This might return null,
|
||||
// so make sure to check the result!
|
||||
winrt::com_ptr<TerminalTab> TerminalPage::_GetFocusedTabImpl() const noexcept
|
||||
winrt::com_ptr<Tab> TerminalPage::_GetFocusedTabImpl() const noexcept
|
||||
{
|
||||
if (auto tab{ _GetFocusedTab() })
|
||||
{
|
||||
return _GetTerminalTabImpl(tab);
|
||||
return _GetTabImpl(tab);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -665,7 +664,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// Method Description:
|
||||
// - returns a tab corresponding to a view item. This might return null,
|
||||
// so make sure to check the result!
|
||||
winrt::TerminalApp::TabBase TerminalPage::_GetTabByTabViewItem(const Microsoft::UI::Xaml::Controls::TabViewItem& tabViewItem) const noexcept
|
||||
winrt::TerminalApp::Tab TerminalPage::_GetTabByTabViewItem(const Microsoft::UI::Xaml::Controls::TabViewItem& tabViewItem) const noexcept
|
||||
{
|
||||
uint32_t tabIndexFromControl{};
|
||||
const auto items{ _tabView.TabItems() };
|
||||
@@ -687,7 +686,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - tab: tab to focus.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
safe_void_coroutine TerminalPage::_SetFocusedTab(const winrt::TerminalApp::TabBase tab)
|
||||
safe_void_coroutine TerminalPage::_SetFocusedTab(const winrt::TerminalApp::Tab tab)
|
||||
{
|
||||
// GH#1117: This is a workaround because _tabView.SelectedIndex(tabIndex)
|
||||
// sometimes set focus to an incorrect tab after removing some tabs
|
||||
@@ -774,11 +773,11 @@ namespace winrt::TerminalApp::implementation
|
||||
// tab's Closed event.
|
||||
safe_void_coroutine TerminalPage::_CloseFocusedPane()
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto activeTab{ _GetFocusedTabImpl() })
|
||||
{
|
||||
_UnZoomIfNeeded();
|
||||
|
||||
if (const auto pane{ terminalTab->GetActivePane() })
|
||||
if (const auto pane{ activeTab->GetActivePane() })
|
||||
{
|
||||
if (co_await _PaneConfirmCloseReadOnly(pane))
|
||||
{
|
||||
@@ -793,7 +792,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// Arguments:
|
||||
// - weakTab: weak reference to the tab that the pane belongs to.
|
||||
// - paneIds: collection of the IDs of the panes that are marked for removal.
|
||||
void TerminalPage::_ClosePanes(weak_ref<TerminalTab> weakTab, std::vector<uint32_t> paneIds)
|
||||
void TerminalPage::_ClosePanes(weak_ref<Tab> weakTab, std::vector<uint32_t> paneIds)
|
||||
{
|
||||
if (auto strongTab{ weakTab.get() })
|
||||
{
|
||||
@@ -838,7 +837,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - Closes provided tabs one by one
|
||||
// Arguments:
|
||||
// - tabs - tabs to remove
|
||||
safe_void_coroutine TerminalPage::_RemoveTabs(const std::vector<winrt::TerminalApp::TabBase> tabs)
|
||||
safe_void_coroutine TerminalPage::_RemoveTabs(const std::vector<winrt::TerminalApp::Tab> tabs)
|
||||
{
|
||||
for (auto& tab : tabs)
|
||||
{
|
||||
@@ -926,7 +925,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
// WinUI asynchronously updates its tab view items, so it may happen that we're given a
|
||||
// `TabViewItem` that still contains a `TabBase` which has actually already been removed.
|
||||
// `TabViewItem` that still contains a `Tab` which has actually already been removed.
|
||||
// First we must yield once, to flush out whatever TabView is currently doing.
|
||||
const auto strong = get_strong();
|
||||
co_await wil::resume_foreground(Dispatcher());
|
||||
@@ -966,7 +965,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPage::_UpdatedSelectedTab(const winrt::TerminalApp::TabBase& tab)
|
||||
void TerminalPage::_UpdatedSelectedTab(const winrt::TerminalApp::Tab& tab)
|
||||
{
|
||||
// Unfocus all the tabs.
|
||||
for (const auto& tab : _tabs)
|
||||
@@ -1007,10 +1006,10 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
_updateThemeColors();
|
||||
|
||||
auto tab_impl = _GetTerminalTabImpl(tab);
|
||||
if (tab_impl)
|
||||
auto tabImpl = _GetTabImpl(tab);
|
||||
if (tabImpl)
|
||||
{
|
||||
auto profile = tab_impl->GetFocusedProfile();
|
||||
auto profile = tabImpl->GetFocusedProfile();
|
||||
_UpdateBackground(profile);
|
||||
}
|
||||
}
|
||||
@@ -1057,7 +1056,7 @@ namespace winrt::TerminalApp::implementation
|
||||
for (uint32_t i = 0; i < size; ++i)
|
||||
{
|
||||
auto tab{ _tabs.GetAt(i) };
|
||||
auto tabImpl{ winrt::get_self<TabBase>(tab) };
|
||||
auto tabImpl{ winrt::get_self<Tab>(tab) };
|
||||
tabImpl->UpdateTabViewIndex(i, size);
|
||||
}
|
||||
}
|
||||
@@ -1068,7 +1067,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - tab: tab to bump.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalPage::_UpdateMRUTab(const winrt::TerminalApp::TabBase& tab)
|
||||
void TerminalPage::_UpdateMRUTab(const winrt::TerminalApp::Tab& tab)
|
||||
{
|
||||
uint32_t mruIndex;
|
||||
if (_mruTabs.IndexOf(tab, mruIndex))
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "PaletteItem.h"
|
||||
#include "TabPaletteItem.g.h"
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
struct TabPaletteItem : TabPaletteItemT<TabPaletteItem, PaletteItem>
|
||||
{
|
||||
TabPaletteItem() = default;
|
||||
TabPaletteItem(const winrt::TerminalApp::TabBase& tab);
|
||||
|
||||
winrt::TerminalApp::TabBase Tab() const noexcept
|
||||
{
|
||||
return _tab.get();
|
||||
}
|
||||
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::TerminalApp::TerminalTabStatus, TabStatus, PropertyChanged.raise);
|
||||
|
||||
private:
|
||||
winrt::weak_ref<winrt::TerminalApp::TabBase> _tab;
|
||||
Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker _tabChangedRevoker;
|
||||
Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker _tabStatusChangedRevoker;
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::TerminalApp::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(TabPaletteItem);
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "PaletteItem.idl";
|
||||
import "TabBase.idl";
|
||||
import "TerminalTabStatus.idl";
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
[default_interface] runtimeclass TabPaletteItem : PaletteItem
|
||||
{
|
||||
TabPaletteItem(TabBase tab);
|
||||
|
||||
TabBase Tab { get; };
|
||||
|
||||
TerminalTabStatus TabStatus { get; };
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,8 @@
|
||||
<Page Include="TabHeaderControl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="HighlightedTextControl.xaml">
|
||||
<Page Include="HighlightedTextControlStyle.xaml">
|
||||
<Type>DefaultStyle</Type>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="ColorPickupFlyout.xaml">
|
||||
@@ -81,11 +82,10 @@
|
||||
</ItemGroup>
|
||||
<!-- ========================= Headers ======================== -->
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ActionPaletteItem.h" />
|
||||
<ClInclude Include="App.base.h" />
|
||||
<ClInclude Include="AppCommandlineArgs.h" />
|
||||
<ClInclude Include="Commandline.h" />
|
||||
<ClInclude Include="CommandLinePaletteItem.h" />
|
||||
<ClInclude Include="CommandPaletteItems.h" />
|
||||
<ClInclude Include="Jumplist.h" />
|
||||
<ClInclude Include="LanguageProfileNotifier.h" />
|
||||
<ClInclude Include="MinMaxCloseControl.h">
|
||||
@@ -98,17 +98,13 @@
|
||||
<DependentUpon>PaletteItemTemplateSelector.idl</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PaletteItem.h" />
|
||||
<ClInclude Include="TabBase.h">
|
||||
<DependentUpon>TabBase.idl</DependentUpon>
|
||||
<ClInclude Include="BasePaletteItem.h" />
|
||||
<ClInclude Include="Tab.h">
|
||||
<DependentUpon>Tab.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TabPaletteItem.h" />
|
||||
<ClInclude Include="TaskbarState.h">
|
||||
<DependentUpon>TaskbarState.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TerminalTab.h">
|
||||
<DependentUpon>TerminalTab.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TerminalPage.h">
|
||||
<DependentUpon>TerminalPage.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
@@ -127,9 +123,8 @@
|
||||
<DependentUpon>TabHeaderControl.xaml</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="HighlightedTextControl.h">
|
||||
<DependentUpon>HighlightedTextControl.xaml</DependentUpon>
|
||||
<DependentUpon>HighlightedTextControl.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="HighlightedText.h" />
|
||||
<ClInclude Include="ColorPickupFlyout.h">
|
||||
<DependentUpon>ColorPickupFlyout.xaml</DependentUpon>
|
||||
</ClInclude>
|
||||
@@ -139,7 +134,6 @@
|
||||
<ClInclude Include="FilteredCommand.h" />
|
||||
<ClInclude Include="Pane.h" />
|
||||
<ClInclude Include="fzf/fzf.h" />
|
||||
<ClInclude Include="ColorHelper.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="ShortcutActionDispatch.h">
|
||||
<DependentUpon>ShortcutActionDispatch.idl</DependentUpon>
|
||||
@@ -192,11 +186,10 @@
|
||||
</ItemGroup>
|
||||
<!-- ========================= Cpp Files ======================== -->
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ActionPaletteItem.cpp" />
|
||||
<ClCompile Include="CommandLinePaletteItem.cpp" />
|
||||
<ClCompile Include="init.cpp" />
|
||||
<ClCompile Include="AppCommandlineArgs.cpp" />
|
||||
<ClCompile Include="Commandline.cpp" />
|
||||
<ClCompile Include="CommandPaletteItems.cpp" />
|
||||
<ClCompile Include="Jumplist.cpp" />
|
||||
<ClCompile Include="LanguageProfileNotifier.cpp" />
|
||||
<ClCompile Include="MinMaxCloseControl.cpp">
|
||||
@@ -209,18 +202,13 @@
|
||||
<DependentUpon>PaletteItemTemplateSelector.idl</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PaletteItem.cpp" />
|
||||
<ClCompile Include="TabBase.cpp">
|
||||
<DependentUpon>TabBase.idl</DependentUpon>
|
||||
<ClCompile Include="Tab.cpp">
|
||||
<DependentUpon>Tab.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="fzf/fzf.cpp" />
|
||||
<ClCompile Include="TabPaletteItem.cpp" />
|
||||
<ClCompile Include="TaskbarState.cpp">
|
||||
<DependentUpon>TaskbarState.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TerminalTab.cpp">
|
||||
<DependentUpon>TerminalTab.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TerminalPage.cpp">
|
||||
<DependentUpon>TerminalPage.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
@@ -247,9 +235,8 @@
|
||||
<DependentUpon>TabHeaderControl.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="HighlightedTextControl.cpp">
|
||||
<DependentUpon>HighlightedTextControl.xaml</DependentUpon>
|
||||
<DependentUpon>HighlightedTextControl.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="HighlightedText.cpp" />
|
||||
<ClCompile Include="ColorPickupFlyout.cpp">
|
||||
<DependentUpon>ColorPickupFlyout.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
@@ -259,9 +246,6 @@
|
||||
<ClCompile Include="FilteredCommand.cpp" />
|
||||
<ClCompile Include="Pane.cpp" />
|
||||
<ClCompile Include="Pane.LayoutSizeNode.cpp" />
|
||||
<ClCompile Include="ColorHelper.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DebugTapConnection.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
@@ -320,8 +304,6 @@
|
||||
<ItemGroup>
|
||||
<!-- If you add idl files here, make sure to include their implementation's
|
||||
header in TerminalApp.vcxproj (as well as in this file) -->
|
||||
<Midl Include="ActionPaletteItem.idl" />
|
||||
<Midl Include="CommandLinePaletteItem.idl" />
|
||||
<Midl Include="AboutDialog.idl">
|
||||
<DependentUpon>AboutDialog.xaml</DependentUpon>
|
||||
</Midl>
|
||||
@@ -332,7 +314,7 @@
|
||||
<Midl Include="PaletteItemTemplateSelector.idl">
|
||||
<SubType>Designer</SubType>
|
||||
</Midl>
|
||||
<Midl Include="PaletteItem.idl" />
|
||||
<Midl Include="IPaletteItem.idl" />
|
||||
<Midl Include="ShortcutActionDispatch.idl" />
|
||||
<Midl Include="AppKeyBindings.idl" />
|
||||
<Midl Include="AppLogic.idl" />
|
||||
@@ -341,10 +323,8 @@
|
||||
<DependentUpon>MinMaxCloseControl.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="TabBase.idl" />
|
||||
<Midl Include="TabPaletteItem.idl" />
|
||||
<Midl Include="Tab.idl" />
|
||||
<Midl Include="TaskbarState.idl" />
|
||||
<Midl Include="TerminalTab.idl" />
|
||||
<Midl Include="TerminalPage.idl">
|
||||
<DependentUpon>TerminalPage.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
@@ -365,10 +345,8 @@
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="HighlightedTextControl.idl">
|
||||
<DependentUpon>HighlightedTextControl.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="HighlightedText.idl" />
|
||||
<Midl Include="ColorPickupFlyout.idl">
|
||||
<DependentUpon>ColorPickupFlyout.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
|
||||
@@ -20,27 +20,14 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="AppCommandlineArgs.cpp" />
|
||||
<ClCompile Include="Commandline.cpp" />
|
||||
<ClCompile Include="ColorHelper.cpp" />
|
||||
<ClCompile Include="DebugTapConnection.cpp" />
|
||||
<ClCompile Include="Jumplist.cpp" />
|
||||
<ClCompile Include="FilteredCommand.cpp">
|
||||
<Filter>commandPalette</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ActionPaletteItem.cpp">
|
||||
<ClCompile Include="CommandPaletteItems.cpp">
|
||||
<Filter>commandPalette</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PaletteItem.cpp">
|
||||
<Filter>commandPalette</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TabPaletteItem.cpp">
|
||||
<Filter>commandPalette</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CommandLinePaletteItem.cpp">
|
||||
<Filter>commandPalette</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="HighlightedText.cpp">
|
||||
<Filter>highlightedText</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="fzf/fzf.cpp">
|
||||
<Filter>fzf</Filter>
|
||||
</ClCompile>
|
||||
@@ -60,26 +47,16 @@
|
||||
<ClInclude Include="AppCommandlineArgs.h" />
|
||||
<ClInclude Include="Commandline.h" />
|
||||
<ClInclude Include="DebugTapConnection.h" />
|
||||
<ClInclude Include="ColorHelper.h" />
|
||||
<ClInclude Include="Jumplist.h" />
|
||||
<ClInclude Include="FilteredCommand.h">
|
||||
<Filter>commandPalette</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ActionPaletteItem.h">
|
||||
<ClInclude Include="CommandPaletteItems.h">
|
||||
<Filter>commandPalette</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PaletteItem.h">
|
||||
<ClInclude Include="BasePaletteItem.h">
|
||||
<Filter>commandPalette</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TabPaletteItem.h">
|
||||
<Filter>commandPalette</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CommandLinePaletteItem.h">
|
||||
<Filter>commandPalette</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="HighlightedText.h">
|
||||
<Filter>highlightedText</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="fzf/fzf.h">
|
||||
<Filter>fzf</Filter>
|
||||
</ClInclude>
|
||||
@@ -102,20 +79,14 @@
|
||||
<Midl Include="ShortcutActionDispatch.idl">
|
||||
<Filter>settings</Filter>
|
||||
</Midl>
|
||||
<Midl Include="TerminalTab.idl">
|
||||
<Filter>tab</Filter>
|
||||
</Midl>
|
||||
<Midl Include="FilteredCommand.idl">
|
||||
<Filter>commandPalette</Filter>
|
||||
</Midl>
|
||||
<Midl Include="HighlightedText.idl">
|
||||
<Filter>highlightedText</Filter>
|
||||
</Midl>
|
||||
<Midl Include="TerminalTabStatus.idl">
|
||||
<Filter>tab</Filter>
|
||||
</Midl>
|
||||
<Midl Include="PaletteItemTemplateSelector.idl" />
|
||||
<Midl Include="TabBase.idl" />
|
||||
<Midl Include="Tab.idl" />
|
||||
<Midl Include="TerminalWindow.idl" />
|
||||
<Midl Include="TaskbarState.idl" />
|
||||
<Midl Include="IPaneContent.idl" />
|
||||
@@ -144,19 +115,10 @@
|
||||
<Page Include="CommandPalette.xaml">
|
||||
<Filter>commandPalette</Filter>
|
||||
</Page>
|
||||
<Midl Include="PaletteItem.idl">
|
||||
<Midl Include="IPaletteItem.idl">
|
||||
<Filter>commandPalette</Filter>
|
||||
</Midl>
|
||||
<Midl Include="TabPaletteItem.idl">
|
||||
<Filter>commandPalette</Filter>
|
||||
</Midl>
|
||||
<Midl Include="ActionPaletteItem.idl">
|
||||
<Filter>commandPalette</Filter>
|
||||
</Midl>
|
||||
<Midl Include="CommandLinePaletteItem.idl">
|
||||
<Filter>commandPalette</Filter>
|
||||
</Midl>
|
||||
<Page Include="HighlightedTextControl.xaml">
|
||||
<Page Include="HighlightedTextControlStyle.xaml">
|
||||
<Filter>highlightedText</Filter>
|
||||
</Page>
|
||||
<Page Include="AboutDialog.xaml" />
|
||||
|
||||
@@ -6,24 +6,24 @@
|
||||
#include "TerminalPage.h"
|
||||
|
||||
#include <LibraryResources.h>
|
||||
#include <TerminalCore/ControlKeyStates.hpp>
|
||||
#include <Utils.h>
|
||||
#include <TerminalCore/ControlKeyStates.hpp>
|
||||
|
||||
#include "../../types/inc/utils.hpp"
|
||||
#include "App.h"
|
||||
#include "ColorHelper.h"
|
||||
#include "DebugTapConnection.h"
|
||||
#include "SettingsPaneContent.h"
|
||||
#include "ScratchpadContent.h"
|
||||
#include "SnippetsPaneContent.h"
|
||||
#include "MarkdownPaneContent.h"
|
||||
#include "TabRowControl.h"
|
||||
#include "Remoting.h"
|
||||
#include "ScratchpadContent.h"
|
||||
#include "SettingsPaneContent.h"
|
||||
#include "SnippetsPaneContent.h"
|
||||
#include "TabRowControl.h"
|
||||
#include "../../types/inc/ColorFix.hpp"
|
||||
#include "../../types/inc/utils.hpp"
|
||||
|
||||
#include "TerminalPage.g.cpp"
|
||||
#include "LaunchPositionRequest.g.cpp"
|
||||
#include "RenameWindowRequestedArgs.g.cpp"
|
||||
#include "RequestMoveContentArgs.g.cpp"
|
||||
#include "LaunchPositionRequest.g.cpp"
|
||||
#include "TerminalPage.g.cpp"
|
||||
|
||||
using namespace winrt;
|
||||
using namespace winrt::Microsoft::Management::Deployment;
|
||||
@@ -59,8 +59,8 @@ namespace winrt
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
TerminalPage::TerminalPage(TerminalApp::WindowProperties properties, const TerminalApp::ContentManager& manager) :
|
||||
_tabs{ winrt::single_threaded_observable_vector<TerminalApp::TabBase>() },
|
||||
_mruTabs{ winrt::single_threaded_observable_vector<TerminalApp::TabBase>() },
|
||||
_tabs{ winrt::single_threaded_observable_vector<TerminalApp::Tab>() },
|
||||
_mruTabs{ winrt::single_threaded_observable_vector<TerminalApp::Tab>() },
|
||||
_manager{ manager },
|
||||
_hostingHwnd{},
|
||||
_WindowProperties{ std::move(properties) }
|
||||
@@ -84,9 +84,9 @@ namespace winrt::TerminalApp::implementation
|
||||
// GH#13211 - if we haven't yet set the owning hwnd, reparent all the controls now.
|
||||
for (const auto& tab : _tabs)
|
||||
{
|
||||
if (auto terminalTab{ _GetTerminalTabImpl(tab) })
|
||||
if (auto tabImpl{ _GetTabImpl(tab) })
|
||||
{
|
||||
terminalTab->GetRootPane()->WalkTree([&](auto&& pane) {
|
||||
tabImpl->GetRootPane()->WalkTree([&](auto&& pane) {
|
||||
if (const auto& term{ pane->GetTerminalControl() })
|
||||
{
|
||||
term.OwningHwnd(reinterpret_cast<uint64_t>(hwnd));
|
||||
@@ -237,6 +237,14 @@ namespace winrt::TerminalApp::implementation
|
||||
_newTabButton.Click([weakThis{ get_weak() }](auto&&, auto&&) {
|
||||
if (auto page{ weakThis.get() })
|
||||
{
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalAppProvider,
|
||||
"NewTabMenuDefaultButtonClicked",
|
||||
TraceLoggingDescription("Event emitted when the default button from the new tab split button is invoked"),
|
||||
TraceLoggingValue(page->NumberOfTabs(), "TabCount", "The count of tabs currently opened in this window"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
|
||||
page->_OpenNewTerminalViaDropdown(NewTerminalArgs());
|
||||
}
|
||||
});
|
||||
@@ -558,9 +566,9 @@ namespace winrt::TerminalApp::implementation
|
||||
// GH#6586: now that we're done processing all startup commands,
|
||||
// focus the active control. This will work as expected for both
|
||||
// commandline invocations and for `wt` action invocations.
|
||||
if (const auto& terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto& tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
if (const auto& content{ terminalTab->GetActiveContent() })
|
||||
if (const auto& content{ tabImpl->GetActiveContent() })
|
||||
{
|
||||
content.Focus(FocusState::Programmatic);
|
||||
}
|
||||
@@ -834,14 +842,36 @@ namespace winrt::TerminalApp::implementation
|
||||
// Since the previous focus location might be discarded in the background,
|
||||
// e.g., the command palette will be dismissed by the menu,
|
||||
// and then closing the fly-out will move the focus to wrong location.
|
||||
newTabFlyout.Opening([this](auto&&, auto&&) {
|
||||
_FocusCurrentTab(true);
|
||||
newTabFlyout.Opening([weakThis{ get_weak() }](auto&&, auto&&) {
|
||||
if (auto page{ weakThis.get() })
|
||||
{
|
||||
page->_FocusCurrentTab(true);
|
||||
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalAppProvider,
|
||||
"NewTabMenuOpened",
|
||||
TraceLoggingDescription("Event emitted when the new tab menu is opened"),
|
||||
TraceLoggingValue(page->NumberOfTabs(), "TabCount", "The Count of tabs currently opened in this window"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
}
|
||||
});
|
||||
// Necessary for fly-out sub items to get focus on a tab before collapsing. Related to #15049
|
||||
newTabFlyout.Closing([this](auto&&, auto&&) {
|
||||
if (!_commandPaletteIs(Visibility::Visible))
|
||||
newTabFlyout.Closing([weakThis{ get_weak() }](auto&&, auto&&) {
|
||||
if (auto page{ weakThis.get() })
|
||||
{
|
||||
_FocusCurrentTab(true);
|
||||
if (!page->_commandPaletteIs(Visibility::Visible))
|
||||
{
|
||||
page->_FocusCurrentTab(true);
|
||||
}
|
||||
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalAppProvider,
|
||||
"NewTabMenuClosed",
|
||||
TraceLoggingDescription("Event emitted when the new tab menu is closed"),
|
||||
TraceLoggingValue(page->NumberOfTabs(), "TabCount", "The Count of tabs currently opened in this window"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
}
|
||||
});
|
||||
_newTabButton.Flyout(newTabFlyout);
|
||||
@@ -1047,6 +1077,15 @@ namespace winrt::TerminalApp::implementation
|
||||
profileMenuItem.Click([profileIndex, weakThis{ get_weak() }](auto&&, auto&&) {
|
||||
if (auto page{ weakThis.get() })
|
||||
{
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalAppProvider,
|
||||
"NewTabMenuItemClicked",
|
||||
TraceLoggingDescription("Event emitted when an item from the new tab menu is invoked"),
|
||||
TraceLoggingValue(page->NumberOfTabs(), "TabCount", "The count of tabs currently opened in this window"),
|
||||
TraceLoggingValue("Profile", "ItemType", "The type of item that was clicked in the new tab menu"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
|
||||
NewTerminalArgs newTerminalArgs{ profileIndex };
|
||||
page->_OpenNewTerminalViaDropdown(newTerminalArgs);
|
||||
}
|
||||
@@ -1093,6 +1132,15 @@ namespace winrt::TerminalApp::implementation
|
||||
actionMenuItem.Click([action, weakThis{ get_weak() }](auto&&, auto&&) {
|
||||
if (auto page{ weakThis.get() })
|
||||
{
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalAppProvider,
|
||||
"NewTabMenuItemClicked",
|
||||
TraceLoggingDescription("Event emitted when an item from the new tab menu is invoked"),
|
||||
TraceLoggingValue(page->NumberOfTabs(), "TabCount", "The count of tabs currently opened in this window"),
|
||||
TraceLoggingValue("Action", "ItemType", "The type of item that was clicked in the new tab menu"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
|
||||
page->_actionDispatch->DoAction(action.ActionAndArgs());
|
||||
}
|
||||
});
|
||||
@@ -1154,6 +1202,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
const auto dispatchToElevatedWindow = ctrlPressed && !IsRunningElevated();
|
||||
|
||||
auto sessionType = "";
|
||||
if ((shiftPressed || dispatchToElevatedWindow) && !debugTap)
|
||||
{
|
||||
// Manually fill in the evaluated profile.
|
||||
@@ -1171,10 +1220,12 @@ namespace winrt::TerminalApp::implementation
|
||||
if (dispatchToElevatedWindow)
|
||||
{
|
||||
_OpenElevatedWT(newTerminalArgs);
|
||||
sessionType = "ElevatedWindow";
|
||||
}
|
||||
else
|
||||
{
|
||||
_OpenNewWindow(newTerminalArgs);
|
||||
sessionType = "Window";
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1193,12 +1244,23 @@ namespace winrt::TerminalApp::implementation
|
||||
SplitDirection::Automatic,
|
||||
0.5f,
|
||||
newPane);
|
||||
sessionType = "Pane";
|
||||
}
|
||||
else
|
||||
{
|
||||
_CreateNewTabFromPane(newPane);
|
||||
sessionType = "Tab";
|
||||
}
|
||||
}
|
||||
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalAppProvider,
|
||||
"NewTabMenuCreatedNewTerminalSession",
|
||||
TraceLoggingDescription("Event emitted when a new terminal was created via the new tab menu"),
|
||||
TraceLoggingValue(NumberOfTabs(), "NewTabCount", "The count of tabs currently opened in this window"),
|
||||
TraceLoggingValue(sessionType, "SessionType", "The type of session that was created"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
}
|
||||
|
||||
std::wstring TerminalPage::_evaluatePathForCwd(const std::wstring_view path)
|
||||
@@ -1405,6 +1467,30 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
target = SettingsTarget::DefaultsFile;
|
||||
}
|
||||
|
||||
const auto targetAsString = [&target]() {
|
||||
switch (target)
|
||||
{
|
||||
case SettingsTarget::SettingsFile:
|
||||
return "SettingsFile";
|
||||
case SettingsTarget::DefaultsFile:
|
||||
return "DefaultsFile";
|
||||
case SettingsTarget::SettingsUI:
|
||||
default:
|
||||
return "UI";
|
||||
}
|
||||
}();
|
||||
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalAppProvider,
|
||||
"NewTabMenuItemClicked",
|
||||
TraceLoggingDescription("Event emitted when an item from the new tab menu is invoked"),
|
||||
TraceLoggingValue(NumberOfTabs(), "TabCount", "The count of tabs currently opened in this window"),
|
||||
TraceLoggingValue("Settings", "ItemType", "The type of item that was clicked in the new tab menu"),
|
||||
TraceLoggingValue(targetAsString, "SettingsTarget", "The target settings file or UI"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
|
||||
_LaunchSettings(target);
|
||||
}
|
||||
|
||||
@@ -1416,6 +1502,15 @@ namespace winrt::TerminalApp::implementation
|
||||
auto p = LoadCommandPalette();
|
||||
p.EnableCommandPaletteMode(CommandPaletteLaunchMode::Action);
|
||||
p.Visibility(Visibility::Visible);
|
||||
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalAppProvider,
|
||||
"NewTabMenuItemClicked",
|
||||
TraceLoggingDescription("Event emitted when an item from the new tab menu is invoked"),
|
||||
TraceLoggingValue(NumberOfTabs(), "TabCount", "The count of tabs currently opened in this window"),
|
||||
TraceLoggingValue("CommandPalette", "ItemType", "The type of item that was clicked in the new tab menu"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -1428,6 +1523,15 @@ namespace winrt::TerminalApp::implementation
|
||||
const RoutedEventArgs&)
|
||||
{
|
||||
_ShowAboutDialog();
|
||||
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalAppProvider,
|
||||
"NewTabMenuItemClicked",
|
||||
TraceLoggingDescription("Event emitted when an item from the new tab menu is invoked"),
|
||||
TraceLoggingValue(NumberOfTabs(), "TabCount", "The count of tabs currently opened in this window"),
|
||||
TraceLoggingValue("About", "ItemType", "The type of item that was clicked in the new tab menu"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -1651,7 +1755,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// TitleChanged event.
|
||||
// Arguments:
|
||||
// - tab: the Tab to update the title for.
|
||||
void TerminalPage::_UpdateTitle(const TerminalTab& tab)
|
||||
void TerminalPage::_UpdateTitle(const Tab& tab)
|
||||
{
|
||||
auto newTabTitle = tab.Title();
|
||||
|
||||
@@ -1729,13 +1833,13 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Connects event handlers to the TerminalTab for events that we want to
|
||||
// - Connects event handlers to the Tab for events that we want to
|
||||
// handle. This includes:
|
||||
// * the TitleChanged event, for changing the text of the tab
|
||||
// * the Color{Selected,Cleared} events to change the color of a tab.
|
||||
// Arguments:
|
||||
// - hostingTab: The Tab that's hosting this TermControl instance
|
||||
void TerminalPage::_RegisterTabEvents(TerminalTab& hostingTab)
|
||||
void TerminalPage::_RegisterTabEvents(Tab& hostingTab)
|
||||
{
|
||||
auto weakTab{ hostingTab.get_weak() };
|
||||
auto weakThis{ get_weak() };
|
||||
@@ -1818,9 +1922,9 @@ namespace winrt::TerminalApp::implementation
|
||||
// to the terminal when no other panes are present (GH#6219)
|
||||
bool TerminalPage::_MoveFocus(const FocusDirection& direction)
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
return terminalTab->NavigateFocus(direction);
|
||||
return tabImpl->NavigateFocus(direction);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1834,19 +1938,19 @@ namespace winrt::TerminalApp::implementation
|
||||
// - true if panes were swapped.
|
||||
bool TerminalPage::_SwapPane(const FocusDirection& direction)
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
_UnZoomIfNeeded();
|
||||
return terminalTab->SwapPane(direction);
|
||||
return tabImpl->SwapPane(direction);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
TermControl TerminalPage::_GetActiveControl()
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
return terminalTab->GetActiveTerminalControl();
|
||||
return tabImpl->GetActiveTerminalControl();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1953,7 +2057,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
for (auto tab : _tabs)
|
||||
{
|
||||
auto t = winrt::get_self<implementation::TabBase>(tab);
|
||||
auto t = winrt::get_self<implementation::Tab>(tab);
|
||||
auto tabActions = t->BuildStartupActions(serializeBuffer ? BuildStartupKind::PersistAll : BuildStartupKind::PersistLayout);
|
||||
actions.insert(actions.end(), std::make_move_iterator(tabActions.begin()), std::make_move_iterator(tabActions.end()));
|
||||
}
|
||||
@@ -2048,14 +2152,14 @@ namespace winrt::TerminalApp::implementation
|
||||
// - rowsToScroll: a number of lines to move the viewport. If not provided we will use a system default.
|
||||
void TerminalPage::_Scroll(ScrollDirection scrollDirection, const Windows::Foundation::IReference<uint32_t>& rowsToScroll)
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
uint32_t realRowsToScroll;
|
||||
if (rowsToScroll == nullptr)
|
||||
{
|
||||
// The magic value of WHEEL_PAGESCROLL indicates that we need to scroll the entire page
|
||||
realRowsToScroll = _systemRowsToScroll == WHEEL_PAGESCROLL ?
|
||||
terminalTab->GetActiveTerminalControl().ViewHeight() :
|
||||
tabImpl->GetActiveTerminalControl().ViewHeight() :
|
||||
_systemRowsToScroll;
|
||||
}
|
||||
else
|
||||
@@ -2064,7 +2168,7 @@ namespace winrt::TerminalApp::implementation
|
||||
realRowsToScroll = rowsToScroll.Value();
|
||||
}
|
||||
auto scrollDelta = _ComputeScrollDelta(scrollDirection, realRowsToScroll);
|
||||
terminalTab->Scroll(scrollDelta);
|
||||
tabImpl->Scroll(scrollDelta);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2095,9 +2199,9 @@ namespace winrt::TerminalApp::implementation
|
||||
// specified window instead of moving it in our tab row.
|
||||
if (!windowId.empty())
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
if (const auto pane{ terminalTab->GetActivePane() })
|
||||
if (const auto pane{ tabImpl->GetActivePane() })
|
||||
{
|
||||
auto startupActions = pane->BuildStartupActions(0, 1, BuildStartupKind::MovePane);
|
||||
_DetachPaneFromWindow(pane);
|
||||
@@ -2136,7 +2240,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// tab before its index changes.
|
||||
if (tabIdx < _tabs.Size())
|
||||
{
|
||||
auto targetTab = _GetTerminalTabImpl(_tabs.GetAt(tabIdx));
|
||||
auto targetTab = _GetTabImpl(_tabs.GetAt(tabIdx));
|
||||
// if the selected tab is not a host of terminals (e.g. settings)
|
||||
// don't attempt to add a pane to it.
|
||||
if (!targetTab)
|
||||
@@ -2184,15 +2288,12 @@ namespace winrt::TerminalApp::implementation
|
||||
});
|
||||
}
|
||||
|
||||
void TerminalPage::_DetachTabFromWindow(const winrt::com_ptr<TabBase>& tab)
|
||||
void TerminalPage::_DetachTabFromWindow(const winrt::com_ptr<Tab>& tab)
|
||||
{
|
||||
if (const auto terminalTab = tab.try_as<TerminalTab>())
|
||||
// Detach the root pane, which will act like the whole tab got detached.
|
||||
if (const auto rootPane = tab->GetRootPane())
|
||||
{
|
||||
// Detach the root pane, which will act like the whole tab got detached.
|
||||
if (const auto rootPane = terminalTab->GetRootPane())
|
||||
{
|
||||
_DetachPaneFromWindow(rootPane);
|
||||
}
|
||||
_DetachPaneFromWindow(rootPane);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2220,7 +2321,7 @@ namespace winrt::TerminalApp::implementation
|
||||
RequestMoveContent.raise(*this, *request);
|
||||
}
|
||||
|
||||
bool TerminalPage::_MoveTab(winrt::com_ptr<TerminalTab> tab, MoveTabArgs args)
|
||||
bool TerminalPage::_MoveTab(winrt::com_ptr<Tab> tab, MoveTabArgs args)
|
||||
{
|
||||
if (!tab)
|
||||
{
|
||||
@@ -2288,10 +2389,10 @@ namespace winrt::TerminalApp::implementation
|
||||
// When the tab's active pane changes, we'll want to lookup a new icon
|
||||
// for it. The Title change will be propagated upwards through the tab's
|
||||
// PropertyChanged event handler.
|
||||
void TerminalPage::_activePaneChanged(winrt::TerminalApp::TerminalTab sender,
|
||||
void TerminalPage::_activePaneChanged(winrt::TerminalApp::Tab sender,
|
||||
Windows::Foundation::IInspectable /*args*/)
|
||||
{
|
||||
if (const auto tab{ _GetTerminalTabImpl(sender) })
|
||||
if (const auto tab{ _GetTabImpl(sender) })
|
||||
{
|
||||
// Possibly update the icon of the tab.
|
||||
_UpdateTabIcon(*tab);
|
||||
@@ -2380,7 +2481,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - splitDirection: one value from the TerminalApp::SplitDirection enum, indicating how the
|
||||
// new pane should be split from its parent.
|
||||
// - splitSize: the size of the split
|
||||
void TerminalPage::_SplitPane(const winrt::com_ptr<TerminalTab>& tab,
|
||||
void TerminalPage::_SplitPane(const winrt::com_ptr<Tab>& tab,
|
||||
const SplitDirection splitDirection,
|
||||
const float splitSize,
|
||||
std::shared_ptr<Pane> newPane)
|
||||
@@ -2461,10 +2562,10 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalPage::_ToggleSplitOrientation()
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
_UnZoomIfNeeded();
|
||||
terminalTab->ToggleSplitOrientation();
|
||||
tabImpl->ToggleSplitOrientation();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2478,10 +2579,10 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalPage::_ResizePane(const ResizeDirection& direction)
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
_UnZoomIfNeeded();
|
||||
terminalTab->ResizePane(direction);
|
||||
tabImpl->ResizePane(direction);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2493,23 +2594,23 @@ namespace winrt::TerminalApp::implementation
|
||||
void TerminalPage::_ScrollPage(ScrollDirection scrollDirection)
|
||||
{
|
||||
// Do nothing if for some reason, there's no terminal tab in focus. We don't want to crash.
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
if (const auto& control{ _GetActiveControl() })
|
||||
{
|
||||
const auto termHeight = control.ViewHeight();
|
||||
auto scrollDelta = _ComputeScrollDelta(scrollDirection, termHeight);
|
||||
terminalTab->Scroll(scrollDelta);
|
||||
tabImpl->Scroll(scrollDelta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPage::_ScrollToBufferEdge(ScrollDirection scrollDirection)
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
auto scrollDelta = _ComputeScrollDelta(scrollDirection, INT_MAX);
|
||||
terminalTab->Scroll(scrollDelta);
|
||||
tabImpl->Scroll(scrollDelta);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2621,9 +2722,9 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
if (_settings && _settings.GlobalSettings().SnapToGridOnResize())
|
||||
{
|
||||
if (const auto terminalTab{ _GetFocusedTabImpl() })
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
return terminalTab->CalcSnappedDimension(widthOrHeight, dimension);
|
||||
return tabImpl->CalcSnappedDimension(widthOrHeight, dimension);
|
||||
}
|
||||
}
|
||||
return dimension;
|
||||
@@ -3239,7 +3340,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// connection, then we'll return nullptr. Otherwise, we'll return a new
|
||||
// Pane for this connection.
|
||||
std::shared_ptr<Pane> TerminalPage::_MakeTerminalPane(const NewTerminalArgs& newTerminalArgs,
|
||||
const winrt::TerminalApp::TabBase& sourceTab,
|
||||
const winrt::TerminalApp::Tab& sourceTab,
|
||||
TerminalConnection::ITerminalConnection existingConnection)
|
||||
{
|
||||
// First things first - Check for making a pane from content ID.
|
||||
@@ -3257,15 +3358,15 @@ namespace winrt::TerminalApp::implementation
|
||||
TerminalSettingsCreateResult controlSettings{ nullptr };
|
||||
Profile profile{ nullptr };
|
||||
|
||||
if (const auto& terminalTab{ _GetTerminalTabImpl(sourceTab) })
|
||||
if (const auto& tabImpl{ _GetTabImpl(sourceTab) })
|
||||
{
|
||||
profile = terminalTab->GetFocusedProfile();
|
||||
profile = tabImpl->GetFocusedProfile();
|
||||
if (profile)
|
||||
{
|
||||
// TODO GH#5047 If we cache the NewTerminalArgs, we no longer need to do this.
|
||||
profile = GetClosestProfileForDuplicationOfProfile(profile);
|
||||
controlSettings = TerminalSettings::CreateWithProfile(_settings, profile, *_bindings);
|
||||
const auto workingDirectory = terminalTab->GetActiveTerminalControl().WorkingDirectory();
|
||||
const auto workingDirectory = tabImpl->GetActiveTerminalControl().WorkingDirectory();
|
||||
const auto validWorkingDirectory = !workingDirectory.empty();
|
||||
if (validWorkingDirectory)
|
||||
{
|
||||
@@ -3329,7 +3430,7 @@ namespace winrt::TerminalApp::implementation
|
||||
auto debugContent{ winrt::make<TerminalPaneContent>(profile, _terminalSettingsCache, newControl) };
|
||||
auto debugPane = std::make_shared<Pane>(debugContent);
|
||||
|
||||
// Since we're doing this split directly on the pane (instead of going through TerminalTab,
|
||||
// Since we're doing this split directly on the pane (instead of going through Tab,
|
||||
// we need to handle the panes 'active' states
|
||||
|
||||
// Set the pane we're splitting to active (otherwise Split will not do anything)
|
||||
@@ -3347,7 +3448,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// NOTE: callers of _MakePane should be able to accept nullptr as a return
|
||||
// value gracefully.
|
||||
std::shared_ptr<Pane> TerminalPage::_MakePane(const INewContentArgs& contentArgs,
|
||||
const winrt::TerminalApp::TabBase& sourceTab,
|
||||
const winrt::TerminalApp::Tab& sourceTab,
|
||||
TerminalConnection::ITerminalConnection existingConnection)
|
||||
|
||||
{
|
||||
@@ -3381,9 +3482,9 @@ namespace winrt::TerminalApp::implementation
|
||||
// Prevent the user from opening a bunch of snippets panes.
|
||||
//
|
||||
// Look at the focused tab, and if it already has one, then just focus it.
|
||||
if (const auto& focusedTab{ _GetFocusedTab() })
|
||||
if (const auto& focusedTab{ _GetFocusedTabImpl() })
|
||||
{
|
||||
const auto rootPane{ focusedTab.try_as<TerminalTab>()->GetRootPane() };
|
||||
const auto rootPane{ focusedTab->GetRootPane() };
|
||||
const bool found = rootPane == nullptr ? false : rootPane->WalkTree([](const auto& p) -> bool {
|
||||
if (const auto& snippets{ p->GetContent().try_as<SnippetsPaneContent>() })
|
||||
{
|
||||
@@ -3539,21 +3640,21 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
for (const auto& tab : _tabs)
|
||||
{
|
||||
if (auto terminalTab{ _GetTerminalTabImpl(tab) })
|
||||
if (auto tabImpl{ _GetTabImpl(tab) })
|
||||
{
|
||||
// Let the tab know that there are new settings. It's up to each content to decide what to do with them.
|
||||
terminalTab->UpdateSettings(_settings);
|
||||
tabImpl->UpdateSettings(_settings);
|
||||
|
||||
// Update the icon of the tab for the currently focused profile in that tab.
|
||||
// Only do this for TerminalTabs. Other types of tabs won't have multiple panes
|
||||
// and profiles so the Title and Icon will be set once and only once on init.
|
||||
_UpdateTabIcon(*terminalTab);
|
||||
_UpdateTabIcon(*tabImpl);
|
||||
|
||||
// Force the TerminalTab to re-grab its currently active control's title.
|
||||
terminalTab->UpdateTitle();
|
||||
tabImpl->UpdateTitle();
|
||||
}
|
||||
|
||||
auto tabImpl{ winrt::get_self<TabBase>(tab) };
|
||||
auto tabImpl{ winrt::get_self<Tab>(tab) };
|
||||
tabImpl->SetActionMap(_settings.ActionMap());
|
||||
}
|
||||
|
||||
@@ -3672,7 +3773,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
for (const auto& tab : _tabs)
|
||||
{
|
||||
if (auto tabImpl{ _GetTerminalTabImpl(tab) })
|
||||
if (auto tabImpl{ _GetTabImpl(tab) })
|
||||
{
|
||||
auto tabState{ tabImpl->GetCombinedTaskbarState() };
|
||||
// lowest priority wins
|
||||
@@ -3715,11 +3816,11 @@ namespace winrt::TerminalApp::implementation
|
||||
_visible = showOrHide;
|
||||
for (const auto& tab : _tabs)
|
||||
{
|
||||
if (auto terminalTab{ _GetTerminalTabImpl(tab) })
|
||||
if (auto tabImpl{ _GetTabImpl(tab) })
|
||||
{
|
||||
// Manually enumerate the panes in each tab; this will let us recycle TerminalSettings
|
||||
// objects but only have to iterate one time.
|
||||
terminalTab->GetRootPane()->WalkTree([&](auto&& pane) {
|
||||
tabImpl->GetRootPane()->WalkTree([&](auto&& pane) {
|
||||
if (auto control = pane->GetTerminalControl())
|
||||
{
|
||||
control.WindowVisibilityChanged(showOrHide);
|
||||
@@ -3737,7 +3838,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - tab: the tab where the search box should be created
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalPage::_Find(const TerminalTab& tab)
|
||||
void TerminalPage::_Find(const Tab& tab)
|
||||
{
|
||||
if (const auto& control{ tab.GetActiveTerminalControl() })
|
||||
{
|
||||
@@ -3803,36 +3904,18 @@ namespace winrt::TerminalApp::implementation
|
||||
// and the non-client are behind it
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalPage::_SetNewTabButtonColor(const Windows::UI::Color& color, const Windows::UI::Color& accentColor)
|
||||
void TerminalPage::_SetNewTabButtonColor(const til::color color, const til::color accentColor)
|
||||
{
|
||||
constexpr auto lightnessThreshold = 0.6f;
|
||||
// TODO GH#3327: Look at what to do with the tab button when we have XAML theming
|
||||
auto IsBrightColor = ColorHelper::IsBrightColor(color);
|
||||
auto isLightAccentColor = ColorHelper::IsBrightColor(accentColor);
|
||||
winrt::Windows::UI::Color pressedColor{};
|
||||
winrt::Windows::UI::Color hoverColor{};
|
||||
winrt::Windows::UI::Color foregroundColor{};
|
||||
const auto hoverColorAdjustment = 5.f;
|
||||
const auto pressedColorAdjustment = 7.f;
|
||||
const auto IsBrightColor = ColorFix::GetLightness(color) >= lightnessThreshold;
|
||||
const auto isLightAccentColor = ColorFix::GetLightness(accentColor) >= lightnessThreshold;
|
||||
const auto hoverColorAdjustment = isLightAccentColor ? -0.05f : 0.05f;
|
||||
const auto pressedColorAdjustment = isLightAccentColor ? -0.1f : 0.1f;
|
||||
|
||||
if (IsBrightColor)
|
||||
{
|
||||
foregroundColor = winrt::Windows::UI::Colors::Black();
|
||||
}
|
||||
else
|
||||
{
|
||||
foregroundColor = winrt::Windows::UI::Colors::White();
|
||||
}
|
||||
|
||||
if (isLightAccentColor)
|
||||
{
|
||||
hoverColor = ColorHelper::Darken(accentColor, hoverColorAdjustment);
|
||||
pressedColor = ColorHelper::Darken(accentColor, pressedColorAdjustment);
|
||||
}
|
||||
else
|
||||
{
|
||||
hoverColor = ColorHelper::Lighten(accentColor, hoverColorAdjustment);
|
||||
pressedColor = ColorHelper::Lighten(accentColor, pressedColorAdjustment);
|
||||
}
|
||||
const auto foregroundColor = IsBrightColor ? Colors::Black() : Colors::White();
|
||||
const auto hoverColor = til::color{ ColorFix::AdjustLightness(accentColor, hoverColorAdjustment) };
|
||||
const auto pressedColor = til::color{ ColorFix::AdjustLightness(accentColor, pressedColorAdjustment) };
|
||||
|
||||
Media::SolidColorBrush backgroundBrush{ accentColor };
|
||||
Media::SolidColorBrush backgroundHoverBrush{ hoverColor };
|
||||
@@ -3855,7 +3938,7 @@ namespace winrt::TerminalApp::implementation
|
||||
_newTabButton.Background(backgroundBrush);
|
||||
_newTabButton.Foreground(foregroundBrush);
|
||||
|
||||
// This is just like what we do in TabBase::_RefreshVisualState. We need
|
||||
// This is just like what we do in Tab::_RefreshVisualState. We need
|
||||
// to manually toggle the visual state, so the setters in the visual
|
||||
// state group will re-apply, and set our currently selected colors in
|
||||
// the resources.
|
||||
@@ -4106,25 +4189,18 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Returns a com_ptr to the implementation type of the given tab if it's a TerminalTab.
|
||||
// - Returns a com_ptr to the implementation type of the given tab if it's a Tab.
|
||||
// If the tab is not a TerminalTab, returns nullptr.
|
||||
// Arguments:
|
||||
// - tab: the projected type of a Tab
|
||||
// Return Value:
|
||||
// - If the tab is a TerminalTab, a com_ptr to the implementation type.
|
||||
// If the tab is not a TerminalTab, nullptr
|
||||
winrt::com_ptr<TerminalTab> TerminalPage::_GetTerminalTabImpl(const TerminalApp::TabBase& tab)
|
||||
winrt::com_ptr<Tab> TerminalPage::_GetTabImpl(const TerminalApp::Tab& tab)
|
||||
{
|
||||
if (auto terminalTab = tab.try_as<TerminalApp::TerminalTab>())
|
||||
{
|
||||
winrt::com_ptr<TerminalTab> tabImpl;
|
||||
tabImpl.copy_from(winrt::get_self<TerminalTab>(terminalTab));
|
||||
return tabImpl;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
winrt::com_ptr<Tab> tabImpl;
|
||||
tabImpl.copy_from(winrt::get_self<Tab>(tab));
|
||||
return tabImpl;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -4611,10 +4687,10 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
for (const auto& tab : _tabs)
|
||||
{
|
||||
if (auto terminalTab{ _GetTerminalTabImpl(tab) })
|
||||
if (auto tabImpl{ _GetTabImpl(tab) })
|
||||
{
|
||||
// The root pane will propagate the theme change to all its children.
|
||||
if (const auto& rootPane{ terminalTab->GetRootPane() })
|
||||
if (const auto& rootPane{ tabImpl->GetRootPane() })
|
||||
{
|
||||
rootPane->UpdateResources(_paneResources);
|
||||
}
|
||||
@@ -4675,7 +4751,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
// Second: Update the colors of our individual TabViewItems. This
|
||||
// applies tab.background to the tabs via TerminalTab::ThemeColor.
|
||||
// applies tab.background to the tabs via Tab::ThemeColor.
|
||||
//
|
||||
// Do this second, so that we already know the bgColor of the titlebar.
|
||||
{
|
||||
@@ -4683,8 +4759,8 @@ namespace winrt::TerminalApp::implementation
|
||||
const auto tabUnfocusedBackground = theme.Tab() ? theme.Tab().UnfocusedBackground() : nullptr;
|
||||
for (const auto& tab : _tabs)
|
||||
{
|
||||
winrt::com_ptr<TabBase> tabImpl;
|
||||
tabImpl.copy_from(winrt::get_self<TabBase>(tab));
|
||||
winrt::com_ptr<Tab> tabImpl;
|
||||
tabImpl.copy_from(winrt::get_self<Tab>(tab));
|
||||
tabImpl->ThemeColor(tabBackground, tabUnfocusedBackground, bgColor);
|
||||
}
|
||||
}
|
||||
@@ -5153,8 +5229,8 @@ namespace winrt::TerminalApp::implementation
|
||||
// Get the tab impl from this event.
|
||||
const auto eventTab = e.Tab();
|
||||
const auto tabBase = _GetTabByTabViewItem(eventTab);
|
||||
winrt::com_ptr<TabBase> tabImpl;
|
||||
tabImpl.copy_from(winrt::get_self<TabBase>(tabBase));
|
||||
winrt::com_ptr<Tab> tabImpl;
|
||||
tabImpl.copy_from(winrt::get_self<Tab>(tabBase));
|
||||
if (tabImpl)
|
||||
{
|
||||
// First: stash the tab we started dragging.
|
||||
@@ -5365,6 +5441,14 @@ namespace winrt::TerminalApp::implementation
|
||||
runAsAdminItem.Click([profileIndex, weakThis{ get_weak() }](auto&&, auto&&) {
|
||||
if (auto page{ weakThis.get() })
|
||||
{
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalAppProvider,
|
||||
"NewTabMenuItemElevateSubmenuItemClicked",
|
||||
TraceLoggingDescription("Event emitted when the elevate submenu item from the new tab menu is invoked"),
|
||||
TraceLoggingValue(page->NumberOfTabs(), "TabCount", "The count of tabs currently opened in this window"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
|
||||
NewTerminalArgs args{ profileIndex };
|
||||
args.Elevate(true);
|
||||
page->_OpenNewTerminalViaDropdown(args);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "TerminalPage.g.h"
|
||||
#include "TerminalTab.h"
|
||||
#include "Tab.h"
|
||||
#include "AppKeyBindings.h"
|
||||
#include "AppCommandlineArgs.h"
|
||||
#include "RenameWindowRequestedArgs.g.h"
|
||||
@@ -219,13 +219,13 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
Microsoft::Terminal::Settings::Model::CascadiaSettings _settings{ nullptr };
|
||||
|
||||
Windows::Foundation::Collections::IObservableVector<TerminalApp::TabBase> _tabs;
|
||||
Windows::Foundation::Collections::IObservableVector<TerminalApp::TabBase> _mruTabs;
|
||||
static winrt::com_ptr<TerminalTab> _GetTerminalTabImpl(const TerminalApp::TabBase& tab);
|
||||
Windows::Foundation::Collections::IObservableVector<TerminalApp::Tab> _tabs;
|
||||
Windows::Foundation::Collections::IObservableVector<TerminalApp::Tab> _mruTabs;
|
||||
static winrt::com_ptr<Tab> _GetTabImpl(const TerminalApp::Tab& tab);
|
||||
|
||||
void _UpdateTabIndices();
|
||||
|
||||
TerminalApp::TerminalTab _settingsTab{ nullptr };
|
||||
TerminalApp::Tab _settingsTab{ nullptr };
|
||||
|
||||
bool _isInFocusMode{ false };
|
||||
bool _isFullscreen{ false };
|
||||
@@ -277,7 +277,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
struct StashedDragData
|
||||
{
|
||||
winrt::com_ptr<winrt::TerminalApp::implementation::TabBase> draggedTab{ nullptr };
|
||||
winrt::com_ptr<winrt::TerminalApp::implementation::Tab> draggedTab{ nullptr };
|
||||
winrt::Windows::Foundation::Point dragOffset{ 0, 0 };
|
||||
} _stashed;
|
||||
|
||||
@@ -305,7 +305,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void _OpenNewTabDropdown();
|
||||
HRESULT _OpenNewTab(const Microsoft::Terminal::Settings::Model::INewContentArgs& newContentArgs);
|
||||
TerminalApp::TerminalTab _CreateNewTabFromPane(std::shared_ptr<Pane> pane, uint32_t insertPosition = -1);
|
||||
TerminalApp::Tab _CreateNewTabFromPane(std::shared_ptr<Pane> pane, uint32_t insertPosition = -1);
|
||||
|
||||
std::wstring _evaluatePathForCwd(std::wstring_view path);
|
||||
|
||||
@@ -328,25 +328,25 @@ namespace winrt::TerminalApp::implementation
|
||||
void _HookupKeyBindings(const Microsoft::Terminal::Settings::Model::IActionMapView& actionMap) noexcept;
|
||||
void _RegisterActionCallbacks();
|
||||
|
||||
void _UpdateTitle(const TerminalTab& tab);
|
||||
void _UpdateTabIcon(TerminalTab& tab);
|
||||
void _UpdateTitle(const Tab& tab);
|
||||
void _UpdateTabIcon(Tab& tab);
|
||||
void _UpdateTabView();
|
||||
void _UpdateTabWidthMode();
|
||||
void _SetBackgroundImage(const winrt::Microsoft::Terminal::Settings::Model::IAppearanceConfig& newAppearance);
|
||||
|
||||
void _DuplicateFocusedTab();
|
||||
void _DuplicateTab(const TerminalTab& tab);
|
||||
void _DuplicateTab(const Tab& tab);
|
||||
|
||||
safe_void_coroutine _ExportTab(const TerminalTab& tab, winrt::hstring filepath);
|
||||
safe_void_coroutine _ExportTab(const Tab& tab, winrt::hstring filepath);
|
||||
|
||||
winrt::Windows::Foundation::IAsyncAction _HandleCloseTabRequested(winrt::TerminalApp::TabBase tab);
|
||||
winrt::Windows::Foundation::IAsyncAction _HandleCloseTabRequested(winrt::TerminalApp::Tab tab);
|
||||
void _CloseTabAtIndex(uint32_t index);
|
||||
void _RemoveTab(const winrt::TerminalApp::TabBase& tab);
|
||||
safe_void_coroutine _RemoveTabs(const std::vector<winrt::TerminalApp::TabBase> tabs);
|
||||
void _RemoveTab(const winrt::TerminalApp::Tab& tab);
|
||||
safe_void_coroutine _RemoveTabs(const std::vector<winrt::TerminalApp::Tab> tabs);
|
||||
|
||||
void _InitializeTab(winrt::com_ptr<TerminalTab> newTabImpl, uint32_t insertPosition = -1);
|
||||
void _InitializeTab(winrt::com_ptr<Tab> newTabImpl, uint32_t insertPosition = -1);
|
||||
void _RegisterTerminalEvents(Microsoft::Terminal::Control::TermControl term);
|
||||
void _RegisterTabEvents(TerminalTab& hostingTab);
|
||||
void _RegisterTabEvents(Tab& hostingTab);
|
||||
|
||||
void _DismissTabContextMenus();
|
||||
void _FocusCurrentTab(const bool focusAlways);
|
||||
@@ -357,7 +357,7 @@ namespace winrt::TerminalApp::implementation
|
||||
bool _MoveFocus(const Microsoft::Terminal::Settings::Model::FocusDirection& direction);
|
||||
bool _SwapPane(const Microsoft::Terminal::Settings::Model::FocusDirection& direction);
|
||||
bool _MovePane(const Microsoft::Terminal::Settings::Model::MovePaneArgs args);
|
||||
bool _MoveTab(winrt::com_ptr<TerminalTab> tab, const Microsoft::Terminal::Settings::Model::MoveTabArgs args);
|
||||
bool _MoveTab(winrt::com_ptr<Tab> tab, const Microsoft::Terminal::Settings::Model::MoveTabArgs args);
|
||||
|
||||
template<typename F>
|
||||
bool _ApplyToActiveControls(F f)
|
||||
@@ -381,21 +381,21 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
winrt::Microsoft::Terminal::Control::TermControl _GetActiveControl();
|
||||
std::optional<uint32_t> _GetFocusedTabIndex() const noexcept;
|
||||
std::optional<uint32_t> _GetTabIndex(const TerminalApp::TabBase& tab) const noexcept;
|
||||
TerminalApp::TabBase _GetFocusedTab() const noexcept;
|
||||
winrt::com_ptr<TerminalTab> _GetFocusedTabImpl() const noexcept;
|
||||
TerminalApp::TabBase _GetTabByTabViewItem(const Microsoft::UI::Xaml::Controls::TabViewItem& tabViewItem) const noexcept;
|
||||
std::optional<uint32_t> _GetTabIndex(const TerminalApp::Tab& tab) const noexcept;
|
||||
TerminalApp::Tab _GetFocusedTab() const noexcept;
|
||||
winrt::com_ptr<Tab> _GetFocusedTabImpl() const noexcept;
|
||||
TerminalApp::Tab _GetTabByTabViewItem(const Microsoft::UI::Xaml::Controls::TabViewItem& tabViewItem) const noexcept;
|
||||
|
||||
void _HandleClosePaneRequested(std::shared_ptr<Pane> pane);
|
||||
safe_void_coroutine _SetFocusedTab(const winrt::TerminalApp::TabBase tab);
|
||||
safe_void_coroutine _SetFocusedTab(const winrt::TerminalApp::Tab tab);
|
||||
safe_void_coroutine _CloseFocusedPane();
|
||||
void _ClosePanes(weak_ref<TerminalTab> weakTab, std::vector<uint32_t> paneIds);
|
||||
void _ClosePanes(weak_ref<Tab> weakTab, std::vector<uint32_t> paneIds);
|
||||
winrt::Windows::Foundation::IAsyncOperation<bool> _PaneConfirmCloseReadOnly(std::shared_ptr<Pane> pane);
|
||||
void _AddPreviouslyClosedPaneOrTab(std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs>&& args);
|
||||
|
||||
void _Scroll(ScrollDirection scrollDirection, const Windows::Foundation::IReference<uint32_t>& rowsToScroll);
|
||||
|
||||
void _SplitPane(const winrt::com_ptr<TerminalTab>& tab,
|
||||
void _SplitPane(const winrt::com_ptr<Tab>& tab,
|
||||
const Microsoft::Terminal::Settings::Model::SplitDirection splitType,
|
||||
const float splitSize,
|
||||
std::shared_ptr<Pane> newPane);
|
||||
@@ -439,14 +439,14 @@ namespace winrt::TerminalApp::implementation
|
||||
void _OnTabItemsChanged(const IInspectable& sender, const Windows::Foundation::Collections::IVectorChangedEventArgs& eventArgs);
|
||||
void _OnTabCloseRequested(const IInspectable& sender, const Microsoft::UI::Xaml::Controls::TabViewTabCloseRequestedEventArgs& eventArgs);
|
||||
void _OnFirstLayout(const IInspectable& sender, const IInspectable& eventArgs);
|
||||
void _UpdatedSelectedTab(const winrt::TerminalApp::TabBase& tab);
|
||||
void _UpdatedSelectedTab(const winrt::TerminalApp::Tab& tab);
|
||||
void _UpdateBackground(const winrt::Microsoft::Terminal::Settings::Model::Profile& profile);
|
||||
|
||||
void _OnDispatchCommandRequested(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::Command& command);
|
||||
void _OnCommandLineExecutionRequested(const IInspectable& sender, const winrt::hstring& commandLine);
|
||||
void _OnSwitchToTabRequested(const IInspectable& sender, const winrt::TerminalApp::TabBase& tab);
|
||||
void _OnSwitchToTabRequested(const IInspectable& sender, const winrt::TerminalApp::Tab& tab);
|
||||
|
||||
void _Find(const TerminalTab& tab);
|
||||
void _Find(const Tab& tab);
|
||||
|
||||
winrt::Microsoft::Terminal::Control::TermControl _CreateNewControlAndContent(const winrt::Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult& settings,
|
||||
const winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection& connection);
|
||||
@@ -455,15 +455,15 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
TerminalApp::IPaneContent _makeSettingsContent();
|
||||
std::shared_ptr<Pane> _MakeTerminalPane(const Microsoft::Terminal::Settings::Model::NewTerminalArgs& newTerminalArgs = nullptr,
|
||||
const winrt::TerminalApp::TabBase& sourceTab = nullptr,
|
||||
const winrt::TerminalApp::Tab& sourceTab = nullptr,
|
||||
winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection existingConnection = nullptr);
|
||||
std::shared_ptr<Pane> _MakePane(const Microsoft::Terminal::Settings::Model::INewContentArgs& newContentArgs = nullptr,
|
||||
const winrt::TerminalApp::TabBase& sourceTab = nullptr,
|
||||
const winrt::TerminalApp::Tab& sourceTab = nullptr,
|
||||
winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection existingConnection = nullptr);
|
||||
|
||||
void _RefreshUIForSettingsReload();
|
||||
|
||||
void _SetNewTabButtonColor(const Windows::UI::Color& color, const Windows::UI::Color& accentColor);
|
||||
void _SetNewTabButtonColor(til::color color, til::color accentColor);
|
||||
void _ClearNewTabButtonColor();
|
||||
|
||||
safe_void_coroutine _CompleteInitialization();
|
||||
@@ -475,7 +475,7 @@ namespace winrt::TerminalApp::implementation
|
||||
static int _ComputeScrollDelta(ScrollDirection scrollDirection, const uint32_t rowsToScroll);
|
||||
static uint32_t _ReadSystemRowsToScroll();
|
||||
|
||||
void _UpdateMRUTab(const winrt::TerminalApp::TabBase& tab);
|
||||
void _UpdateMRUTab(const winrt::TerminalApp::Tab& tab);
|
||||
|
||||
void _TryMoveTab(const uint32_t currentTabIndex, const int32_t suggestedNewTabIndex);
|
||||
|
||||
@@ -534,7 +534,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void _onTabDroppedOutside(winrt::Windows::Foundation::IInspectable sender, winrt::Microsoft::UI::Xaml::Controls::TabViewTabDroppedOutsideEventArgs e);
|
||||
|
||||
void _DetachPaneFromWindow(std::shared_ptr<Pane> pane);
|
||||
void _DetachTabFromWindow(const winrt::com_ptr<TabBase>& terminalTab);
|
||||
void _DetachTabFromWindow(const winrt::com_ptr<Tab>& tabImpl);
|
||||
void _MoveContent(std::vector<winrt::Microsoft::Terminal::Settings::Model::ActionAndArgs>&& actions,
|
||||
const winrt::hstring& windowName,
|
||||
const uint32_t tabIndex,
|
||||
@@ -546,9 +546,9 @@ namespace winrt::TerminalApp::implementation
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyout _CreateRunAsAdminFlyout(int profileIndex);
|
||||
|
||||
winrt::Microsoft::Terminal::Control::TermControl _senderOrActiveControl(const winrt::Windows::Foundation::IInspectable& sender);
|
||||
winrt::com_ptr<TerminalTab> _senderOrFocusedTab(const IInspectable& sender);
|
||||
winrt::com_ptr<Tab> _senderOrFocusedTab(const IInspectable& sender);
|
||||
|
||||
void _activePaneChanged(winrt::TerminalApp::TerminalTab tab, Windows::Foundation::IInspectable args);
|
||||
void _activePaneChanged(winrt::TerminalApp::Tab tab, Windows::Foundation::IInspectable args);
|
||||
safe_void_coroutine _doHandleSuggestions(Microsoft::Terminal::Settings::Model::SuggestionsArgs realArgs);
|
||||
|
||||
#pragma region ActionHandlers
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace winrt::TerminalApp::implementation
|
||||
NewTerminalArgs args{};
|
||||
const auto& controlSettings = _control.Settings();
|
||||
|
||||
args.Profile(controlSettings.ProfileName());
|
||||
args.Profile(::Microsoft::Console::Utils::GuidToString(_profile.Guid()));
|
||||
// If we know the user's working directory use it instead of the profile.
|
||||
if (const auto dir = _control.WorkingDirectory(); !dir.empty())
|
||||
{
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "TabBase.idl";
|
||||
import "TerminalTabStatus.idl";
|
||||
|
||||
namespace TerminalApp
|
||||
{
|
||||
[default_interface] runtimeclass TerminalTab : TabBase
|
||||
{
|
||||
TerminalTabStatus TabStatus { get; };
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,7 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "TitlebarControl.h"
|
||||
|
||||
#include "ColorHelper.h"
|
||||
#include "../../types/inc/ColorFix.hpp"
|
||||
|
||||
#include "TitlebarControl.g.cpp"
|
||||
|
||||
@@ -189,7 +188,8 @@ namespace winrt::TerminalApp::implementation
|
||||
return;
|
||||
}
|
||||
|
||||
const auto isBrightColor = ColorHelper::IsBrightColor(c);
|
||||
constexpr auto lightnessThreshold = 0.6f;
|
||||
const auto isBrightColor = ColorFix::GetLightness(c) >= lightnessThreshold;
|
||||
MinMaxCloseControl().RequestedTheme(isBrightColor ? winrt::Windows::UI::Xaml::ElementTheme::Light :
|
||||
winrt::Windows::UI::Xaml::ElementTheme::Dark);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<!-- sets a bunch of Windows Universal properties -->
|
||||
<OpenConsoleUniversalApp>true</OpenConsoleUniversalApp>
|
||||
<PgoTarget>true</PgoTarget>
|
||||
<VersionInfoFileDescription>Windows Terminal Main UI Library</VersionInfoFileDescription>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="NuGet Dependencies">
|
||||
<TerminalCppWinrt>true</TerminalCppWinrt>
|
||||
@@ -35,7 +36,6 @@
|
||||
<ClInclude Include="../TitlebarControl.h" />
|
||||
<ClInclude Include="../TabRowControl.h" />
|
||||
<ClInclude Include="../App.h" />
|
||||
<ClInclude Include="../TerminalTab.h" />
|
||||
</ItemGroup>
|
||||
<!-- ========================= Cpp Files ======================== -->
|
||||
<ItemGroup>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<OpenConsoleUniversalApp>false</OpenConsoleUniversalApp>
|
||||
<ApplicationType>Windows Store</ApplicationType>
|
||||
<TargetPlatformIdentifier>Windows</TargetPlatformIdentifier>
|
||||
<VersionInfoFileDescription>Windows Terminal Azure Cloud Shell Connector</VersionInfoFileDescription>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Label="NuGet Dependencies">
|
||||
|
||||
@@ -66,10 +66,41 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
|
||||
// WSLENV is a colon-delimited list of environment variables (+flags) that should appear inside WSL
|
||||
// https://devblogs.microsoft.com/commandline/share-environment-vars-between-wsl-and-windows/
|
||||
std::wstring wslEnv{ L"WT_SESSION:WT_PROFILE_ID:" };
|
||||
|
||||
// WSLENV.1: Get a handle to the WSLENV environment variable.
|
||||
auto& wslEnv = environment.as_map()[L"WSLENV"];
|
||||
std::wstring additionalWslEnv;
|
||||
|
||||
// WSLENV.2: Figure out what variables are already in WSLENV.
|
||||
std::unordered_set<std::wstring_view> wslEnvVars;
|
||||
for (const auto& part : til::split_iterator{ std::wstring_view{ wslEnv }, L':' })
|
||||
{
|
||||
// Each part may contain a variable name and flags (e.g., /p, /l, etc.)
|
||||
// We only care about the variable name for WSLENV.
|
||||
const auto key = til::safe_slice_len(part, 0, part.rfind(L'/'));
|
||||
wslEnvVars.emplace(key);
|
||||
}
|
||||
|
||||
// WSLENV.3: Add our terminal-specific environment variables to WSLENV.
|
||||
static constexpr std::wstring_view builtinWslEnvVars[] = {
|
||||
L"WT_SESSION",
|
||||
L"WT_PROFILE_ID",
|
||||
};
|
||||
// Misdiagnosis in MSVC 14.44.35207. No pointer arithmetic in sight.
|
||||
#pragma warning(suppress : 26481) // Don't use pointer arithmetic. Use span instead (bounds.1).
|
||||
for (const auto& key : builtinWslEnvVars)
|
||||
{
|
||||
if (wslEnvVars.emplace(key).second)
|
||||
{
|
||||
additionalWslEnv.append(key);
|
||||
additionalWslEnv.push_back(L':');
|
||||
}
|
||||
}
|
||||
|
||||
if (_environment)
|
||||
{
|
||||
// Order the environment variable names so that resolution order is consistent
|
||||
// NOTE(lhecker): I'm like 99% sure that this is unnecessary.
|
||||
std::set<std::wstring, til::env_key_sorter> keys{};
|
||||
for (const auto item : _environment)
|
||||
{
|
||||
@@ -85,18 +116,39 @@ namespace winrt::Microsoft::Terminal::TerminalConnection::implementation
|
||||
const auto value = winrt::unbox_value<hstring>(_environment.Lookup(key));
|
||||
|
||||
environment.set_user_environment_var(key.c_str(), value.c_str());
|
||||
// For each environment variable added to the environment, also add it to WSLENV
|
||||
wslEnv += key + L":";
|
||||
|
||||
// WSLENV.4: Add custom user environment variables to WSLENV.
|
||||
if (wslEnvVars.emplace(key).second)
|
||||
{
|
||||
additionalWslEnv.append(key);
|
||||
additionalWslEnv.push_back(L':');
|
||||
}
|
||||
}
|
||||
CATCH_LOG();
|
||||
}
|
||||
}
|
||||
|
||||
// We want to prepend new environment variables to WSLENV - that way if a variable already
|
||||
// exists in WSLENV but with a flag, the flag will be respected.
|
||||
// (This behaviour was empirically observed)
|
||||
wslEnv += environment.as_map()[L"WSLENV"];
|
||||
environment.as_map().insert_or_assign(L"WSLENV", wslEnv);
|
||||
if (!additionalWslEnv.empty())
|
||||
{
|
||||
// WSLENV.5: In the next step we'll prepend `additionalWslEnv` to `wslEnv`,
|
||||
// so make sure that we have a single colon in between them.
|
||||
const auto hasColon = additionalWslEnv.ends_with(L':');
|
||||
const auto needsColon = !wslEnv.starts_with(L':');
|
||||
if (hasColon != needsColon)
|
||||
{
|
||||
if (hasColon)
|
||||
{
|
||||
additionalWslEnv.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
additionalWslEnv.push_back(L':');
|
||||
}
|
||||
}
|
||||
|
||||
// WSLENV.6: Prepend our additional environment variables to WSLENV.
|
||||
wslEnv.insert(0, additionalWslEnv);
|
||||
}
|
||||
}
|
||||
|
||||
auto newEnvVars = environment.to_string();
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OpenConsoleUniversalApp>true</OpenConsoleUniversalApp>
|
||||
<PgoTarget>true</PgoTarget>
|
||||
<VersionInfoFileDescription>Windows Terminal Connection Library</VersionInfoFileDescription>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="NuGet Dependencies">
|
||||
<TerminalCppWinrt>true</TerminalCppWinrt>
|
||||
|
||||
@@ -515,11 +515,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
const auto ctrlPressed = modifiers.IsCtrlPressed();
|
||||
const auto shiftPressed = modifiers.IsShiftPressed();
|
||||
|
||||
if (ctrlPressed && shiftPressed)
|
||||
if (ctrlPressed && shiftPressed && _core->Settings().ScrollToChangeOpacity())
|
||||
{
|
||||
_mouseTransparencyHandler(delta);
|
||||
}
|
||||
else if (ctrlPressed)
|
||||
else if (ctrlPressed && !shiftPressed && _core->Settings().ScrollToZoom())
|
||||
{
|
||||
_mouseZoomHandler(delta);
|
||||
}
|
||||
|
||||
@@ -60,6 +60,8 @@ namespace Microsoft.Terminal.Control
|
||||
Boolean CopyOnSelect { get; };
|
||||
Microsoft.Terminal.Control.CopyFormat CopyFormatting { get; };
|
||||
Boolean FocusFollowMouse { get; };
|
||||
Boolean ScrollToZoom { get; };
|
||||
Boolean ScrollToChangeOpacity { get; };
|
||||
|
||||
String Commandline { get; };
|
||||
String StartingDirectory { get; };
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
projects compile properly when they depend on this "Microsoft.winmd."
|
||||
-->
|
||||
<CppWinRTNamespaceMergeDepth>3</CppWinRTNamespaceMergeDepth>
|
||||
<VersionInfoFileDescription>Windows Terminal Control Library</VersionInfoFileDescription>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Label="NuGet Dependencies">
|
||||
|
||||
@@ -156,6 +156,7 @@ public:
|
||||
bool IsVtInputEnabled() const noexcept override;
|
||||
void NotifyAccessibilityChange(const til::rect& changedRect) noexcept override;
|
||||
void NotifyBufferRotation(const int delta) override;
|
||||
void NotifyShellIntegrationMark() override;
|
||||
|
||||
void InvokeCompletions(std::wstring_view menuJson, unsigned int replaceLength) override;
|
||||
|
||||
|
||||
@@ -404,3 +404,9 @@ void Terminal::NotifyBufferRotation(const int delta)
|
||||
_NotifyScrollEvent();
|
||||
}
|
||||
}
|
||||
|
||||
void Terminal::NotifyShellIntegrationMark()
|
||||
{
|
||||
// Notify the scrollbar that marks have been added so it can refresh the mark indicators
|
||||
_NotifyScrollEvent();
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="{StaticResource ControlCornerRadius}" />
|
||||
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
@@ -97,7 +97,8 @@
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="1" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="{StaticResource ControlCornerRadius}" />
|
||||
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
@@ -138,7 +139,7 @@
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
</Style>
|
||||
<x:Int32 x:Key="EditButtonSize">32</x:Int32>
|
||||
<x:Double x:Key="EditButtonIconSize">15</x:Double>
|
||||
<x:Double x:Key="EditButtonIconSize">14</x:Double>
|
||||
<Style x:Key="EditButtonStyle"
|
||||
BasedOn="{StaticResource DefaultButtonStyle}"
|
||||
TargetType="Button">
|
||||
@@ -150,7 +151,7 @@
|
||||
<Style x:Key="AccentEditButtonStyle"
|
||||
BasedOn="{StaticResource AccentButtonStyle}"
|
||||
TargetType="Button">
|
||||
<Setter Property="Padding" Value="3" />
|
||||
<Setter Property="Padding" Value="4" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="Height" Value="{StaticResource EditButtonSize}" />
|
||||
<Setter Property="Width" Value="{StaticResource EditButtonSize}" />
|
||||
@@ -191,6 +192,7 @@
|
||||
|
||||
<!-- Command Name -->
|
||||
<TextBlock Grid.Column="0"
|
||||
FontWeight="Normal"
|
||||
Style="{StaticResource KeyBindingNameTextBlockStyle}"
|
||||
Text="{x:Bind Name, Mode=OneWay}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(IsInEditMode), Mode=OneWay}" />
|
||||
@@ -317,7 +319,6 @@
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ListViewItem>
|
||||
@@ -332,6 +333,7 @@
|
||||
Style="{StaticResource SettingsStackStyle}">
|
||||
<!-- Add New Button -->
|
||||
<Button x:Name="AddNewButton"
|
||||
Margin="0,12,0,0"
|
||||
Click="AddNew_Click">
|
||||
<Button.Content>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
|
||||
@@ -32,25 +32,24 @@
|
||||
<!-- Loosely based on NonExpanderGrid style -->
|
||||
<Setter Property="MinWidth" Value="{ThemeResource FlyoutThemeMinWidth}" />
|
||||
<Setter Property="MinHeight" Value="64" />
|
||||
<Setter Property="Padding" Value="16,0,8,0" />
|
||||
<Setter Property="Padding" Value="0,0,8,0" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
</Page.Resources>
|
||||
|
||||
<Grid Margin="0,0,0,8"
|
||||
<Grid MaxWidth="{StaticResource StandardControlMaxWidth}"
|
||||
Margin="0,0,0,8"
|
||||
RowSpacing="8">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Grid.Row="0"
|
||||
MaxWidth="{StaticResource StandardControlMaxWidth}"
|
||||
Spacing="8">
|
||||
<TextBlock x:Uid="ColorSchemesDisclaimer"
|
||||
Style="{StaticResource DisclaimerStyle}" />
|
||||
|
||||
<Button x:Name="AddNewButton"
|
||||
Margin="4,0,0,0"
|
||||
Margin="0"
|
||||
Click="AddNew_Click"
|
||||
Style="{StaticResource BrowseButtonStyle}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
@@ -65,6 +64,7 @@
|
||||
<ListView x:Name="ColorSchemeListView"
|
||||
Grid.Row="1"
|
||||
MaxWidth="{StaticResource StandardControlMaxWidth}"
|
||||
Margin="-16,0,0,0"
|
||||
IsItemClickEnabled="True"
|
||||
ItemClick="{x:Bind ViewModel.SchemeListItemClicked}"
|
||||
ItemsSource="{x:Bind ViewModel.AllColorSchemes, Mode=OneWay}"
|
||||
@@ -88,11 +88,11 @@
|
||||
<!-- Set the height of the inner grid as 48 to be 3/4 of the ListViewItem height -->
|
||||
<Grid Grid.Column="0"
|
||||
Height="48"
|
||||
Padding="12,11,8,8"
|
||||
Padding="12,12,8,8"
|
||||
VerticalAlignment="Center"
|
||||
Background="{x:Bind mtu:Converters.ColorToBrush(BackgroundColor.Color), Mode=OneWay}"
|
||||
ColumnSpacing="2"
|
||||
CornerRadius="4"
|
||||
CornerRadius="{StaticResource ControlCornerRadius}"
|
||||
RowSpacing="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
@@ -200,19 +200,19 @@
|
||||
Text="{x:Bind Name, Mode=OneWay}" />
|
||||
</Grid>
|
||||
<Border Grid.Column="1"
|
||||
Margin="10,0,0,0"
|
||||
Padding="2,0,2,0"
|
||||
Margin="12,0,0,0"
|
||||
Padding="8,4"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Background="{ThemeResource SystemAltMediumLowColor}"
|
||||
BorderBrush="{ThemeResource SystemControlForegroundBaseMediumBrush}"
|
||||
Background="{ThemeResource SubtleFillColorSecondaryBrush}"
|
||||
BorderBrush="{ThemeResource ControlStrongStrokeColorDefaultBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="1"
|
||||
CornerRadius="{StaticResource ControlCornerRadius}"
|
||||
Visibility="{x:Bind IsDefaultScheme, Mode=OneWay}">
|
||||
<TextBlock x:Uid="ColorScheme_DefaultTag"
|
||||
Grid.Column="1"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Foreground="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
|
||||
</Border>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
@@ -68,24 +68,23 @@
|
||||
<Color x:Key="DeleteButtonColor">Firebrick</Color>
|
||||
|
||||
<x:Double x:Key="StandardIconSize">14.0</x:Double>
|
||||
<Thickness x:Key="StandardIndentMargin">13,0,0,0</Thickness>
|
||||
<Thickness x:Key="StandardControlMargin">0,24,0,0</Thickness>
|
||||
<x:Double x:Key="StandardBoxMinWidth">250</x:Double>
|
||||
<x:Double x:Key="StandardBoxMinWidth">248</x:Double>
|
||||
<x:Double x:Key="StandardControlMaxWidth">1000</x:Double>
|
||||
<Thickness x:Key="SettingStackMargin">13,0,13,48</Thickness>
|
||||
<Thickness x:Key="SettingStackMargin">0,0,0,0</Thickness>
|
||||
|
||||
<!-- We're purposefully not providing a DataType here.
|
||||
This is expected to be used with an IReference<Microsoft::Terminal::Core::Color>.
|
||||
We're doing all the data type handling in the used converters.-->
|
||||
<DataTemplate x:Key="ColorPreviewTemplate">
|
||||
<Grid ColumnSpacing="5">
|
||||
<Grid ColumnSpacing="4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Rectangle Grid.Column="0"
|
||||
Width="13"
|
||||
Height="13"
|
||||
Width="12"
|
||||
Height="12"
|
||||
VerticalAlignment="Center"
|
||||
Fill="{Binding Converter={StaticResource ColorToBrushConverter}}"
|
||||
RadiusX="2"
|
||||
@@ -112,13 +111,13 @@
|
||||
<!-- Used to stack a group of settings -->
|
||||
<Style x:Key="SettingsStackStyle"
|
||||
TargetType="StackPanel">
|
||||
<Setter Property="Margin" Value="{StaticResource SettingStackMargin}" />
|
||||
<Setter Property="MaxWidth" Value="{StaticResource StandardControlMaxWidth}" />
|
||||
</Style>
|
||||
|
||||
<!-- Used to stack a group of settings inside a pivot -->
|
||||
<Style x:Key="PivotStackStyle"
|
||||
TargetType="StackPanel">
|
||||
<Setter Property="Margin" Value="{StaticResource SettingStackMargin}" />
|
||||
<Setter Property="MaxWidth" Value="{StaticResource StandardControlMaxWidth}" />
|
||||
</Style>
|
||||
|
||||
<!-- Combo Box -->
|
||||
@@ -145,7 +144,7 @@
|
||||
|
||||
<!-- Text Block -->
|
||||
<Style x:Key="TextBlockSettingStyle"
|
||||
BasedOn="{StaticResource BaseTextBlockStyle}"
|
||||
BasedOn="{StaticResource BodyTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="MinWidth" Value="{StaticResource StandardBoxMinWidth}" />
|
||||
<Setter Property="MaxWidth" Value="400" />
|
||||
@@ -155,24 +154,27 @@
|
||||
</Style>
|
||||
|
||||
<Style x:Key="TextBlockSubHeaderStyle"
|
||||
BasedOn="{StaticResource SubtitleTextBlockStyle}"
|
||||
BasedOn="{StaticResource BodyStrongTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="MaxWidth" Value="{StaticResource StandardControlMaxWidth}" />
|
||||
<Setter Property="Margin" Value="0,32,0,4" />
|
||||
</Style>
|
||||
|
||||
<!-- Used for disclaimers -->
|
||||
<Style x:Key="DisclaimerStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="TextWrapping" Value="Wrap" />
|
||||
<Setter Property="MaxWidth" Value="1000" />
|
||||
<Setter Property="MaxWidth" Value="{StaticResource StandardControlMaxWidth}" />
|
||||
<Setter Property="Foreground" Value="{ThemeResource TextFillColorSecondaryBrush}" />
|
||||
<Setter Property="Margin" Value="0,0,0,8" />
|
||||
</Style>
|
||||
|
||||
<!-- Used for flyout messages -->
|
||||
<Style x:Key="CustomFlyoutTextStyle"
|
||||
BasedOn="{StaticResource BaseTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="FontWeight" Value="Bold" />
|
||||
<Setter Property="Margin" Value="0,0,0,10" />
|
||||
<Setter Property="FontWeight" Value="SemiBold" />
|
||||
<Setter Property="Margin" Value="0,0,0,8" />
|
||||
<Setter Property="TextWrapping" Value="Wrap" />
|
||||
</Style>
|
||||
|
||||
@@ -200,8 +202,8 @@
|
||||
<Style x:Key="BrowseButtonStyle"
|
||||
BasedOn="{StaticResource BaseButtonStyle}"
|
||||
TargetType="Button">
|
||||
<Setter Property="Margin" Value="10,0,0,0" />
|
||||
<Setter Property="MinHeight" Value="33" />
|
||||
<Setter Property="Margin" Value="8,0,0,0" />
|
||||
<Setter Property="MinHeight" Value="32" />
|
||||
</Style>
|
||||
|
||||
<!-- Delete button based on Accent button template -->
|
||||
@@ -306,8 +308,8 @@
|
||||
<Style x:Key="ExtraSmallButtonStyle"
|
||||
BasedOn="{StaticResource BrowseButtonStyle}"
|
||||
TargetType="Button">
|
||||
<Setter Property="Height" Value="25" />
|
||||
<Setter Property="Width" Value="25" />
|
||||
<Setter Property="Height" Value="24" />
|
||||
<Setter Property="Width" Value="24" />
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="Margin" Value="0" />
|
||||
<Setter Property="MinHeight" Value="0" />
|
||||
@@ -317,25 +319,25 @@
|
||||
<Style x:Key="SmallButtonStyle"
|
||||
BasedOn="{StaticResource BrowseButtonStyle}"
|
||||
TargetType="Button">
|
||||
<Setter Property="Height" Value="33" />
|
||||
<Setter Property="Width" Value="33" />
|
||||
<Setter Property="Padding" Value="5" />
|
||||
<Setter Property="Height" Value="32" />
|
||||
<Setter Property="Width" Value="32" />
|
||||
<Setter Property="Padding" Value="4" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="AccentBrowseButtonStyle"
|
||||
BasedOn="{StaticResource AccentButtonStyle}"
|
||||
TargetType="Button">
|
||||
<Setter Property="Margin" Value="10,0,0,0" />
|
||||
<Setter Property="Margin" Value="8,0,0,0" />
|
||||
<Setter Property="VerticalAlignment" Value="Bottom" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="AccentSmallButtonStyle"
|
||||
BasedOn="{StaticResource AccentButtonStyle}"
|
||||
TargetType="Button">
|
||||
<Setter Property="Margin" Value="10,0,0,0" />
|
||||
<Setter Property="Margin" Value="8,0,0,0" />
|
||||
<Setter Property="VerticalAlignment" Value="Bottom" />
|
||||
<Setter Property="Height" Value="33" />
|
||||
<Setter Property="Width" Value="33" />
|
||||
<Setter Property="Height" Value="32" />
|
||||
<Setter Property="Width" Value="32" />
|
||||
<Setter Property="Padding" Value="5" />
|
||||
</Style>
|
||||
|
||||
@@ -350,8 +352,8 @@
|
||||
<Style x:Key="DeleteExtraSmallButtonStyle"
|
||||
BasedOn="{StaticResource DeleteButtonStyle}"
|
||||
TargetType="Button">
|
||||
<Setter Property="Height" Value="25" />
|
||||
<Setter Property="Width" Value="25" />
|
||||
<Setter Property="Height" Value="24" />
|
||||
<Setter Property="Width" Value="24" />
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="Margin" Value="0" />
|
||||
<Setter Property="MinHeight" Value="0" />
|
||||
@@ -360,7 +362,7 @@
|
||||
|
||||
<Style x:Key="IconButtonTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Margin" Value="10,0,0,0" />
|
||||
<Setter Property="Margin" Value="8,0,0,0" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="BIAlignmentToggleButtonStyle"
|
||||
@@ -1195,7 +1197,6 @@
|
||||
TargetType="Button">
|
||||
<Setter Property="Background" Value="{ThemeResource ExpanderHeaderBackground}" />
|
||||
<Setter Property="MinWidth" Value="{ThemeResource FlyoutThemeMinWidth}" />
|
||||
<Setter Property="MaxWidth" Value="1000" />
|
||||
<Setter Property="MinHeight" Value="64" />
|
||||
<Setter Property="BorderThickness" Value="{ThemeResource ExpanderHeaderBorderThickness}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource ExpanderHeaderBorderBrush}" />
|
||||
|
||||
@@ -84,16 +84,18 @@
|
||||
</Page.Resources>
|
||||
|
||||
<StackPanel Style="{StaticResource SettingsStackStyle}">
|
||||
<Border MaxWidth="{StaticResource StandardControlMaxWidth}">
|
||||
<Border MaxWidth="{StaticResource StandardControlMaxWidth}"
|
||||
CornerRadius="{StaticResource ControlCornerRadius}">
|
||||
<!-- Preview of the selected scheme -->
|
||||
<Grid Width="350"
|
||||
Height="160"
|
||||
<Grid Width="348"
|
||||
MaxWidth="{StaticResource StandardControlMaxWidth}"
|
||||
Margin="4"
|
||||
Margin="0,12"
|
||||
Padding="8"
|
||||
HorizontalAlignment="Left"
|
||||
Background="{x:Bind mtu:Converters.ColorToBrush(ViewModel.BackgroundColor.Color), Mode=OneWay}"
|
||||
BorderBrush="{ThemeResource SystemControlForegroundBaseMediumLowBrush}"
|
||||
BorderThickness="1">
|
||||
BorderBrush="{ThemeResource ControlStrongStrokeColorDefaultBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="{StaticResource ControlCornerRadius}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
@@ -468,8 +470,7 @@
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<Grid MaxWidth="1000"
|
||||
Margin="2,6,0,0"
|
||||
<Grid Margin="2,6,0,0"
|
||||
ColumnSpacing="4"
|
||||
Visibility="{x:Bind ViewModel.IsEditable, Mode=OneWay}">
|
||||
<Grid.ColumnDefinitions>
|
||||
|
||||
@@ -216,7 +216,7 @@
|
||||
Orientation="Horizontal">
|
||||
<IconSourceElement Width="16"
|
||||
Height="16"
|
||||
Margin="0,0,8,0"
|
||||
Margin="0,0,12,0"
|
||||
IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Profile.EvaluatedIcon), Mode=OneWay}" />
|
||||
|
||||
<TextBlock Text="{x:Bind Profile.Name, Mode=OneWay}" />
|
||||
@@ -248,7 +248,6 @@
|
||||
<!-- This styling matches that of ExpanderSettingContainerStyle for consistency -->
|
||||
<Style x:Key="ExpanderStyle"
|
||||
TargetType="muxc:Expander">
|
||||
<Setter Property="MaxWidth" Value="1000" />
|
||||
<Setter Property="MinHeight" Value="64" />
|
||||
<Setter Property="Margin" Value="0,4,0,0" />
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
@@ -289,8 +288,8 @@
|
||||
Padding="8"
|
||||
VerticalAlignment="Center"
|
||||
Background="{x:Bind mtu:Converters.ColorToBrush(BackgroundColor.Color), Mode=OneWay}"
|
||||
ColumnSpacing="1"
|
||||
CornerRadius="2"
|
||||
ColumnSpacing="2"
|
||||
CornerRadius="{StaticResource ControlCornerRadius}"
|
||||
RowSpacing="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
@@ -451,10 +450,12 @@
|
||||
|
||||
<!-- Learn more about fragment extensions -->
|
||||
<HyperlinkButton x:Uid="Extensions_DisclaimerHyperlink"
|
||||
Margin="-12,0,0,0"
|
||||
NavigateUri="https://go.microsoft.com/fwlink/?linkid=2321753" />
|
||||
|
||||
<!-- Grouping: Active Extensions -->
|
||||
<TextBlock x:Uid="Extensions_ActiveExtensionsHeader"
|
||||
Margin="0,12,0,8"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<ItemsControl x:Name="ActiveExtensionsList"
|
||||
IsTabStop="False"
|
||||
@@ -513,9 +514,11 @@
|
||||
</StackPanel>
|
||||
|
||||
<!-- Grouping: Modified Profiles -->
|
||||
<StackPanel Margin="{x:Bind CalculateMargin(ViewModel.NoProfilesModified), Mode=OneWay}"
|
||||
<StackPanel MaxWidth="{StaticResource StandardControlMaxWidth}"
|
||||
Margin="{x:Bind CalculateMargin(ViewModel.NoProfilesModified), Mode=OneWay}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(ViewModel.NoProfilesModified), Mode=OneWay}">
|
||||
<TextBlock x:Uid="Extensions_ModifiedProfilesHeader"
|
||||
Margin="0,0,0,8"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<ItemsControl x:Name="ModifiedProfilesList"
|
||||
IsTabStop="False"
|
||||
@@ -525,9 +528,11 @@
|
||||
</StackPanel>
|
||||
|
||||
<!-- Grouping: Added Profiles -->
|
||||
<StackPanel Margin="{x:Bind CalculateMargin(ViewModel.NoProfilesAdded), Mode=OneWay}"
|
||||
<StackPanel MaxWidth="{StaticResource StandardControlMaxWidth}"
|
||||
Margin="{x:Bind CalculateMargin(ViewModel.NoProfilesAdded), Mode=OneWay}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(ViewModel.NoProfilesAdded), Mode=OneWay}">
|
||||
<TextBlock x:Uid="Extensions_AddedProfilesHeader"
|
||||
Margin="0,0,0,8"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<ItemsControl x:Name="AddedProfilesList"
|
||||
IsTabStop="False"
|
||||
@@ -537,9 +542,11 @@
|
||||
</StackPanel>
|
||||
|
||||
<!-- Grouping: Added Color Schemes -->
|
||||
<StackPanel Margin="{x:Bind CalculateMargin(ViewModel.NoProfilesAdded), Mode=OneWay}"
|
||||
<StackPanel MaxWidth="{StaticResource StandardControlMaxWidth}"
|
||||
Margin="{x:Bind CalculateMargin(ViewModel.NoProfilesAdded), Mode=OneWay}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(ViewModel.NoSchemesAdded), Mode=OneWay}">
|
||||
<TextBlock x:Uid="Extensions_AddedColorSchemesHeader"
|
||||
Margin="0,0,0,8"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<ItemsControl x:Name="AddedColorSchemesList"
|
||||
IsTabStop="False"
|
||||
|
||||
@@ -83,6 +83,18 @@
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Enable Font Size Changes with Scrolling -->
|
||||
<local:SettingContainer x:Uid="Globals_ScrollToZoom">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ScrollToZoom, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Enable Window Opacity Changes with Scrolling -->
|
||||
<local:SettingContainer x:Uid="Globals_ScrollToChangeOpacity">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ScrollToChangeOpacity, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Detect URLs -->
|
||||
<local:SettingContainer x:Uid="Globals_DetectURLs">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.DetectURLs, Mode=TwoWay}"
|
||||
|
||||
@@ -25,6 +25,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, TrimPaste);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, SnapToGridOnResize);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, FocusFollowMouse);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ScrollToZoom);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ScrollToChangeOpacity);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, DetectURLs);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, SearchWebDefaultQueryUrl);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, WordDelimiters);
|
||||
|
||||
@@ -22,6 +22,8 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, TrimPaste);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, SnapToGridOnResize);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, FocusFollowMouse);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, ScrollToZoom);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, ScrollToChangeOpacity);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, DetectURLs);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(String, SearchWebDefaultQueryUrl);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(String, WordDelimiters);
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
<TextBlock Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Grid.ColumnSpan="2"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Text="{x:Bind Name}" />
|
||||
|
||||
@@ -192,8 +193,8 @@
|
||||
<local:SettingContainer x:Uid="Globals_LaunchSize"
|
||||
CurrentValue="{x:Bind ViewModel.LaunchSizeCurrentValue, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<Grid ColumnSpacing="10"
|
||||
RowSpacing="10">
|
||||
<Grid ColumnSpacing="12"
|
||||
RowSpacing="8">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
@@ -235,7 +236,7 @@
|
||||
<local:SettingContainer x:Uid="Globals_LaunchParameters"
|
||||
CurrentValue="{x:Bind ViewModel.LaunchParametersCurrentValue, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<Grid RowSpacing="10">
|
||||
<Grid RowSpacing="8">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="CommonResources.xaml" />
|
||||
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
@@ -60,7 +59,6 @@
|
||||
|
||||
<Thickness x:Key="NavigationViewContentGridBorderThickness">0</Thickness>
|
||||
<Thickness x:Key="NavigationViewMinimalContentGridBorderThickness">0</Thickness>
|
||||
|
||||
</ResourceDictionary>
|
||||
</Page.Resources>
|
||||
|
||||
@@ -73,28 +71,32 @@
|
||||
TabFocusNavigation="Cycle">
|
||||
<muxc:NavigationView.Resources>
|
||||
<ResourceDictionary>
|
||||
<Thickness x:Key="NavigationViewHeaderMargin">15,0,0,0</Thickness>
|
||||
<Thickness x:Key="NavigationViewHeaderMargin">0,4,0,0</Thickness>
|
||||
</ResourceDictionary>
|
||||
</muxc:NavigationView.Resources>
|
||||
<muxc:NavigationView.Header>
|
||||
<muxc:BreadcrumbBar x:Name="NavigationBreadcrumbBar"
|
||||
MaxWidth="{StaticResource StandardControlMaxWidth}"
|
||||
ItemClicked="BreadcrumbBar_ItemClicked"
|
||||
ItemsSource="{x:Bind Breadcrumbs}">
|
||||
<muxc:BreadcrumbBar.ItemTemplate>
|
||||
<DataTemplate x:DataType="local:Breadcrumb">
|
||||
<TextBlock Text="{x:Bind Label}" />
|
||||
</DataTemplate>
|
||||
</muxc:BreadcrumbBar.ItemTemplate>
|
||||
<muxc:BreadcrumbBar.Resources>
|
||||
<ResourceDictionary>
|
||||
<x:Double x:Key="BreadcrumbBarItemThemeFontSize">28</x:Double>
|
||||
<Thickness x:Key="BreadcrumbBarChevronPadding">11,4,12,0</Thickness>
|
||||
<FontWeight x:Key="BreadcrumbBarItemFontWeight">SemiBold</FontWeight>
|
||||
<x:Double x:Key="BreadcrumbBarChevronFontSize">16</x:Double>
|
||||
</ResourceDictionary>
|
||||
</muxc:BreadcrumbBar.Resources>
|
||||
</muxc:BreadcrumbBar>
|
||||
<Grid Padding="16,0">
|
||||
<!-- Wrapping the BreadcrumbBar in a Grid to avoid the title to drift (and no longer being aligned with the content of the page) when resizing the window. It's weird, I know. I believe it has to do with https://github.com/microsoft/microsoft-ui-xaml/issues/3842 doing funky things when setting a MaxWidth -->
|
||||
<muxc:BreadcrumbBar x:Name="NavigationBreadcrumbBar"
|
||||
MaxWidth="1000"
|
||||
ItemClicked="BreadcrumbBar_ItemClicked"
|
||||
ItemsSource="{x:Bind Breadcrumbs}">
|
||||
<muxc:BreadcrumbBar.ItemTemplate>
|
||||
<DataTemplate x:DataType="local:Breadcrumb">
|
||||
<TextBlock Text="{x:Bind Label}" />
|
||||
</DataTemplate>
|
||||
</muxc:BreadcrumbBar.ItemTemplate>
|
||||
<muxc:BreadcrumbBar.Resources>
|
||||
<ResourceDictionary>
|
||||
<x:Double x:Key="BreadcrumbBarItemThemeFontSize">20</x:Double>
|
||||
<Thickness x:Key="BreadcrumbBarChevronPadding">8,4,8,0</Thickness>
|
||||
<FontWeight x:Key="BreadcrumbBarItemFontWeight">SemiBold</FontWeight>
|
||||
<x:Double x:Key="BreadcrumbBarChevronFontSize">16</x:Double>
|
||||
</ResourceDictionary>
|
||||
</muxc:BreadcrumbBar.Resources>
|
||||
</muxc:BreadcrumbBar>
|
||||
|
||||
</Grid>
|
||||
</muxc:NavigationView.Header>
|
||||
|
||||
<muxc:NavigationView.MenuItems>
|
||||
@@ -191,7 +193,7 @@
|
||||
</muxc:NavigationViewItem>
|
||||
</muxc:NavigationView.FooterMenuItems>
|
||||
|
||||
<Grid Margin="0,0,0,0">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
@@ -199,7 +201,8 @@
|
||||
<ScrollViewer x:Name="SettingsMainPage_ScrollViewer"
|
||||
Grid.Row="0">
|
||||
<Frame x:Name="contentFrame"
|
||||
Grid.Row="0">
|
||||
Grid.Row="0"
|
||||
Padding="16,0,16,48">
|
||||
<Frame.ContentTransitions>
|
||||
<TransitionCollection>
|
||||
<NavigationThemeTransition>
|
||||
@@ -213,13 +216,13 @@
|
||||
</ScrollViewer>
|
||||
<!-- Explicitly set the background color on grid to prevent the navigation animation from overflowing it -->
|
||||
<Grid Grid.Row="1"
|
||||
Height="55"
|
||||
Height="56"
|
||||
BorderBrush="{ThemeResource DividerStrokeColorDefaultBrush}"
|
||||
BorderThickness="0,1,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Margin="30,0,0,0"
|
||||
<StackPanel Margin="32,0,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Vertical">
|
||||
@@ -242,7 +245,7 @@
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
<StackPanel Margin="0,0,30,0"
|
||||
<StackPanel Margin="0,0,32,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Horizontal">
|
||||
@@ -252,7 +255,7 @@
|
||||
Style="{StaticResource AccentButtonStyle}" />
|
||||
<Button x:Name="ResetButton"
|
||||
x:Uid="Settings_ResetSettingsButton"
|
||||
Margin="10,0,0,0"
|
||||
Margin="8,0,0,0"
|
||||
Click="ResetButton_Click" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
-->
|
||||
<CppWinRTNamespaceMergeDepth>4</CppWinRTNamespaceMergeDepth>
|
||||
<XamlComponentResourceLocation>nested</XamlComponentResourceLocation>
|
||||
<VersionInfoFileDescription>Windows Terminal Settings UI Library</VersionInfoFileDescription>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="NuGet Dependencies">
|
||||
<TerminalCppWinrt>true</TerminalCppWinrt>
|
||||
|
||||
@@ -227,8 +227,7 @@
|
||||
</ResourceDictionary>
|
||||
</Page.Resources>
|
||||
|
||||
<Grid Margin="{StaticResource SettingStackMargin}"
|
||||
RowSpacing="10">
|
||||
<Grid RowSpacing="12">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
@@ -271,7 +270,7 @@
|
||||
<!-- New Tab Menu Content -->
|
||||
<StackPanel Grid.Row="0"
|
||||
MaxWidth="{StaticResource StandardControlMaxWidth}"
|
||||
Spacing="10">
|
||||
Spacing="8">
|
||||
<Border Height="300"
|
||||
MaxWidth="{StaticResource StandardControlMaxWidth}"
|
||||
Margin="0,12,0,0"
|
||||
@@ -297,7 +296,7 @@
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="NewTabMenu_MoveToFolderTextBlock"
|
||||
Margin="10,0,0,0" />
|
||||
Margin="8,0,0,0" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button x:Name="DeleteMultipleButton"
|
||||
@@ -308,7 +307,7 @@
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="NewTabMenu_DeleteMultipleTextBlock"
|
||||
Margin="10,0,0,0" />
|
||||
Margin="8,0,0,0" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
@@ -359,7 +358,7 @@
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="5">
|
||||
Spacing="4">
|
||||
<!-- Select profile to add -->
|
||||
<ComboBox x:Name="AddProfileComboBox"
|
||||
MinWidth="{StaticResource StandardBoxMinWidth}"
|
||||
@@ -448,7 +447,7 @@
|
||||
<local:SettingContainer x:Uid="NewTabMenu_AddMatchProfiles"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithIcon}">
|
||||
<StackPanel Spacing="10">
|
||||
<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" />
|
||||
<TextBox x:Uid="NewTabMenu_AddMatchProfiles_Name"
|
||||
|
||||
@@ -123,11 +123,11 @@
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Spacing="5">
|
||||
<StackPanel Spacing="4">
|
||||
<ToggleButton AutomationProperties.Name="{x:Bind NullColorButtonLabel}"
|
||||
Click="NullColorButton_Clicked"
|
||||
IsChecked="{x:Bind IsNull(CurrentColor), Mode=OneWay}">
|
||||
<Grid ColumnSpacing="5">
|
||||
<Grid ColumnSpacing="4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
@@ -138,7 +138,7 @@
|
||||
Height="20"
|
||||
Background="{x:Bind mtu:Converters.ColorToBrush(NullColorPreview), Mode=OneWay}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="{ThemeResource ControlCornerRadius}" />
|
||||
CornerRadius="{StaticResource ControlCornerRadius}" />
|
||||
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{x:Bind NullColorButtonLabel}" />
|
||||
|
||||
@@ -32,8 +32,6 @@
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock x:Uid="Profile_BaseLayerDisclaimer"
|
||||
Grid.Row="0"
|
||||
Margin="{StaticResource StandardIndentMargin}"
|
||||
Style="{StaticResource DisclaimerStyle}"
|
||||
Visibility="{x:Bind Profile.IsBaseLayer}" />
|
||||
<StackPanel Grid.Row="1"
|
||||
@@ -123,7 +121,7 @@
|
||||
<ItemsControl ItemsSource="{x:Bind Profile.CurrentBellSounds, Mode=OneWay}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Spacing="5" />
|
||||
<StackPanel Spacing="4" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
@@ -156,7 +154,7 @@
|
||||
</StackPanel>
|
||||
<Button x:Uid="Profile_BellSoundAudioPreview"
|
||||
Grid.Column="1"
|
||||
Margin="5,0,0,0"
|
||||
Margin="4,0,0,0"
|
||||
VerticalAlignment="Stretch"
|
||||
Click="BellSoundAudioPreview_Click"
|
||||
IsEnabled="{x:Bind FileExists, Mode=OneWay}"
|
||||
@@ -167,7 +165,7 @@
|
||||
</Button>
|
||||
<Button x:Uid="Profile_BellSoundDelete"
|
||||
Grid.Column="2"
|
||||
Margin="5,0,0,0"
|
||||
Margin="4,0,0,0"
|
||||
VerticalAlignment="Stretch"
|
||||
Click="BellSoundDelete_Click"
|
||||
Style="{StaticResource DeleteButtonStyle}"
|
||||
@@ -185,7 +183,7 @@
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="Profile_AddBellSound"
|
||||
Margin="10,0,0,0" />
|
||||
Margin="8,0,0,0" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
@@ -50,27 +50,28 @@
|
||||
</ResourceDictionary>
|
||||
</Page.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid MaxWidth="{StaticResource StandardControlMaxWidth}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock x:Uid="Profile_BaseLayerDisclaimer"
|
||||
Grid.Row="0"
|
||||
Margin="{StaticResource StandardIndentMargin}"
|
||||
Style="{StaticResource DisclaimerStyle}"
|
||||
Visibility="{x:Bind Profile.IsBaseLayer}" />
|
||||
<StackPanel Grid.Row="1"
|
||||
Margin="0,12,0,0"
|
||||
Style="{StaticResource SettingsStackStyle}">
|
||||
<!-- Control Preview -->
|
||||
<Border MaxWidth="{StaticResource StandardControlMaxWidth}">
|
||||
<Border MaxWidth="{StaticResource StandardControlMaxWidth}"
|
||||
CornerRadius="{StaticResource ControlCornerRadius}">
|
||||
<Border x:Name="ControlPreview"
|
||||
Width="400"
|
||||
Height="180"
|
||||
Margin="0,12,0,12"
|
||||
HorizontalAlignment="Left"
|
||||
BorderBrush="{ThemeResource SystemControlForegroundBaseMediumLowBrush}"
|
||||
BorderThickness="1" />
|
||||
BorderBrush="{ThemeResource ControlStrongStrokeColorDefaultBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="{StaticResource ControlCornerRadius}" />
|
||||
</Border>
|
||||
|
||||
<local:Appearances Appearance="{x:Bind Profile.DefaultAppearance, Mode=OneWay}"
|
||||
@@ -131,9 +132,9 @@
|
||||
<Border Margin="0,12,0,12"
|
||||
Padding="2,0,2,0"
|
||||
HorizontalAlignment="Left"
|
||||
BorderBrush="{ThemeResource SystemControlForegroundBaseMediumLowBrush}"
|
||||
BorderBrush="{ThemeResource CardStrokeColorDefaultSolidBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="8">
|
||||
CornerRadius="{StaticResource OverlayCornerRadius}">
|
||||
<Grid>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
@@ -206,23 +207,23 @@
|
||||
<TextBlock x:Uid="Profile_UnfocusedAppearanceTextBlock"
|
||||
Style="{StaticResource TitleTextBlockStyle}" />
|
||||
<Button x:Uid="Profile_CreateUnfocusedAppearanceButton"
|
||||
Margin="10,0,0,0"
|
||||
Margin="8,0,0,0"
|
||||
Click="CreateUnfocusedAppearance_Click"
|
||||
Style="{StaticResource BaseButtonStyle}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.HasUnfocusedAppearance), Mode=OneWay}">
|
||||
<Button.Content>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon Margin="0,3,0,0"
|
||||
<FontIcon Margin="0,4,0,0"
|
||||
FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="Profile_AddAppearanceButton"
|
||||
Margin="10,0,0,0"
|
||||
Margin="8,0,0,0"
|
||||
FontSize="{StaticResource StandardIconSize}" />
|
||||
</StackPanel>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button x:Uid="Profile_DeleteUnfocusedAppearanceButton"
|
||||
Margin="10,0,0,0"
|
||||
Margin="8,0,0,0"
|
||||
Click="DeleteUnfocusedAppearance_Click"
|
||||
Style="{StaticResource DeleteButtonStyle}"
|
||||
Visibility="{x:Bind Profile.HasUnfocusedAppearance, Mode=OneWay}">
|
||||
@@ -231,7 +232,7 @@
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="Profile_DeleteAppearanceButton"
|
||||
Margin="10,0,0,0"
|
||||
Margin="8,0,0,0"
|
||||
FontSize="{StaticResource StandardIconSize}" />
|
||||
</StackPanel>
|
||||
</Button.Content>
|
||||
|
||||
@@ -22,14 +22,13 @@
|
||||
</Page.Resources>
|
||||
|
||||
<!-- Use a Grid instead of a StackPanel. StackPanel suppresses the inner ScrollViewer. -->
|
||||
<Grid>
|
||||
<Grid MaxWidth="{StaticResource StandardControlMaxWidth}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock x:Uid="Profile_BaseLayerDisclaimer"
|
||||
Grid.Row="0"
|
||||
Margin="{StaticResource StandardIndentMargin}"
|
||||
Style="{StaticResource DisclaimerStyle}"
|
||||
Visibility="{x:Bind Profile.IsBaseLayer}" />
|
||||
<StackPanel Grid.Row="1"
|
||||
@@ -64,7 +63,7 @@
|
||||
Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind Profile.Commandline, Mode=TwoWay}" />
|
||||
<Button x:Uid="Profile_CommandlineBrowse"
|
||||
Margin="0,10,0,0"
|
||||
Margin="0,8,0,0"
|
||||
Click="Commandline_Click"
|
||||
Style="{StaticResource BrowseButtonStyle}" />
|
||||
</StackPanel>
|
||||
@@ -87,13 +86,13 @@
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button x:Name="StartingDirectoryBrowse"
|
||||
x:Uid="Profile_StartingDirectoryBrowse"
|
||||
Margin="0,10,10,0"
|
||||
Margin="0,12,12,0"
|
||||
Click="StartingDirectory_Click"
|
||||
IsEnabled="{x:Bind mtu:Converters.InvertBoolean(Profile.UseParentProcessDirectory), Mode=OneWay}"
|
||||
Style="{StaticResource BrowseButtonStyle}" />
|
||||
<CheckBox x:Name="StartingDirectoryUseParentCheckbox"
|
||||
x:Uid="Profile_StartingDirectoryUseParentCheckbox"
|
||||
Margin="0,5,0,0"
|
||||
Margin="0,4,0,0"
|
||||
IsChecked="{x:Bind Profile.UseParentProcessDirectory, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
@@ -123,7 +122,7 @@
|
||||
</Grid>
|
||||
</local:SettingContainer.CurrentValue>
|
||||
<local:SettingContainer.Content>
|
||||
<Grid ColumnSpacing="10">
|
||||
<Grid ColumnSpacing="12">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
@@ -150,7 +149,7 @@
|
||||
Visibility="{x:Bind Profile.UsingBuiltInIcon, Mode=OneWay}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="local:EnumEntry">
|
||||
<Grid ColumnSpacing="10">
|
||||
<Grid ColumnSpacing="12">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="16" />
|
||||
<ColumnDefinition Width="*" />
|
||||
@@ -226,7 +225,7 @@
|
||||
</local:SettingContainer>
|
||||
|
||||
<TextBlock x:Uid="Profile_AdditionalSettingsHeader"
|
||||
Margin="0,48,0,0"
|
||||
Margin="0,32,0,4"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
|
||||
<Button x:Name="AppearanceNavigator"
|
||||
@@ -249,7 +248,7 @@
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="Profile_DeleteButton"
|
||||
Margin="10,0,0,0" />
|
||||
Margin="8,0,0,0" />
|
||||
</StackPanel>
|
||||
</Button.Content>
|
||||
<Button.Flyout>
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="Profile_DeleteButton"
|
||||
Margin="10,0,0,0" />
|
||||
Margin="8,0,0,0" />
|
||||
</StackPanel>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock x:Uid="Profile_BaseLayerDisclaimer"
|
||||
Grid.Row="0"
|
||||
Margin="{StaticResource StandardIndentMargin}"
|
||||
Style="{StaticResource DisclaimerStyle}"
|
||||
Visibility="{x:Bind Profile.IsBaseLayer}" />
|
||||
<StackPanel Grid.Row="1"
|
||||
|
||||
@@ -1736,6 +1736,14 @@
|
||||
<value>Bereich automatisch mit dem Mauszeiger fokussieren</value>
|
||||
<comment>Header for a control to toggle the "focus follow mouse" setting. When enabled, hovering over a pane puts it in focus.</comment>
|
||||
</data>
|
||||
<data name="Globals_ScrollToZoom.Header" xml:space="preserve">
|
||||
<value>Passen Sie die Schriftgröße des Terminals an, indem Sie die STRG-TASTE gedrückt halten und scrollen</value>
|
||||
<comment>Header for a control to toggle font size changes with scrolling. When enabled, holding the Ctrl key while scrolling will increase or decrease the terminal font size.</comment>
|
||||
</data>
|
||||
<data name="Globals_ScrollToChangeOpacity.Header" xml:space="preserve">
|
||||
<value>Passen Sie die Deckkraft des Terminals an, indem Sie scrollen, während Sie die STRG- und UMSCHALTTASTE gedrückt halten</value>
|
||||
<comment>Header for a control to toggle opacity changes with scrolling. When enabled, holding the Ctrl and Shift keys while scrolling will increase or decrease the window opacity.</comment>
|
||||
</data>
|
||||
<data name="Globals_DisableAnimationsReversed.Header" xml:space="preserve">
|
||||
<value>Bereichsanimationen</value>
|
||||
<comment>Header for a control to toggle animations on panes. "Enabled" value enables the animations.</comment>
|
||||
|
||||
@@ -1736,6 +1736,14 @@
|
||||
<value>Automatically focus pane on mouse hover</value>
|
||||
<comment>Header for a control to toggle the "focus follow mouse" setting. When enabled, hovering over a pane puts it in focus.</comment>
|
||||
</data>
|
||||
<data name="Globals_ScrollToZoom.Header" xml:space="preserve">
|
||||
<value>Adjust terminal font size by scrolling while holding the Ctrl key</value>
|
||||
<comment>Header for a control to toggle font size changes with scrolling. When enabled, holding the Ctrl key while scrolling will increase or decrease the terminal font size.</comment>
|
||||
</data>
|
||||
<data name="Globals_ScrollToChangeOpacity.Header" xml:space="preserve">
|
||||
<value>Adjust terminal opacity by scrolling while holding the Ctrl and Shift keys</value>
|
||||
<comment>Header for a control to toggle opacity changes with scrolling. When enabled, holding the Ctrl and Shift keys while scrolling will increase or decrease the window opacity.</comment>
|
||||
</data>
|
||||
<data name="Globals_DisableAnimationsReversed.Header" xml:space="preserve">
|
||||
<value>Pane animations</value>
|
||||
<comment>Header for a control to toggle animations on panes. "Enabled" value enables the animations.</comment>
|
||||
|
||||
@@ -1736,6 +1736,14 @@
|
||||
<value>Centrarse automáticamente en el panel al pasar el mouse</value>
|
||||
<comment>Header for a control to toggle the "focus follow mouse" setting. When enabled, hovering over a pane puts it in focus.</comment>
|
||||
</data>
|
||||
<data name="Globals_ScrollToZoom.Header" xml:space="preserve">
|
||||
<value>Ajuste el tamaño de fuente del terminal desplazándose mientras mantiene presionada la tecla Ctrl</value>
|
||||
<comment>Header for a control to toggle font size changes with scrolling. When enabled, holding the Ctrl key while scrolling will increase or decrease the terminal font size.</comment>
|
||||
</data>
|
||||
<data name="Globals_ScrollToChangeOpacity.Header" xml:space="preserve">
|
||||
<value>Ajuste la opacidad del terminal desplazándose mientras mantiene presionadas las teclas CTRL y Mayús</value>
|
||||
<comment>Header for a control to toggle opacity changes with scrolling. When enabled, holding the Ctrl and Shift keys while scrolling will increase or decrease the window opacity.</comment>
|
||||
</data>
|
||||
<data name="Globals_DisableAnimationsReversed.Header" xml:space="preserve">
|
||||
<value>Animaciones de panel</value>
|
||||
<comment>Header for a control to toggle animations on panes. "Enabled" value enables the animations.</comment>
|
||||
|
||||
@@ -1736,6 +1736,14 @@
|
||||
<value>Mise au point automatique du volet au survol de la souris</value>
|
||||
<comment>Header for a control to toggle the "focus follow mouse" setting. When enabled, hovering over a pane puts it in focus.</comment>
|
||||
</data>
|
||||
<data name="Globals_ScrollToZoom.Header" xml:space="preserve">
|
||||
<value>Ajustez la taille de police du terminal en faisant défiler tout en maintenant la touche Ctrl enfoncée</value>
|
||||
<comment>Header for a control to toggle font size changes with scrolling. When enabled, holding the Ctrl key while scrolling will increase or decrease the terminal font size.</comment>
|
||||
</data>
|
||||
<data name="Globals_ScrollToChangeOpacity.Header" xml:space="preserve">
|
||||
<value>Ajustez l’opacité du terminal en faisant défiler tout en maintenant les touches Ctrl et Maj enfoncées</value>
|
||||
<comment>Header for a control to toggle opacity changes with scrolling. When enabled, holding the Ctrl and Shift keys while scrolling will increase or decrease the window opacity.</comment>
|
||||
</data>
|
||||
<data name="Globals_DisableAnimationsReversed.Header" xml:space="preserve">
|
||||
<value>Animations du volet</value>
|
||||
<comment>Header for a control to toggle animations on panes. "Enabled" value enables the animations.</comment>
|
||||
|
||||
@@ -1736,6 +1736,14 @@
|
||||
<value>Riquadro di messa a fuoco automatica al passaggio del mouse</value>
|
||||
<comment>Header for a control to toggle the "focus follow mouse" setting. When enabled, hovering over a pane puts it in focus.</comment>
|
||||
</data>
|
||||
<data name="Globals_ScrollToZoom.Header" xml:space="preserve">
|
||||
<value>Regola le dimensioni del carattere del terminale scorrendo tenendo premuto il tasto CTRL</value>
|
||||
<comment>Header for a control to toggle font size changes with scrolling. When enabled, holding the Ctrl key while scrolling will increase or decrease the terminal font size.</comment>
|
||||
</data>
|
||||
<data name="Globals_ScrollToChangeOpacity.Header" xml:space="preserve">
|
||||
<value>Regola l'opacità del terminale scorrendo mentre tieni premuti i tasti CTRL e MAIUSC</value>
|
||||
<comment>Header for a control to toggle opacity changes with scrolling. When enabled, holding the Ctrl and Shift keys while scrolling will increase or decrease the window opacity.</comment>
|
||||
</data>
|
||||
<data name="Globals_DisableAnimationsReversed.Header" xml:space="preserve">
|
||||
<value>Riquadro animazioni</value>
|
||||
<comment>Header for a control to toggle animations on panes. "Enabled" value enables the animations.</comment>
|
||||
|
||||
@@ -1736,6 +1736,14 @@
|
||||
<value>マウスをポイントしたときにフォーカス ウィンドウを自動的に表示する</value>
|
||||
<comment>Header for a control to toggle the "focus follow mouse" setting. When enabled, hovering over a pane puts it in focus.</comment>
|
||||
</data>
|
||||
<data name="Globals_ScrollToZoom.Header" xml:space="preserve">
|
||||
<value>Ctrl キーを押しながらスクロールして、ターミナルのフォント サイズを調整します</value>
|
||||
<comment>Header for a control to toggle font size changes with scrolling. When enabled, holding the Ctrl key while scrolling will increase or decrease the terminal font size.</comment>
|
||||
</data>
|
||||
<data name="Globals_ScrollToChangeOpacity.Header" xml:space="preserve">
|
||||
<value>Ctrl キーと Shift キーを押しながらスクロールして、ターミナルの不透明度を調整します</value>
|
||||
<comment>Header for a control to toggle opacity changes with scrolling. When enabled, holding the Ctrl and Shift keys while scrolling will increase or decrease the window opacity.</comment>
|
||||
</data>
|
||||
<data name="Globals_DisableAnimationsReversed.Header" xml:space="preserve">
|
||||
<value>ウィンドウのアニメーション</value>
|
||||
<comment>Header for a control to toggle animations on panes. "Enabled" value enables the animations.</comment>
|
||||
|
||||
@@ -1736,6 +1736,14 @@
|
||||
<value>마우스를 위에 가져다 대면 자동으로 포커스 창이 실행됨</value>
|
||||
<comment>Header for a control to toggle the "focus follow mouse" setting. When enabled, hovering over a pane puts it in focus.</comment>
|
||||
</data>
|
||||
<data name="Globals_ScrollToZoom.Header" xml:space="preserve">
|
||||
<value>Ctrl 키를 누른 상태에서 스크롤하여 터미널 글꼴 크기 조정</value>
|
||||
<comment>Header for a control to toggle font size changes with scrolling. When enabled, holding the Ctrl key while scrolling will increase or decrease the terminal font size.</comment>
|
||||
</data>
|
||||
<data name="Globals_ScrollToChangeOpacity.Header" xml:space="preserve">
|
||||
<value>Ctrl 키와 Shift 키를 누른 상태에서 스크롤하여 터미널 불투명도 조정</value>
|
||||
<comment>Header for a control to toggle opacity changes with scrolling. When enabled, holding the Ctrl and Shift keys while scrolling will increase or decrease the window opacity.</comment>
|
||||
</data>
|
||||
<data name="Globals_DisableAnimationsReversed.Header" xml:space="preserve">
|
||||
<value>창 애니메이션</value>
|
||||
<comment>Header for a control to toggle animations on panes. "Enabled" value enables the animations.</comment>
|
||||
|
||||
@@ -1736,6 +1736,14 @@
|
||||
<value>Focalizar painel automaticamente ao passar o mouse</value>
|
||||
<comment>Header for a control to toggle the "focus follow mouse" setting. When enabled, hovering over a pane puts it in focus.</comment>
|
||||
</data>
|
||||
<data name="Globals_ScrollToZoom.Header" xml:space="preserve">
|
||||
<value>Ajustar o tamanho da fonte do terminal rolando enquanto mantém a tecla Ctrl pressionada</value>
|
||||
<comment>Header for a control to toggle font size changes with scrolling. When enabled, holding the Ctrl key while scrolling will increase or decrease the terminal font size.</comment>
|
||||
</data>
|
||||
<data name="Globals_ScrollToChangeOpacity.Header" xml:space="preserve">
|
||||
<value>Ajustar a opacidade do terminal ao rolar enquanto mantém as teclas Ctrl e Shift</value>
|
||||
<comment>Header for a control to toggle opacity changes with scrolling. When enabled, holding the Ctrl and Shift keys while scrolling will increase or decrease the window opacity.</comment>
|
||||
</data>
|
||||
<data name="Globals_DisableAnimationsReversed.Header" xml:space="preserve">
|
||||
<value>Animações do painel</value>
|
||||
<comment>Header for a control to toggle animations on panes. "Enabled" value enables the animations.</comment>
|
||||
|
||||
@@ -1736,6 +1736,14 @@
|
||||
<value>Áϋτомàţīćąłłý ƒόćŭś рåπę öń мõùšě ђöνëŗ !!! !!! !!! !!!</value>
|
||||
<comment>Header for a control to toggle the "focus follow mouse" setting. When enabled, hovering over a pane puts it in focus.</comment>
|
||||
</data>
|
||||
<data name="Globals_ScrollToZoom.Header" xml:space="preserve">
|
||||
<value>Аδĵŭŝт ţєŗмιņăℓ ƒøпť ѕįżε вỳ şċѓοℓℓíńğ ẃħïĺє ĥöľδīйģ τђе €ŧřŀ ќëÿ !!! !!! !!! !!! !!! !!! !</value>
|
||||
<comment>Header for a control to toggle font size changes with scrolling. When enabled, holding the Ctrl key while scrolling will increase or decrease the terminal font size.</comment>
|
||||
</data>
|
||||
<data name="Globals_ScrollToChangeOpacity.Header" xml:space="preserve">
|
||||
<value>Ąδĵüšţ ŧęřмìńąĺ ôрǻčĩτў ьγ šćřοļĺįήĝ ẅђϊłę ħōļδîʼnğ ťђз Çťгł àиδ Śђĭƒт ķęÿŝ !!! !!! !!! !!! !!! !!! !!! !</value>
|
||||
<comment>Header for a control to toggle opacity changes with scrolling. When enabled, holding the Ctrl and Shift keys while scrolling will increase or decrease the window opacity.</comment>
|
||||
</data>
|
||||
<data name="Globals_DisableAnimationsReversed.Header" xml:space="preserve">
|
||||
<value>Ρǻйě ǻйϊмäţіőηş !!! !</value>
|
||||
<comment>Header for a control to toggle animations on panes. "Enabled" value enables the animations.</comment>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user