mirror of
https://github.com/microsoft/terminal.git
synced 2026-05-21 06:18:34 +00:00
Compare commits
16 Commits
dev/duhowe
...
dev/migrie
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25e7320940 | ||
|
|
17e6126597 | ||
|
|
7a83c0f167 | ||
|
|
b2666fb346 | ||
|
|
8f4fdf9751 | ||
|
|
33a80191c1 | ||
|
|
84ae7adec6 | ||
|
|
a6ebdd3d4a | ||
|
|
031998bfc3 | ||
|
|
41e08a68bd | ||
|
|
81170aff78 | ||
|
|
c90ace8326 | ||
|
|
fd30d00304 | ||
|
|
45ddf94067 | ||
|
|
abb06e1918 | ||
|
|
eb2899e267 |
10
.github/workflows/spelling2.yml
vendored
10
.github/workflows/spelling2.yml
vendored
@@ -93,7 +93,7 @@ jobs:
|
||||
steps:
|
||||
- name: check-spelling
|
||||
id: spelling
|
||||
uses: check-spelling/check-spelling@c635c2f3f714eec2fcf27b643a1919b9a811ef2e # v0.0.25
|
||||
uses: check-spelling/check-spelling@cfb6f7e75bbfc89c71eaa30366d0c166f1bd9c8c # v0.0.26
|
||||
with:
|
||||
suppress_push_for_open_pull_request: ${{ github.actor != 'dependabot[bot]' && 1 }}
|
||||
checkout: true
|
||||
@@ -153,9 +153,8 @@ jobs:
|
||||
if: (success() || failure()) && needs.spelling.outputs.followup && github.event_name == 'push'
|
||||
steps:
|
||||
- name: comment
|
||||
uses: check-spelling/check-spelling@c635c2f3f714eec2fcf27b643a1919b9a811ef2e # v0.0.25
|
||||
uses: check-spelling/check-spelling@cfb6f7e75bbfc89c71eaa30366d0c166f1bd9c8c # v0.0.26
|
||||
with:
|
||||
checkout: true
|
||||
spell_check_this: microsoft/terminal@main
|
||||
task: ${{ needs.spelling.outputs.followup }}
|
||||
|
||||
@@ -171,9 +170,8 @@ jobs:
|
||||
if: (success() || failure()) && needs.spelling.outputs.followup && contains(github.event_name, 'pull_request')
|
||||
steps:
|
||||
- name: comment
|
||||
uses: check-spelling/check-spelling@c635c2f3f714eec2fcf27b643a1919b9a811ef2e # v0.0.25
|
||||
uses: check-spelling/check-spelling@cfb6f7e75bbfc89c71eaa30366d0c166f1bd9c8c # v0.0.26
|
||||
with:
|
||||
checkout: true
|
||||
spell_check_this: microsoft/terminal@main
|
||||
task: ${{ needs.spelling.outputs.followup }}
|
||||
experimental_apply_changes_via_bot: ${{ github.repository_owner != 'microsoft' && 1 }}
|
||||
@@ -197,7 +195,7 @@ jobs:
|
||||
cancel-in-progress: false
|
||||
steps:
|
||||
- name: apply spelling updates
|
||||
uses: check-spelling/check-spelling@c635c2f3f714eec2fcf27b643a1919b9a811ef2e # v0.0.25
|
||||
uses: check-spelling/check-spelling@cfb6f7e75bbfc89c71eaa30366d0c166f1bd9c8c # v0.0.26
|
||||
with:
|
||||
experimental_apply_changes_via_bot: ${{ github.repository_owner != 'microsoft' && 1 }}
|
||||
checkout: true
|
||||
|
||||
@@ -350,7 +350,7 @@ void ROW::_init() noexcept
|
||||
std::iota(_charOffsets.begin(), _charOffsets.end(), uint16_t{ 0 });
|
||||
#endif
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(pop)
|
||||
}
|
||||
|
||||
void ROW::CopyFrom(const ROW& source)
|
||||
@@ -1143,6 +1143,13 @@ til::CoordType ROW::GetTrailingColumnAtCharOffset(const ptrdiff_t offset) const
|
||||
return _createCharToColumnMapper(offset).GetTrailingColumnAt(offset);
|
||||
}
|
||||
|
||||
uint16_t ROW::GetCharOffset(til::CoordType col) const noexcept
|
||||
{
|
||||
const auto columns = GetReadableColumnCount();
|
||||
const auto colBeg = clamp(col, 0, columns);
|
||||
return _uncheckedCharOffset(gsl::narrow_cast<size_t>(colBeg));
|
||||
}
|
||||
|
||||
DelimiterClass ROW::DelimiterClassAt(til::CoordType column, const std::wstring_view& wordDelimiters) const noexcept
|
||||
{
|
||||
const auto col = _clampedColumn(column);
|
||||
|
||||
@@ -172,6 +172,7 @@ public:
|
||||
std::wstring_view GetText(til::CoordType columnBegin, til::CoordType columnEnd) const noexcept;
|
||||
til::CoordType GetLeadingColumnAtCharOffset(ptrdiff_t offset) const noexcept;
|
||||
til::CoordType GetTrailingColumnAtCharOffset(ptrdiff_t offset) const noexcept;
|
||||
uint16_t GetCharOffset(til::CoordType col) const noexcept;
|
||||
DelimiterClass DelimiterClassAt(til::CoordType column, const std::wstring_view& wordDelimiters) const noexcept;
|
||||
|
||||
auto AttrBegin() const noexcept { return _attr.begin(); }
|
||||
|
||||
@@ -1421,7 +1421,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_ARE_EQUAL(L"profile0", terminalArgs.Profile());
|
||||
VERIFY_IS_NULL(terminalArgs.Elevate());
|
||||
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
|
||||
const auto termSettings = termSettingsResult.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(L"cmd.exe", termSettings->Commandline());
|
||||
VERIFY_ARE_EQUAL(false, termSettings->Elevate());
|
||||
@@ -1444,7 +1444,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_ARE_EQUAL(L"profile1", terminalArgs.Profile());
|
||||
VERIFY_IS_NULL(terminalArgs.Elevate());
|
||||
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
|
||||
const auto termSettings = termSettingsResult.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(L"pwsh.exe", termSettings->Commandline());
|
||||
VERIFY_ARE_EQUAL(true, termSettings->Elevate());
|
||||
@@ -1467,7 +1467,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_ARE_EQUAL(L"profile2", terminalArgs.Profile());
|
||||
VERIFY_IS_NULL(terminalArgs.Elevate());
|
||||
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
|
||||
const auto termSettings = termSettingsResult.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(L"wsl.exe", termSettings->Commandline());
|
||||
VERIFY_ARE_EQUAL(false, termSettings->Elevate());
|
||||
@@ -1492,7 +1492,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_NOT_NULL(terminalArgs.Elevate());
|
||||
VERIFY_IS_FALSE(terminalArgs.Elevate().Value());
|
||||
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
|
||||
const auto termSettings = termSettingsResult.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(L"cmd.exe", termSettings->Commandline());
|
||||
VERIFY_ARE_EQUAL(false, termSettings->Elevate());
|
||||
@@ -1516,7 +1516,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_NOT_NULL(terminalArgs.Elevate());
|
||||
VERIFY_IS_FALSE(terminalArgs.Elevate().Value());
|
||||
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
|
||||
const auto termSettings = termSettingsResult.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(L"pwsh.exe", termSettings->Commandline());
|
||||
VERIFY_ARE_EQUAL(false, termSettings->Elevate());
|
||||
@@ -1540,7 +1540,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_NOT_NULL(terminalArgs.Elevate());
|
||||
VERIFY_IS_FALSE(terminalArgs.Elevate().Value());
|
||||
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
|
||||
const auto termSettings = termSettingsResult.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(L"wsl.exe", termSettings->Commandline());
|
||||
VERIFY_ARE_EQUAL(false, termSettings->Elevate());
|
||||
@@ -1565,7 +1565,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_NOT_NULL(terminalArgs.Elevate());
|
||||
VERIFY_IS_TRUE(terminalArgs.Elevate().Value());
|
||||
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
|
||||
const auto termSettings = termSettingsResult.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(L"cmd.exe", termSettings->Commandline());
|
||||
VERIFY_ARE_EQUAL(true, termSettings->Elevate());
|
||||
@@ -1588,7 +1588,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_NOT_NULL(terminalArgs.Elevate());
|
||||
VERIFY_IS_TRUE(terminalArgs.Elevate().Value());
|
||||
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
|
||||
const auto termSettings = termSettingsResult.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(L"pwsh.exe", termSettings->Commandline());
|
||||
VERIFY_ARE_EQUAL(true, termSettings->Elevate());
|
||||
@@ -1612,7 +1612,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_NOT_NULL(terminalArgs.Elevate());
|
||||
VERIFY_IS_TRUE(terminalArgs.Elevate().Value());
|
||||
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
|
||||
const auto termSettings = termSettingsResult.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(L"wsl.exe", termSettings->Commandline());
|
||||
VERIFY_ARE_EQUAL(true, termSettings->Elevate());
|
||||
|
||||
@@ -308,6 +308,11 @@ namespace TerminalAppLocalTests
|
||||
// TerminalPage and not only create them successfully, but also create a
|
||||
// tab using those settings successfully.
|
||||
|
||||
// - - - IMPORTANT - - -
|
||||
// GH#14623: "closeOnExit": "never" is important for all test profiles. Without
|
||||
// it, the spawned process exits immediately in the UAP test environment,
|
||||
// and the default "automatic" close-on-exit behavior removes the
|
||||
// tab/pane asynchronously, racing against test assertions.
|
||||
static constexpr std::wstring_view settingsJson0{ LR"(
|
||||
{
|
||||
"defaultProfile": "{6239a42c-1111-49a3-80bd-e8fdd045185c}",
|
||||
@@ -315,12 +320,14 @@ namespace TerminalAppLocalTests
|
||||
{
|
||||
"name" : "profile0",
|
||||
"guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}",
|
||||
"historySize": 1
|
||||
"historySize": 1,
|
||||
"closeOnExit": "never"
|
||||
},
|
||||
{
|
||||
"name" : "profile1",
|
||||
"guid": "{6239a42c-2222-49a3-80bd-e8fdd045185c}",
|
||||
"historySize": 2
|
||||
"historySize": 2,
|
||||
"closeOnExit": "never"
|
||||
}
|
||||
]
|
||||
})" };
|
||||
@@ -347,10 +354,6 @@ namespace TerminalAppLocalTests
|
||||
|
||||
void TabTests::TryDuplicateBadTab()
|
||||
{
|
||||
BEGIN_TEST_METHOD_PROPERTIES()
|
||||
TEST_METHOD_PROPERTY(L"Ignore", L"True") // GH#19610 tracks re-enabling this test
|
||||
END_TEST_METHOD_PROPERTIES()
|
||||
|
||||
// * Create a tab with a profile with GUID 1
|
||||
// * Reload the settings so that GUID 1 is no longer in the list of profiles
|
||||
// * Try calling _DuplicateFocusedTab on tab 1
|
||||
@@ -365,12 +368,14 @@ namespace TerminalAppLocalTests
|
||||
{
|
||||
"name" : "profile0",
|
||||
"guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}",
|
||||
"historySize": 1
|
||||
"historySize": 1,
|
||||
"closeOnExit": "never"
|
||||
},
|
||||
{
|
||||
"name" : "profile1",
|
||||
"guid": "{6239a42c-2222-49a3-80bd-e8fdd045185c}",
|
||||
"historySize": 2
|
||||
"historySize": 2,
|
||||
"closeOnExit": "never"
|
||||
}
|
||||
]
|
||||
})" };
|
||||
@@ -382,7 +387,8 @@ namespace TerminalAppLocalTests
|
||||
{
|
||||
"name" : "profile1",
|
||||
"guid": "{6239a42c-2222-49a3-80bd-e8fdd045185c}",
|
||||
"historySize": 2
|
||||
"historySize": 2,
|
||||
"closeOnExit": "never"
|
||||
}
|
||||
]
|
||||
})" };
|
||||
@@ -438,10 +444,6 @@ namespace TerminalAppLocalTests
|
||||
|
||||
void TabTests::TryDuplicateBadPane()
|
||||
{
|
||||
BEGIN_TEST_METHOD_PROPERTIES()
|
||||
TEST_METHOD_PROPERTY(L"Ignore", L"True") // GH#19610 tracks re-enabling this test
|
||||
END_TEST_METHOD_PROPERTIES()
|
||||
|
||||
// * Create a tab with a profile with GUID 1
|
||||
// * Reload the settings so that GUID 1 is no longer in the list of profiles
|
||||
// * Try calling _SplitPane(Duplicate) on tab 1
|
||||
@@ -456,12 +458,14 @@ namespace TerminalAppLocalTests
|
||||
{
|
||||
"name" : "profile0",
|
||||
"guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}",
|
||||
"historySize": 1
|
||||
"historySize": 1,
|
||||
"closeOnExit": "never"
|
||||
},
|
||||
{
|
||||
"name" : "profile1",
|
||||
"guid": "{6239a42c-2222-49a3-80bd-e8fdd045185c}",
|
||||
"historySize": 2
|
||||
"historySize": 2,
|
||||
"closeOnExit": "never"
|
||||
}
|
||||
]
|
||||
})" };
|
||||
@@ -473,7 +477,8 @@ namespace TerminalAppLocalTests
|
||||
{
|
||||
"name" : "profile1",
|
||||
"guid": "{6239a42c-2222-49a3-80bd-e8fdd045185c}",
|
||||
"historySize": 2
|
||||
"historySize": 2,
|
||||
"closeOnExit": "never"
|
||||
}
|
||||
]
|
||||
})" };
|
||||
@@ -572,25 +577,29 @@ namespace TerminalAppLocalTests
|
||||
"name" : "profile0",
|
||||
"guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}",
|
||||
"tabTitle" : "Profile 0",
|
||||
"historySize": 1
|
||||
"historySize": 1,
|
||||
"closeOnExit": "never"
|
||||
},
|
||||
{
|
||||
"name" : "profile1",
|
||||
"guid": "{6239a42c-2222-49a3-80bd-e8fdd045185c}",
|
||||
"tabTitle" : "Profile 1",
|
||||
"historySize": 2
|
||||
"historySize": 2,
|
||||
"closeOnExit": "never"
|
||||
},
|
||||
{
|
||||
"name" : "profile2",
|
||||
"guid": "{6239a42c-3333-49a3-80bd-e8fdd045185c}",
|
||||
"tabTitle" : "Profile 2",
|
||||
"historySize": 3
|
||||
"historySize": 3,
|
||||
"closeOnExit": "never"
|
||||
},
|
||||
{
|
||||
"name" : "profile3",
|
||||
"guid": "{6239a42c-4444-49a3-80bd-e8fdd045185c}",
|
||||
"tabTitle" : "Profile 3",
|
||||
"historySize": 4
|
||||
"historySize": 4,
|
||||
"closeOnExit": "never"
|
||||
}
|
||||
],
|
||||
"schemes":
|
||||
@@ -693,7 +702,6 @@ namespace TerminalAppLocalTests
|
||||
{
|
||||
BEGIN_TEST_METHOD_PROPERTIES()
|
||||
TEST_METHOD_PROPERTY(L"IsolationLevel", L"Method")
|
||||
TEST_METHOD_PROPERTY(L"Ignore", L"True") // GH#19610 tracks re-enabling this test
|
||||
END_TEST_METHOD_PROPERTIES()
|
||||
|
||||
auto page = _commonSetup();
|
||||
@@ -733,10 +741,6 @@ namespace TerminalAppLocalTests
|
||||
|
||||
void TabTests::MoveFocusFromZoomedPane()
|
||||
{
|
||||
BEGIN_TEST_METHOD_PROPERTIES()
|
||||
TEST_METHOD_PROPERTY(L"Ignore", L"True") // GH#19610 tracks re-enabling this test
|
||||
END_TEST_METHOD_PROPERTIES()
|
||||
|
||||
auto page = _commonSetup();
|
||||
|
||||
Log::Comment(L"Create a second pane");
|
||||
@@ -782,10 +786,6 @@ namespace TerminalAppLocalTests
|
||||
|
||||
void TabTests::CloseZoomedPane()
|
||||
{
|
||||
BEGIN_TEST_METHOD_PROPERTIES()
|
||||
TEST_METHOD_PROPERTY(L"Ignore", L"True") // GH#19610 tracks re-enabling this test
|
||||
END_TEST_METHOD_PROPERTIES()
|
||||
|
||||
auto page = _commonSetup();
|
||||
|
||||
Log::Comment(L"Create a second pane");
|
||||
@@ -841,10 +841,6 @@ namespace TerminalAppLocalTests
|
||||
|
||||
void TabTests::SwapPanes()
|
||||
{
|
||||
BEGIN_TEST_METHOD_PROPERTIES()
|
||||
TEST_METHOD_PROPERTY(L"Ignore", L"True") // GH#19610 tracks re-enabling this test
|
||||
END_TEST_METHOD_PROPERTIES()
|
||||
|
||||
auto page = _commonSetup();
|
||||
|
||||
Log::Comment(L"Setup 4 panes.");
|
||||
@@ -1051,31 +1047,31 @@ namespace TerminalAppLocalTests
|
||||
|
||||
void TabTests::NextMRUTab()
|
||||
{
|
||||
BEGIN_TEST_METHOD_PROPERTIES()
|
||||
TEST_METHOD_PROPERTY(L"Ignore", L"True") // GH#19610 tracks re-enabling this test
|
||||
END_TEST_METHOD_PROPERTIES()
|
||||
|
||||
// This is a test for GH#8025 - we want to make sure that we can do both
|
||||
// in-order and MRU tab traversal, using the tab switcher and with the
|
||||
// tab switcher disabled.
|
||||
// This is a test for GH#8025 - we want to make sure that MRU tab
|
||||
// ordering works correctly and that in-order/disabled switching works.
|
||||
//
|
||||
// Note: We test MRU ordering directly rather than going through the
|
||||
// command palette tab switcher, because the palette's anchor key
|
||||
// handling auto-dismisses when no modifier keys are held (which we
|
||||
// can't simulate in the test environment).
|
||||
|
||||
auto page = _commonSetup();
|
||||
|
||||
Log::Comment(L"Create a second tab");
|
||||
Log::Comment(L"Create Tab[1]");
|
||||
TestOnUIThread([&page]() {
|
||||
NewTerminalArgs newTerminalArgs{ 1 };
|
||||
page->_OpenNewTab(newTerminalArgs);
|
||||
});
|
||||
VERIFY_ARE_EQUAL(2u, page->_tabs.Size());
|
||||
|
||||
Log::Comment(L"Create a third tab");
|
||||
Log::Comment(L"Create Tab[2]");
|
||||
TestOnUIThread([&page]() {
|
||||
NewTerminalArgs newTerminalArgs{ 2 };
|
||||
page->_OpenNewTab(newTerminalArgs);
|
||||
});
|
||||
VERIFY_ARE_EQUAL(3u, page->_tabs.Size());
|
||||
|
||||
Log::Comment(L"Create a fourth tab");
|
||||
Log::Comment(L"Create Tab[3]");
|
||||
TestOnUIThread([&page]() {
|
||||
NewTerminalArgs newTerminalArgs{ 3 };
|
||||
page->_OpenNewTab(newTerminalArgs);
|
||||
@@ -1084,99 +1080,90 @@ namespace TerminalAppLocalTests
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
auto focusedIndex = page->_GetFocusedTabIndex().value_or(-1);
|
||||
VERIFY_ARE_EQUAL(3u, focusedIndex, L"Verify the fourth tab is the focused one");
|
||||
VERIFY_ARE_EQUAL(3u, focusedIndex, L"Verify Tab[3] is focused");
|
||||
});
|
||||
|
||||
Log::Comment(L"Select the second tab");
|
||||
Log::Comment(L"Select Tab[1]");
|
||||
TestOnUIThread([&page]() {
|
||||
page->_SelectTab(1);
|
||||
});
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
auto focusedIndex = page->_GetFocusedTabIndex().value_or(-1);
|
||||
VERIFY_ARE_EQUAL(1u, focusedIndex, L"Verify the second tab is the focused one");
|
||||
VERIFY_ARE_EQUAL(1u, focusedIndex, L"Verify Tab[1] is focused");
|
||||
});
|
||||
|
||||
Log::Comment(L"Change the tab switch order to MRU switching");
|
||||
// MRU order should now be: Tab[1], Tab[3], Tab[2], Tab[0]
|
||||
// Verify the MRU list directly.
|
||||
Log::Comment(L"Verify MRU order: MRU[0]=Tab[1], MRU[1]=Tab[3]");
|
||||
TestOnUIThread([&page]() {
|
||||
page->_settings.GlobalSettings().TabSwitcherMode(TabSwitcherMode::MostRecentlyUsed);
|
||||
page->_currentWindowSettings().TabSwitcherMode(TabSwitcherMode::MostRecentlyUsed);
|
||||
VERIFY_ARE_EQUAL(4u, page->_mruTabs.Size());
|
||||
uint32_t mruIdx;
|
||||
page->_tabs.IndexOf(page->_mruTabs.GetAt(0), mruIdx);
|
||||
VERIFY_ARE_EQUAL(1u, mruIdx, L"MRU[0] should be Tab[1] (most recent)");
|
||||
page->_tabs.IndexOf(page->_mruTabs.GetAt(1), mruIdx);
|
||||
VERIFY_ARE_EQUAL(3u, mruIdx, L"MRU[1] should be Tab[3] (last tab added)");
|
||||
});
|
||||
|
||||
Log::Comment(L"Switch to the next MRU tab, which is the fourth tab");
|
||||
Log::Comment(L"Select MRU[1]=Tab[3] directly");
|
||||
TestOnUIThread([&page]() {
|
||||
page->_SelectNextTab(true, nullptr);
|
||||
});
|
||||
|
||||
Log::Comment(L"Sleep to let events propagate");
|
||||
Sleep(250);
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
Log::Comment(L"Hide the command palette, to confirm the selection");
|
||||
// If you don't do this, the palette will just stay open, and the
|
||||
// next time we call _HandleNextTab, we'll continue traversing the
|
||||
// MRU list, instead of just hoping one entry.
|
||||
page->LoadCommandPalette().Visibility(Visibility::Collapsed);
|
||||
// The next MRU tab after Tab[1] is Tab[3]
|
||||
uint32_t nextMruIdx;
|
||||
page->_tabs.IndexOf(page->_mruTabs.GetAt(1), nextMruIdx);
|
||||
page->_SelectTab(nextMruIdx);
|
||||
});
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
auto focusedIndex = page->_GetFocusedTabIndex().value_or(-1);
|
||||
VERIFY_ARE_EQUAL(3u, focusedIndex, L"Verify the fourth tab is the focused one");
|
||||
VERIFY_ARE_EQUAL(3u, focusedIndex, L"Verify Tab[3] is focused");
|
||||
});
|
||||
|
||||
Log::Comment(L"Switch to the next MRU tab, which is the second tab");
|
||||
Log::Comment(L"Select MRU[1]=Tab[1] directly");
|
||||
TestOnUIThread([&page]() {
|
||||
page->_SelectNextTab(true, nullptr);
|
||||
});
|
||||
|
||||
Log::Comment(L"Sleep to let events propagate");
|
||||
Sleep(250);
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
Log::Comment(L"Hide the command palette, to confirm the selection");
|
||||
// If you don't do this, the palette will just stay open, and the
|
||||
// next time we call _HandleNextTab, we'll continue traversing the
|
||||
// MRU list, instead of just hoping one entry.
|
||||
page->LoadCommandPalette().Visibility(Visibility::Collapsed);
|
||||
uint32_t nextMruIdx;
|
||||
page->_tabs.IndexOf(page->_mruTabs.GetAt(1), nextMruIdx);
|
||||
page->_SelectTab(nextMruIdx);
|
||||
});
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
auto focusedIndex = page->_GetFocusedTabIndex().value_or(-1);
|
||||
VERIFY_ARE_EQUAL(1u, focusedIndex, L"Verify the second tab is the focused one");
|
||||
});
|
||||
|
||||
Log::Comment(L"Change the tab switch order to in-order switching");
|
||||
page->_settings.GlobalSettings().TabSwitcherMode(TabSwitcherMode::InOrder);
|
||||
|
||||
Log::Comment(L"Switch to the next in-order tab, which is the third tab");
|
||||
TestOnUIThread([&page]() {
|
||||
page->_SelectNextTab(true, nullptr);
|
||||
});
|
||||
TestOnUIThread([&page]() {
|
||||
auto focusedIndex = page->_GetFocusedTabIndex().value_or(-1);
|
||||
VERIFY_ARE_EQUAL(2u, focusedIndex, L"Verify the third tab is the focused one");
|
||||
VERIFY_ARE_EQUAL(1u, focusedIndex, L"Verify Tab[1] is focused");
|
||||
});
|
||||
|
||||
// The Disabled tab switcher mode uses direct index-based switching
|
||||
// without the command palette, so it works in the test environment.
|
||||
Log::Comment(L"Change the tab switch order to not use the tab switcher (which is in-order always)");
|
||||
page->_settings.GlobalSettings().TabSwitcherMode(TabSwitcherMode::Disabled);
|
||||
page->_currentWindowSettings().TabSwitcherMode(TabSwitcherMode::Disabled);
|
||||
|
||||
Log::Comment(L"Switch to the next in-order tab, which is the fourth tab");
|
||||
Log::Comment(L"Switch to the next in-order tab: Tab[2]");
|
||||
TestOnUIThread([&page]() {
|
||||
page->_SelectNextTab(true, nullptr);
|
||||
});
|
||||
TestOnUIThread([&page]() {
|
||||
auto focusedIndex = page->_GetFocusedTabIndex().value_or(-1);
|
||||
VERIFY_ARE_EQUAL(3u, focusedIndex, L"Verify the fourth tab is the focused one");
|
||||
VERIFY_ARE_EQUAL(2u, focusedIndex, L"Verify Tab[2] is focused");
|
||||
});
|
||||
|
||||
Log::Comment(L"Switch to the next in-order tab: Tab[3]");
|
||||
TestOnUIThread([&page]() {
|
||||
page->_SelectNextTab(true, nullptr);
|
||||
});
|
||||
TestOnUIThread([&page]() {
|
||||
auto focusedIndex = page->_GetFocusedTabIndex().value_or(-1);
|
||||
VERIFY_ARE_EQUAL(3u, focusedIndex, L"Verify Tab[3] is focused");
|
||||
});
|
||||
}
|
||||
|
||||
void TabTests::VerifyCommandPaletteTabSwitcherOrder()
|
||||
{
|
||||
BEGIN_TEST_METHOD_PROPERTIES()
|
||||
TEST_METHOD_PROPERTY(L"Ignore", L"True") // GH#19610 tracks re-enabling this test
|
||||
END_TEST_METHOD_PROPERTIES()
|
||||
|
||||
// This is a test for GH#8188 - we want to make sure that the order of tabs
|
||||
// is preserved in the CommandPalette's TabSwitcher
|
||||
// This is a test for GH#8188 - we want to make sure that the MRU
|
||||
// ordering is correctly maintained as tabs are selected.
|
||||
//
|
||||
// Note: We verify MRU ordering directly rather than going through
|
||||
// the command palette tab switcher, because the palette's anchor key
|
||||
// handling auto-dismisses when no modifier keys are held (which we
|
||||
// can't simulate in the test environment).
|
||||
|
||||
auto page = _commonSetup();
|
||||
|
||||
@@ -1189,7 +1176,7 @@ namespace TerminalAppLocalTests
|
||||
});
|
||||
VERIFY_ARE_EQUAL(4u, page->_mruTabs.Size());
|
||||
|
||||
Log::Comment(L"give alphabetical names to all switch tab actions");
|
||||
Log::Comment(L"give alphabetical names to all tabs");
|
||||
TestOnUIThread([&page]() {
|
||||
page->_GetTabImpl(page->_tabs.GetAt(0))->Title(L"a");
|
||||
});
|
||||
@@ -1211,6 +1198,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_ARE_EQUAL(L"c", page->_tabs.GetAt(2).Title());
|
||||
VERIFY_ARE_EQUAL(L"d", page->_tabs.GetAt(3).Title());
|
||||
|
||||
// MRU order after creating Tab[0]-Tab[3]: MRU[0]=Tab[3], MRU[3]=Tab[0]
|
||||
VERIFY_ARE_EQUAL(L"d", page->_mruTabs.GetAt(0).Title());
|
||||
VERIFY_ARE_EQUAL(L"c", page->_mruTabs.GetAt(1).Title());
|
||||
VERIFY_ARE_EQUAL(L"b", page->_mruTabs.GetAt(2).Title());
|
||||
@@ -1219,10 +1207,10 @@ namespace TerminalAppLocalTests
|
||||
|
||||
Log::Comment(L"Change the tab switch order to MRU switching");
|
||||
TestOnUIThread([&page]() {
|
||||
page->_settings.GlobalSettings().TabSwitcherMode(TabSwitcherMode::MostRecentlyUsed);
|
||||
page->_currentWindowSettings().TabSwitcherMode(TabSwitcherMode::MostRecentlyUsed);
|
||||
});
|
||||
|
||||
Log::Comment(L"Select the tabs from 0 to 3");
|
||||
Log::Comment(L"Select Tab[0] through Tab[3] to establish MRU order");
|
||||
RunOnUIThread([&page]() {
|
||||
page->_UpdatedSelectedTab(page->_tabs.GetAt(0));
|
||||
page->_UpdatedSelectedTab(page->_tabs.GetAt(1));
|
||||
@@ -1230,47 +1218,31 @@ namespace TerminalAppLocalTests
|
||||
page->_UpdatedSelectedTab(page->_tabs.GetAt(3));
|
||||
});
|
||||
|
||||
Log::Comment(L"Verify MRU order: MRU[0]='d', MRU[1]='c', MRU[2]='b', MRU[3]='a'");
|
||||
VERIFY_ARE_EQUAL(4u, page->_mruTabs.Size());
|
||||
VERIFY_ARE_EQUAL(L"d", page->_mruTabs.GetAt(0).Title());
|
||||
VERIFY_ARE_EQUAL(L"c", page->_mruTabs.GetAt(1).Title());
|
||||
VERIFY_ARE_EQUAL(L"b", page->_mruTabs.GetAt(2).Title());
|
||||
VERIFY_ARE_EQUAL(L"a", page->_mruTabs.GetAt(3).Title());
|
||||
|
||||
Log::Comment(L"Switch to the next MRU tab, which is the third tab");
|
||||
RunOnUIThread([&page]() {
|
||||
page->_SelectNextTab(true, nullptr);
|
||||
// In the course of a single tick, the Command Palette will:
|
||||
// * open
|
||||
// * select the proper tab from the mru's list
|
||||
// * raise an event for _filteredActionsView().SelectionChanged to
|
||||
// immediately preview the new tab
|
||||
// * raise a _SwitchToTabRequestedHandlers event
|
||||
// * then dismiss itself, because we can't fake holing down an
|
||||
// anchor key in the tests
|
||||
Log::Comment(L"Select Tab[2]='c' (MRU[1] after 'd')");
|
||||
TestOnUIThread([&page]() {
|
||||
page->_SelectTab(2);
|
||||
});
|
||||
|
||||
Log::Comment(L"Verify MRU order updated: MRU[0]='c', MRU[1]='d', MRU[2]='b', MRU[3]='a'");
|
||||
TestOnUIThread([&page]() {
|
||||
VERIFY_ARE_EQUAL(L"c", page->_mruTabs.GetAt(0).Title());
|
||||
VERIFY_ARE_EQUAL(L"d", page->_mruTabs.GetAt(1).Title());
|
||||
VERIFY_ARE_EQUAL(L"b", page->_mruTabs.GetAt(2).Title());
|
||||
VERIFY_ARE_EQUAL(L"a", page->_mruTabs.GetAt(3).Title());
|
||||
});
|
||||
|
||||
const auto palette = winrt::get_self<winrt::TerminalApp::implementation::CommandPalette>(page->LoadCommandPalette());
|
||||
|
||||
VERIFY_ARE_EQUAL(winrt::TerminalApp::implementation::CommandPaletteMode::TabSwitchMode, palette->_currentMode, L"Verify we are in the tab switcher mode");
|
||||
// At this point, the contents of the command palette's _mruTabs list is
|
||||
// still the _old_ ordering (d, c, b, a). The ordering is only updated
|
||||
// in TerminalPage::_SelectNextTab, but as we saw before, the palette
|
||||
// will also dismiss itself immediately when that's called. So we can't
|
||||
// really inspect the contents of the list in this test, unfortunately.
|
||||
}
|
||||
|
||||
void TabTests::TestWindowRenameSuccessful()
|
||||
{
|
||||
BEGIN_TEST_METHOD_PROPERTIES()
|
||||
TEST_METHOD_PROPERTY(L"IsolationLevel", L"Method")
|
||||
TEST_METHOD_PROPERTY(L"Ignore", L"True") // GH#19610 tracks re-enabling this test
|
||||
END_TEST_METHOD_PROPERTIES()
|
||||
|
||||
auto page = _commonSetup();
|
||||
@@ -1303,7 +1275,6 @@ namespace TerminalAppLocalTests
|
||||
{
|
||||
BEGIN_TEST_METHOD_PROPERTIES()
|
||||
TEST_METHOD_PROPERTY(L"IsolationLevel", L"Method")
|
||||
TEST_METHOD_PROPERTY(L"Ignore", L"True") // GH#19610 tracks re-enabling this test
|
||||
END_TEST_METHOD_PROPERTIES()
|
||||
|
||||
auto page = _commonSetup();
|
||||
@@ -1336,10 +1307,6 @@ namespace TerminalAppLocalTests
|
||||
|
||||
void TabTests::TestPreviewCommitScheme()
|
||||
{
|
||||
BEGIN_TEST_METHOD_PROPERTIES()
|
||||
TEST_METHOD_PROPERTY(L"Ignore", L"True") // GH#19610 tracks re-enabling this test
|
||||
END_TEST_METHOD_PROPERTIES()
|
||||
|
||||
Log::Comment(L"Preview a color scheme. Make sure it's applied, then committed accordingly");
|
||||
|
||||
auto page = _commonSetup();
|
||||
@@ -1402,10 +1369,6 @@ namespace TerminalAppLocalTests
|
||||
|
||||
void TabTests::TestPreviewDismissScheme()
|
||||
{
|
||||
BEGIN_TEST_METHOD_PROPERTIES()
|
||||
TEST_METHOD_PROPERTY(L"Ignore", L"True") // GH#19610 tracks re-enabling this test
|
||||
END_TEST_METHOD_PROPERTIES()
|
||||
|
||||
Log::Comment(L"Preview a color scheme. Make sure it's applied, then dismissed accordingly");
|
||||
|
||||
auto page = _commonSetup();
|
||||
@@ -1454,10 +1417,6 @@ namespace TerminalAppLocalTests
|
||||
|
||||
void TabTests::TestPreviewSchemeWhilePreviewing()
|
||||
{
|
||||
BEGIN_TEST_METHOD_PROPERTIES()
|
||||
TEST_METHOD_PROPERTY(L"Ignore", L"True") // GH#19610 tracks re-enabling this test
|
||||
END_TEST_METHOD_PROPERTIES()
|
||||
|
||||
Log::Comment(L"Preview a color scheme, then preview another scheme. ");
|
||||
|
||||
Log::Comment(L"Preview a color scheme. Make sure it's applied, then committed accordingly");
|
||||
@@ -1525,10 +1484,6 @@ namespace TerminalAppLocalTests
|
||||
|
||||
void TabTests::TestClampSwitchToTab()
|
||||
{
|
||||
BEGIN_TEST_METHOD_PROPERTIES()
|
||||
TEST_METHOD_PROPERTY(L"Ignore", L"True") // GH#19610 tracks re-enabling this test
|
||||
END_TEST_METHOD_PROPERTIES()
|
||||
|
||||
Log::Comment(L"Test that switching to a tab index higher than the number of tabs just clamps to the last tab.");
|
||||
|
||||
auto page = _commonSetup();
|
||||
|
||||
@@ -550,7 +550,7 @@ namespace winrt::TerminalApp::implementation
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<CopyTextArgs>())
|
||||
{
|
||||
const auto copyFormatting = realArgs.CopyFormatting();
|
||||
const auto format = copyFormatting ? copyFormatting.Value() : _settings.GlobalSettings().CopyFormatting();
|
||||
const auto format = copyFormatting ? copyFormatting.Value() : _currentWindowSettings().CopyFormatting();
|
||||
const auto handled = _CopyText(realArgs.DismissSelection(), realArgs.SingleLine(), realArgs.WithControlSequences(), format);
|
||||
args.Handled(handled);
|
||||
}
|
||||
@@ -961,7 +961,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
if (const auto& terminalArgs{ newContentArgs.try_as<NewTerminalArgs>() })
|
||||
{
|
||||
const auto profile{ _settings.GetProfileForArgs(terminalArgs) };
|
||||
const auto profile{ _settings.GetProfileForArgs(terminalArgs, _currentWindowSettings()) };
|
||||
terminalArgs.Profile(::Microsoft::Console::Utils::GuidToString(profile.Guid()));
|
||||
}
|
||||
|
||||
@@ -1118,7 +1118,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// use global default if query URL is unspecified
|
||||
if (queryUrl.empty())
|
||||
{
|
||||
queryUrl = std::wstring_view{ _settings.GlobalSettings().SearchWebDefaultQueryUrl() };
|
||||
queryUrl = std::wstring_view{ _currentWindowSettings().SearchWebDefaultQueryUrl() };
|
||||
}
|
||||
|
||||
constexpr std::wstring_view queryToken{ L"%s" };
|
||||
|
||||
@@ -194,7 +194,7 @@ namespace winrt::TerminalApp::implementation
|
||||
g_hTerminalAppProvider,
|
||||
"AppCreated",
|
||||
TraceLoggingDescription("Event emitted when the application is started"),
|
||||
TraceLoggingBool(_settings.GlobalSettings().ShowTabsInTitlebar(), "TabsInTitlebar"),
|
||||
TraceLoggingBool(_settings.WindowSettingsDefaults().ShowTabsInTitlebar(), "TabsInTitlebar"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
}
|
||||
@@ -229,12 +229,12 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
_hasSettingsStartupActions = false;
|
||||
const auto startupActions = newSettings.GlobalSettings().StartupActions();
|
||||
const auto startupActions = newSettings.WindowSettingsDefaults().StartupActions();
|
||||
if (!startupActions.empty())
|
||||
{
|
||||
_settingsAppArgs.FullResetState();
|
||||
|
||||
ExecuteCommandlineArgs args{ newSettings.GlobalSettings().StartupActions() };
|
||||
ExecuteCommandlineArgs args{ newSettings.WindowSettingsDefaults().StartupActions() };
|
||||
auto result = _settingsAppArgs.ParseArgs(args);
|
||||
if (result == 0)
|
||||
{
|
||||
|
||||
@@ -672,9 +672,15 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>Dieser Linktyp wird derzeit nicht unterstützt:</value>
|
||||
</data>
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>Abbrechen</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>Dieser Link kann zu einem unsicheren Speicherort führen. Links können ihren Computer und Ihre Daten beschädigen. Klicken Sie zum Schutz Des Computers nur auf Links aus vertrauenswürdigen Quellen.</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>Trotzdem öffnen</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>Einstellungen</value>
|
||||
</data>
|
||||
|
||||
@@ -669,9 +669,15 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>This link type is currently not supported:</value>
|
||||
</data>
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>This link may lead to an unsafe location. Hyperlinks can be harmful to your computer and data. To protect your computer, only click links from trusted sources.</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>Open anyway</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>Settings</value>
|
||||
</data>
|
||||
|
||||
@@ -669,9 +669,15 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>Este tipo de vínculo no se admite actualmente:</value>
|
||||
</data>
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>Cancelar</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>Este vínculo puede dar lugar a una ubicación no segura. Los hipervínculos pueden ser perjudiciales para el equipo y los datos. Para proteger el equipo, haga clic solo en vínculos de orígenes de confianza.</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>Abrir de todas formas</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>Configuración</value>
|
||||
</data>
|
||||
|
||||
@@ -669,9 +669,15 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>Ce type de lien n’est actuellement pas pris en charge :</value>
|
||||
</data>
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>Annuler</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>Ce lien peut entraîner un emplacement non sécurisé. Les liens hypertexte peuvent endommager votre ordinateur et vos données. Pour protéger votre ordinateur, cliquez uniquement sur des liens provenant de sources fiables.</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>Ouvrir quand même</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>Paramètres</value>
|
||||
</data>
|
||||
|
||||
@@ -669,9 +669,15 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>Questo tipo di collegamento non è al momento supportato:</value>
|
||||
</data>
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>Annulla</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>Questo collegamento potrebbe causare un percorso non sicuro. I collegamenti ipertestuali possono essere dannosi per il computer e i dati. Per proteggere il computer, fare clic solo su collegamenti da origini attendibili.</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>Apri comunque</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>Impostazioni</value>
|
||||
</data>
|
||||
|
||||
@@ -670,9 +670,15 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>このリンクの種類は現在サポートされていません:</value>
|
||||
</data>
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>キャンセル</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>このリンクは安全でない可能性があります。ハイパーリンクは、コンピューターやデータに問題を起こす可能性があります。コンピューターを保護するには、信頼できるソースからのリンクのみをクリックしてください。</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>開く</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>設定</value>
|
||||
</data>
|
||||
|
||||
@@ -669,9 +669,15 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>이 링크 형식은 현재 지원되지 않습니다.</value>
|
||||
</data>
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>취소</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>이 링크로 인해 안전하지 않은 위치가 발생할 수 있습니다. 하이퍼링크는 컴퓨터와 데이터를 손상시킬 수 있습니다. 컴퓨터를 보호하려면 신뢰할 수 있는 원본의 링크만 클릭하세요.</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>열기</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>설정</value>
|
||||
</data>
|
||||
|
||||
@@ -669,9 +669,15 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>Não há suporte para este tipo de link no momento:</value>
|
||||
</data>
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>Cancelar</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>Este link pode levar a um local não seguro. Hiperlinks podem ser prejudiciais ao computador e aos dados. Para proteger o computador, clique somente em links de fontes confiáveis.</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>Abrir mesmo assim</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>Configurações</value>
|
||||
</data>
|
||||
|
||||
@@ -669,8 +669,14 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>Ťђïś łϊηќ ŧурē ιş çũґѓзⁿτľÿ ñστ şΰρρоŕŧĕđ: !!! !!! !!! !!! </value>
|
||||
</data>
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>Сąñс℮ł !</value>
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>Çдπсёľ !</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>Ŧђīś ℓîŋќ мαў ľêãδ τб áń úʼnšàƒé ℓоćάŧίоñ. Ĥўрзŗℓĭŋķѕ çâⁿ ъέ ђąřмƒúļ τό ўôця ċómφύŧèґ аňδ ðáťǻ. Ţб ρгøťėçŧ ўòύг ςömφùţĕŕ, ŏŋľỳ čℓΐςķ łίŋκѕ ƒřöм ťŗμѕŧєđ śόυяčêś. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>Őρέй ǻпŷŵãγ !!!</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>Śëţťĩпğś !!</value>
|
||||
|
||||
@@ -669,8 +669,14 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>Ťђïś łϊηќ ŧурē ιş çũґѓзⁿτľÿ ñστ şΰρρоŕŧĕđ: !!! !!! !!! !!! </value>
|
||||
</data>
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>Сąñс℮ł !</value>
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>Çдπсёľ !</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>Ŧђīś ℓîŋќ мαў ľêãδ τб áń úʼnšàƒé ℓоćάŧίоñ. Ĥўрзŗℓĭŋķѕ çâⁿ ъέ ђąřмƒúļ τό ўôця ċómφύŧèґ аňδ ðáťǻ. Ţб ρгøťėçŧ ўòύг ςömφùţĕŕ, ŏŋľỳ čℓΐςķ łίŋκѕ ƒřöм ťŗμѕŧєđ śόυяčêś. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>Őρέй ǻпŷŵãγ !!!</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>Śëţťĩпğś !!</value>
|
||||
|
||||
@@ -669,8 +669,14 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>Ťђïś łϊηќ ŧурē ιş çũґѓзⁿτľÿ ñστ şΰρρоŕŧĕđ: !!! !!! !!! !!! </value>
|
||||
</data>
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>Сąñс℮ł !</value>
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>Çдπсёľ !</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>Ŧђīś ℓîŋќ мαў ľêãδ τб áń úʼnšàƒé ℓоćάŧίоñ. Ĥўрзŗℓĭŋķѕ çâⁿ ъέ ђąřмƒúļ τό ўôця ċómφύŧèґ аňδ ðáťǻ. Ţб ρгøťėçŧ ўòύг ςömφùţĕŕ, ŏŋľỳ čℓΐςķ łίŋκѕ ƒřöм ťŗμѕŧєđ śόυяčêś. !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>Őρέй ǻпŷŵãγ !!!</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>Śëţťĩпğś !!</value>
|
||||
|
||||
@@ -669,9 +669,15 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>Этот тип связи в настоящее время не поддерживается:</value>
|
||||
</data>
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>Отмена</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>Эта ссылка может привести к небезопасному расположению. Гиперссылки могут нанести вред компьютеру и данным. Чтобы защитить компьютер, щелкните ссылки только из надежных источников.</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>Все равно открыть</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>Параметры</value>
|
||||
</data>
|
||||
|
||||
@@ -669,9 +669,15 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>当前不支持此链接类型:</value>
|
||||
</data>
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>取消</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>此链接可能会导致不安全的位置。超链接可能对你的计算机和数据有害。若要保护你的计算机,请仅单击来自受信任源的链接。</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>仍然打开</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>设置</value>
|
||||
</data>
|
||||
|
||||
@@ -669,9 +669,15 @@
|
||||
<data name="UnsupportedSchemeText" xml:space="preserve">
|
||||
<value>目前不支援此連結類型:</value>
|
||||
</data>
|
||||
<data name="CouldNotOpenUriDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<data name="UriErrorDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>取消</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmText" xml:space="preserve">
|
||||
<value>此連結可能通往不安全地點。超連結可能對你的電腦和資料造成傷害。為了保護你的電腦,只點擊來自可信來源的連結。</value>
|
||||
</data>
|
||||
<data name="UnsafeUrlConfirmAllowAction" xml:space="preserve">
|
||||
<value>一律開啟</value>
|
||||
</data>
|
||||
<data name="SettingsTab" xml:space="preserve">
|
||||
<value>設定</value>
|
||||
</data>
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
// Stash away the current requested theme of the app. We'll need that in
|
||||
// _BackgroundBrush() to do a theme-aware resource lookup
|
||||
_requestedTheme = settings.GlobalSettings().CurrentTheme().RequestedTheme();
|
||||
_requestedTheme = settings.GlobalSettings().CurrentTheme(settings.WindowSettingsDefaults()).RequestedTheme();
|
||||
}
|
||||
|
||||
void SettingsPaneContent::UpdateSettings(const CascadiaSettings& settings)
|
||||
@@ -27,7 +27,7 @@ namespace winrt::TerminalApp::implementation
|
||||
ASSERT_UI_THREAD();
|
||||
_sui.UpdateSettings(settings);
|
||||
|
||||
_requestedTheme = settings.GlobalSettings().CurrentTheme().RequestedTheme();
|
||||
_requestedTheme = settings.GlobalSettings().CurrentTheme(settings.WindowSettingsDefaults()).RequestedTheme();
|
||||
}
|
||||
|
||||
winrt::Windows::UI::Xaml::FrameworkElement SettingsPaneContent::GetRoot()
|
||||
|
||||
@@ -121,7 +121,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
static const auto key = winrt::box_value(L"SettingsUiTabBrush");
|
||||
return ThemeLookup(WUX::Application::Current().Resources(),
|
||||
_settings.GlobalSettings().CurrentTheme().RequestedTheme(),
|
||||
_settings.GlobalSettings().CurrentTheme(_settings.WindowSettingsDefaults()).RequestedTheme(),
|
||||
key)
|
||||
.try_as<winrt::WUX::Media::Brush>();
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// Make sure to try/catch this, because the LocalTests won't be
|
||||
// able to use this helper.
|
||||
const auto settings{ winrt::TerminalApp::implementation::AppLogic::CurrentAppSettings() };
|
||||
if (settings.GlobalSettings().TabWidthMode() == winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode::SizeToContent)
|
||||
if (settings.WindowSettingsDefaults().TabWidthMode() == winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode::SizeToContent)
|
||||
{
|
||||
_headerControl.RenamerMaxWidth(HeaderRenameBoxWidthTitleLength);
|
||||
}
|
||||
|
||||
@@ -66,14 +66,14 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
if (const auto& newTerminalArgs{ newContentArgs.try_as<NewTerminalArgs>() })
|
||||
{
|
||||
const auto profile{ _settings.GetProfileForArgs(newTerminalArgs) };
|
||||
const auto profile{ _settings.GetProfileForArgs(newTerminalArgs, _currentWindowSettings()) };
|
||||
// GH#11114: GetProfileForArgs can return null if the index is higher
|
||||
// than the number of available profiles.
|
||||
if (!profile)
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
const auto settings{ Settings::TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs) };
|
||||
const auto settings{ Settings::TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs, _currentWindowSettings()) };
|
||||
|
||||
// Try to handle auto-elevation
|
||||
if (_maybeElevate(newTerminalArgs, settings, profile))
|
||||
@@ -105,7 +105,7 @@ namespace winrt::TerminalApp::implementation
|
||||
if (insertPosition == -1)
|
||||
{
|
||||
insertPosition = _tabs.Size();
|
||||
if (_settings.GlobalSettings().NewTabPosition() == NewTabPosition::AfterCurrentTab)
|
||||
if (_currentWindowSettings().NewTabPosition() == NewTabPosition::AfterCurrentTab)
|
||||
{
|
||||
auto currentTabIndex = _GetFocusedTabIndex();
|
||||
if (currentTabIndex.has_value())
|
||||
@@ -220,7 +220,7 @@ namespace winrt::TerminalApp::implementation
|
||||
if (const auto content{ tab.GetActiveContent() })
|
||||
{
|
||||
const auto& icon{ content.Icon() };
|
||||
const auto theme = _settings.GlobalSettings().CurrentTheme();
|
||||
const auto theme = _settings.GlobalSettings().CurrentTheme(_currentWindowSettings());
|
||||
const auto iconStyle = (theme && theme.Tab()) ? theme.Tab().IconStyle() : IconStyle::Default;
|
||||
|
||||
tab.UpdateIcon(icon, iconStyle);
|
||||
@@ -231,7 +231,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - Handle changes to the tab width set by the user
|
||||
void TerminalPage::_UpdateTabWidthMode()
|
||||
{
|
||||
_tabView.TabWidthMode(_settings.GlobalSettings().TabWidthMode());
|
||||
_tabView.TabWidthMode(_currentWindowSettings().TabWidthMode());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -244,9 +244,9 @@ namespace winrt::TerminalApp::implementation
|
||||
// - there is more than one tab, or the user has chosen to always show tabs
|
||||
const auto isVisible = !_isInFocusMode &&
|
||||
(!_isFullscreen || _showTabsFullscreen) &&
|
||||
(_settings.GlobalSettings().ShowTabsInTitlebar() ||
|
||||
(_currentWindowSettings().ShowTabsInTitlebar() ||
|
||||
(_tabs.Size() > 1) ||
|
||||
_settings.GlobalSettings().AlwaysShowTabs());
|
||||
_currentWindowSettings().AlwaysShowTabs());
|
||||
|
||||
if (_tabView)
|
||||
{
|
||||
@@ -286,7 +286,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// current control's live settings (which will include changes
|
||||
// made through VT).
|
||||
uint32_t insertPosition = _tabs.Size();
|
||||
if (_settings.GlobalSettings().NewTabPosition() == NewTabPosition::AfterCurrentTab)
|
||||
if (_currentWindowSettings().NewTabPosition() == NewTabPosition::AfterCurrentTab)
|
||||
{
|
||||
insertPosition = tab.TabViewIndex() + 1;
|
||||
}
|
||||
@@ -477,7 +477,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// 1. We want to customize this behavior (e.g., use MRU logic)
|
||||
// 2. In fullscreen (GH#5799) and focus (GH#7916) modes the _OnTabItemsChanged is not fired
|
||||
// 3. When rearranging tabs (GH#7916) _OnTabItemsChanged is suppressed
|
||||
const auto tabSwitchMode = _settings.GlobalSettings().TabSwitcherMode();
|
||||
const auto tabSwitchMode = _currentWindowSettings().TabSwitcherMode();
|
||||
|
||||
if (tabSwitchMode == TabSwitcherMode::MostRecentlyUsed)
|
||||
{
|
||||
@@ -528,7 +528,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void TerminalPage::_SelectNextTab(const bool bMoveRight, const Windows::Foundation::IReference<Microsoft::Terminal::Settings::Model::TabSwitcherMode>& customTabSwitcherMode)
|
||||
{
|
||||
const auto index{ _GetFocusedTabIndex().value_or(0) };
|
||||
const auto tabSwitchMode = customTabSwitcherMode ? customTabSwitcherMode.Value() : _settings.GlobalSettings().TabSwitcherMode();
|
||||
const auto tabSwitchMode = customTabSwitcherMode ? customTabSwitcherMode.Value() : _currentWindowSettings().TabSwitcherMode();
|
||||
if (tabSwitchMode == TabSwitcherMode::Disabled)
|
||||
{
|
||||
auto tabCount = _tabs.Size();
|
||||
@@ -1017,7 +1017,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void TerminalPage::_UpdateBackground(const winrt::Microsoft::Terminal::Settings::Model::Profile& profile)
|
||||
{
|
||||
if (profile && _settings.GlobalSettings().UseBackgroundImageForWindow())
|
||||
if (profile && _currentWindowSettings().UseBackgroundImageForWindow())
|
||||
{
|
||||
_SetBackgroundImage(profile.DefaultAppearance());
|
||||
}
|
||||
|
||||
@@ -226,6 +226,11 @@ namespace winrt::TerminalApp::implementation
|
||||
_WindowProperties.PropertyChanged({ get_weak(), &TerminalPage::_windowPropertyChanged });
|
||||
}
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::WindowSettings TerminalPage::_currentWindowSettings() const
|
||||
{
|
||||
return _settings.WindowSettings(_WindowProperties.WindowName());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - implements the IInitializeWithWindow interface from shobjidl_core.
|
||||
// - We're going to use this HWND as the owner for the ConPTY windows, via
|
||||
@@ -268,12 +273,19 @@ namespace winrt::TerminalApp::implementation
|
||||
void TerminalPage::SetSettings(CascadiaSettings settings, bool needRefreshUI)
|
||||
{
|
||||
assert(Dispatcher().HasThreadAccess());
|
||||
if (_settings == nullptr)
|
||||
|
||||
// IMPORTANT: we must assign _settings FIRST, because many downstream
|
||||
// helpers (e.g. _currentWindowSettings()) dereference it. On the very
|
||||
// first call _settings is nullptr, so any access before this line would
|
||||
// crash.
|
||||
const auto firstLoad = _settings == nullptr;
|
||||
_settings = settings;
|
||||
|
||||
if (firstLoad)
|
||||
{
|
||||
// Create this only on the first time we load the settings.
|
||||
_terminalSettingsCache = std::make_shared<TerminalSettingsCache>(settings);
|
||||
_terminalSettingsCache = std::make_shared<TerminalSettingsCache>(settings, _currentWindowSettings());
|
||||
}
|
||||
_settings = settings;
|
||||
|
||||
// Make sure to call SetCommands before _RefreshUIForSettingsReload.
|
||||
// SetCommands will make sure the KeyChordText of Commands is updated, which needs
|
||||
@@ -335,7 +347,7 @@ namespace winrt::TerminalApp::implementation
|
||||
auto tabRowImpl = winrt::get_self<implementation::TabRowControl>(_tabRow);
|
||||
_newTabButton = tabRowImpl->NewTabButton();
|
||||
|
||||
if (_settings.GlobalSettings().ShowTabsInTitlebar())
|
||||
if (_currentWindowSettings().ShowTabsInTitlebar())
|
||||
{
|
||||
// Remove the TabView from the page. We'll hang on to it, we need to
|
||||
// put it in the titlebar.
|
||||
@@ -370,7 +382,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
// Initialize the state of the CloseButtonOverlayMode property of
|
||||
// our TabView, to match the tab.showCloseButton property in the theme.
|
||||
if (const auto theme = _settings.GlobalSettings().CurrentTheme())
|
||||
if (const auto theme = _settings.GlobalSettings().CurrentTheme(_currentWindowSettings()))
|
||||
{
|
||||
const auto visibility = theme.Tab() ? theme.Tab().ShowCloseButton() : Settings::Model::TabCloseButtonVisibility::Always;
|
||||
|
||||
@@ -425,7 +437,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// Settings AllowDependentAnimations will affect whether animations are
|
||||
// enabled application-wide, so we don't need to check it each time we
|
||||
// want to create an animation.
|
||||
WUX::Media::Animation::Timeline::AllowDependentAnimations(!_settings.GlobalSettings().DisableAnimations());
|
||||
WUX::Media::Animation::Timeline::AllowDependentAnimations(!_currentWindowSettings().DisableAnimations());
|
||||
|
||||
// Once the page is actually laid out on the screen, trigger all our
|
||||
// startup actions. Things like Panes need to know at least how big the
|
||||
@@ -434,14 +446,14 @@ namespace winrt::TerminalApp::implementation
|
||||
// _OnFirstLayout will remove this handler so it doesn't get called more than once.
|
||||
_layoutUpdatedRevoker = _tabContent.LayoutUpdated(winrt::auto_revoke, { this, &TerminalPage::_OnFirstLayout });
|
||||
|
||||
_isAlwaysOnTop = _settings.GlobalSettings().AlwaysOnTop();
|
||||
_showTabsFullscreen = _settings.GlobalSettings().ShowTabsFullscreen();
|
||||
_isAlwaysOnTop = _currentWindowSettings().AlwaysOnTop();
|
||||
_showTabsFullscreen = _currentWindowSettings().ShowTabsFullscreen();
|
||||
|
||||
// DON'T set up Toasts/TeachingTips here. They should be loaded and
|
||||
// initialized the first time they're opened, in whatever method opens
|
||||
// them.
|
||||
|
||||
_tabRow.ShowElevationShield(IsRunningElevated() && _settings.GlobalSettings().ShowAdminShield());
|
||||
_tabRow.ShowElevationShield(IsRunningElevated() && _currentWindowSettings().ShowAdminShield());
|
||||
|
||||
_adjustProcessPriorityThrottled = std::make_shared<ThrottledFunc<>>(
|
||||
DispatcherQueue::GetForCurrentThread(),
|
||||
@@ -520,7 +532,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
// It's possible that newTerminalArgs is null here.
|
||||
// GetProfileForArgs should be resilient to that.
|
||||
const auto profile{ settings.GetProfileForArgs(newTerminalArgs) };
|
||||
const auto profile{ settings.GetProfileForArgs(newTerminalArgs, settings.WindowSettingsDefaults()) };
|
||||
if (profile.Elevate())
|
||||
{
|
||||
continue;
|
||||
@@ -951,7 +963,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// Create profile entries from the NewTabMenu configuration using a
|
||||
// recursive helper function. This returns a std::vector of FlyoutItemBases,
|
||||
// that we then add to our Flyout.
|
||||
auto entries = _settings.GlobalSettings().NewTabMenu();
|
||||
auto entries = _currentWindowSettings().NewTabMenu();
|
||||
auto items = _CreateNewTabFlyoutItems(entries);
|
||||
for (const auto& item : items)
|
||||
{
|
||||
@@ -1233,7 +1245,7 @@ namespace winrt::TerminalApp::implementation
|
||||
profileMenuItem.Icon(icon);
|
||||
}
|
||||
|
||||
if (profile.Guid() == _settings.GlobalSettings().DefaultProfile())
|
||||
if (profile.Guid() == _currentWindowSettings().DefaultProfile())
|
||||
{
|
||||
// Contrast the default profile with others in font weight.
|
||||
profileMenuItem.FontWeight(FontWeights::Bold());
|
||||
@@ -1399,7 +1411,7 @@ namespace winrt::TerminalApp::implementation
|
||||
if (newTerminalArgs.ProfileIndex() != nullptr)
|
||||
{
|
||||
// We want to promote the index to a GUID because there is no "launch to profile index" command.
|
||||
const auto profile = _settings.GetProfileForArgs(newTerminalArgs);
|
||||
const auto profile = _settings.GetProfileForArgs(newTerminalArgs, _currentWindowSettings());
|
||||
if (profile)
|
||||
{
|
||||
newTerminalArgs.Profile(::Microsoft::Console::Utils::GuidToString(profile.Guid()));
|
||||
@@ -1470,7 +1482,7 @@ namespace winrt::TerminalApp::implementation
|
||||
const bool inheritCursor)
|
||||
{
|
||||
static const auto textMeasurement = [&]() -> std::wstring_view {
|
||||
switch (_settings.GlobalSettings().TextMeasurement())
|
||||
switch (_currentWindowSettings().TextMeasurement())
|
||||
{
|
||||
case TextMeasurement::Graphemes:
|
||||
return L"graphemes";
|
||||
@@ -1596,7 +1608,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
// TODO GH#5047 If we cache the NewTerminalArgs, we no longer need to do this.
|
||||
profile = GetClosestProfileForDuplicationOfProfile(profile);
|
||||
controlSettings = Settings::TerminalSettings::CreateWithProfile(_settings, profile);
|
||||
controlSettings = Settings::TerminalSettings::CreateWithProfile(_settings, profile, _currentWindowSettings());
|
||||
|
||||
// Replace the Starting directory with the CWD, if given
|
||||
const auto workingDirectory = control.WorkingDirectory();
|
||||
@@ -2312,7 +2324,7 @@ namespace winrt::TerminalApp::implementation
|
||||
safe_void_coroutine TerminalPage::CloseWindow()
|
||||
{
|
||||
if (_HasMultipleTabs() &&
|
||||
_settings.GlobalSettings().ConfirmCloseAllTabs() &&
|
||||
_currentWindowSettings().ConfirmCloseAllTabs() &&
|
||||
!_displayingCloseDialog)
|
||||
{
|
||||
if (_newTabButton && _newTabButton.Flyout())
|
||||
@@ -2837,7 +2849,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - the title of the focused control if there is one, else "Terminal"
|
||||
hstring TerminalPage::Title()
|
||||
{
|
||||
if (_settings.GlobalSettings().ShowTitleInTitlebar())
|
||||
if (_currentWindowSettings().ShowTitleInTitlebar())
|
||||
{
|
||||
if (const auto tab{ _GetFocusedTab() })
|
||||
{
|
||||
@@ -2926,7 +2938,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - See Pane::CalcSnappedDimension
|
||||
float TerminalPage::CalcSnappedDimension(const bool widthOrHeight, const float dimension) const
|
||||
{
|
||||
if (_settings && _settings.GlobalSettings().SnapToGridOnResize())
|
||||
if (_settings && _currentWindowSettings().SnapToGridOnResize())
|
||||
{
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
@@ -2954,7 +2966,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// the WinRT one on average, depending on CPU load. Don't use the WinRT clipboard API if you can.
|
||||
const auto weakThis = get_weak();
|
||||
const auto dispatcher = Dispatcher();
|
||||
const auto globalSettings = _settings.GlobalSettings();
|
||||
const auto windowSettings = _currentWindowSettings();
|
||||
const auto bracketedPaste = eventArgs.BracketedPasteEnabled();
|
||||
const auto sourceId = sender.try_as<ControlInteractivity>().Id();
|
||||
|
||||
@@ -2967,7 +2979,7 @@ namespace winrt::TerminalApp::implementation
|
||||
text = clipboard::read();
|
||||
}
|
||||
|
||||
if (!bracketedPaste && globalSettings.TrimPaste())
|
||||
if (!bracketedPaste && windowSettings.TrimPaste())
|
||||
{
|
||||
text = winrt::hstring{ Utils::TrimPaste(text) };
|
||||
}
|
||||
@@ -2982,7 +2994,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
bool warnMultiLine = false;
|
||||
switch (globalSettings.WarnAboutMultiLinePaste())
|
||||
switch (windowSettings.WarnAboutMultiLinePaste())
|
||||
{
|
||||
case WarnAboutMultiLinePaste::Automatic:
|
||||
// NOTE that this is unsafe, because a shell that doesn't support bracketed paste
|
||||
@@ -3005,7 +3017,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
constexpr std::size_t minimumSizeForWarning = 1024 * 5; // 5 KiB
|
||||
const auto warnLargeText = text.size() > minimumSizeForWarning && globalSettings.WarnAboutLargePaste();
|
||||
const auto warnLargeText = text.size() > minimumSizeForWarning && windowSettings.WarnAboutLargePaste();
|
||||
|
||||
if (warnMultiLine || warnLargeText)
|
||||
{
|
||||
@@ -3085,18 +3097,42 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
void TerminalPage::_OpenHyperlinkHandler(const IInspectable /*sender*/, const Microsoft::Terminal::Control::OpenHyperlinkEventArgs eventArgs)
|
||||
safe_void_coroutine TerminalPage::_OpenHyperlinkHandler(const IInspectable /*sender*/, const Microsoft::Terminal::Control::OpenHyperlinkEventArgs eventArgs)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto parsed = winrt::Windows::Foundation::Uri(eventArgs.Uri());
|
||||
auto uriString{ eventArgs.Uri() };
|
||||
auto parsed = winrt::Windows::Foundation::Uri(uriString);
|
||||
if (_IsUriSupported(parsed))
|
||||
{
|
||||
ShellExecute(nullptr, L"open", eventArgs.Uri().c_str(), nullptr, nullptr, SW_SHOWNORMAL);
|
||||
bool shouldLaunch{ _IsUriConsideredSomewhatSafe(parsed) };
|
||||
|
||||
if (!shouldLaunch)
|
||||
{
|
||||
if (auto presenter{ _dialogPresenter.get() })
|
||||
{
|
||||
// FindName needs to be called first to actually load the xaml object
|
||||
auto unopenedUriDialog = FindName(L"UriErrorDialog").try_as<WUX::Controls::ContentDialog>();
|
||||
|
||||
// Insert the reason and the URI
|
||||
unopenedUriDialog.SecondaryButtonText(RS_(L"UnsafeUrlConfirmAllowAction"));
|
||||
CouldNotOpenUriReason().Text(RS_(L"UnsafeUrlConfirmText"));
|
||||
UnopenedUri().Text(uriString);
|
||||
|
||||
// Show the dialog
|
||||
auto result = co_await presenter.ShowDialog(unopenedUriDialog);
|
||||
shouldLaunch = result == ContentDialogResult::Secondary;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldLaunch)
|
||||
{
|
||||
ShellExecuteW(nullptr, L"open", uriString.c_str(), nullptr, nullptr, SW_SHOWNORMAL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_ShowCouldNotOpenDialog(RS_(L"UnsupportedSchemeText"), eventArgs.Uri());
|
||||
_ShowCouldNotOpenDialog(RS_(L"UnsupportedSchemeText"), uriString);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
@@ -3116,9 +3152,10 @@ namespace winrt::TerminalApp::implementation
|
||||
if (auto presenter{ _dialogPresenter.get() })
|
||||
{
|
||||
// FindName needs to be called first to actually load the xaml object
|
||||
auto unopenedUriDialog = FindName(L"CouldNotOpenUriDialog").try_as<WUX::Controls::ContentDialog>();
|
||||
auto unopenedUriDialog = FindName(L"UriErrorDialog").try_as<WUX::Controls::ContentDialog>();
|
||||
|
||||
// Insert the reason and the URI
|
||||
unopenedUriDialog.SecondaryButtonText({});
|
||||
CouldNotOpenUriReason().Text(reason);
|
||||
UnopenedUri().Text(uri);
|
||||
|
||||
@@ -3171,6 +3208,30 @@ namespace winrt::TerminalApp::implementation
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TerminalPage::_IsUriConsideredSomewhatSafe(const winrt::Windows::Foundation::Uri& parsedUri)
|
||||
{
|
||||
if (parsedUri.SchemeName() == L"http" || parsedUri.SchemeName() == L"https")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (parsedUri.SchemeName() == L"file")
|
||||
{
|
||||
static const auto pathext{ wil::TryGetEnvironmentVariableW<std::wstring>(L"PATHEXT") };
|
||||
const auto filename = parsedUri.Path();
|
||||
for (const auto& e : til::split_iterator{ std::wstring_view{ pathext }, L';' })
|
||||
{
|
||||
if (til::ends_with_insensitive_ascii(filename, e))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Important! Don't take this eventArgs by reference, we need to extend the
|
||||
// lifetime of it to the other side of the co_await!
|
||||
safe_void_coroutine TerminalPage::_ControlNoticeRaisedHandler(const IInspectable /*sender*/,
|
||||
@@ -3350,13 +3411,13 @@ namespace winrt::TerminalApp::implementation
|
||||
void TerminalPage::_WindowSizeChanged(const IInspectable sender, const Microsoft::Terminal::Control::WindowSizeChangedEventArgs args)
|
||||
{
|
||||
// Raise if:
|
||||
// - Not in quake mode
|
||||
// - Not in docked mode
|
||||
// - Not in fullscreen
|
||||
// - Only one tab exists
|
||||
// - Only one pane exists
|
||||
// else:
|
||||
// - Reset conpty to its original size back
|
||||
if (!WindowProperties().IsQuakeWindow() && !Fullscreen() &&
|
||||
if (!_currentWindowSettings().DockWindow() && !Fullscreen() &&
|
||||
NumberOfTabs() == 1 && _GetFocusedTabImpl()->GetLeafPaneCount() == 1)
|
||||
{
|
||||
WindowSizeChanged.raise(*this, args);
|
||||
@@ -3540,7 +3601,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
// Don't need to worry about duplicating or anything - we'll
|
||||
// serialize the actual profile's GUID along with the content guid.
|
||||
const auto& profile = _settings.GetProfileForArgs(newTerminalArgs);
|
||||
const auto& profile = _settings.GetProfileForArgs(newTerminalArgs, _currentWindowSettings());
|
||||
const auto control = _AttachControlToContent(newTerminalArgs.ContentId());
|
||||
auto paneContent{ winrt::make<TerminalPaneContent>(profile, _terminalSettingsCache, control) };
|
||||
return std::make_shared<Pane>(paneContent);
|
||||
@@ -3556,7 +3617,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
// TODO GH#5047 If we cache the NewTerminalArgs, we no longer need to do this.
|
||||
profile = GetClosestProfileForDuplicationOfProfile(profile);
|
||||
controlSettings = Settings::TerminalSettings::CreateWithProfile(_settings, profile);
|
||||
controlSettings = Settings::TerminalSettings::CreateWithProfile(_settings, profile, _currentWindowSettings());
|
||||
const auto workingDirectory = tabImpl->GetActiveTerminalControl().WorkingDirectory();
|
||||
if (Utils::IsValidDirectory(workingDirectory.c_str()))
|
||||
{
|
||||
@@ -3566,8 +3627,8 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
if (!profile)
|
||||
{
|
||||
profile = _settings.GetProfileForArgs(newTerminalArgs);
|
||||
controlSettings = Settings::TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs);
|
||||
profile = _settings.GetProfileForArgs(newTerminalArgs, _currentWindowSettings());
|
||||
controlSettings = Settings::TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs, _currentWindowSettings());
|
||||
}
|
||||
|
||||
// Try to handle auto-elevation
|
||||
@@ -3764,7 +3825,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalPage::_SetBackgroundImage(const winrt::Microsoft::Terminal::Settings::Model::IAppearanceConfig& newAppearance)
|
||||
{
|
||||
if (!_settings.GlobalSettings().UseBackgroundImageForWindow())
|
||||
if (!_currentWindowSettings().UseBackgroundImageForWindow())
|
||||
{
|
||||
_tabContent.Background(nullptr);
|
||||
return;
|
||||
@@ -3835,7 +3896,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// updating terminal panes, so that we don't have to build a _new_
|
||||
// TerminalSettings for every profile we update - we can just look them
|
||||
// up the previous ones we built.
|
||||
_terminalSettingsCache->Reset(_settings);
|
||||
_terminalSettingsCache->Reset(_settings, _currentWindowSettings());
|
||||
|
||||
for (const auto& tab : _tabs)
|
||||
{
|
||||
@@ -3873,17 +3934,17 @@ namespace winrt::TerminalApp::implementation
|
||||
// Reload the current value of alwaysOnTop from the settings file. This
|
||||
// will let the user hot-reload this setting, but any runtime changes to
|
||||
// the alwaysOnTop setting will be lost.
|
||||
_isAlwaysOnTop = _settings.GlobalSettings().AlwaysOnTop();
|
||||
_isAlwaysOnTop = _currentWindowSettings().AlwaysOnTop();
|
||||
AlwaysOnTopChanged.raise(*this, nullptr);
|
||||
|
||||
_showTabsFullscreen = _settings.GlobalSettings().ShowTabsFullscreen();
|
||||
_showTabsFullscreen = _currentWindowSettings().ShowTabsFullscreen();
|
||||
|
||||
// Settings AllowDependentAnimations will affect whether animations are
|
||||
// enabled application-wide, so we don't need to check it each time we
|
||||
// want to create an animation.
|
||||
WUX::Media::Animation::Timeline::AllowDependentAnimations(!_settings.GlobalSettings().DisableAnimations());
|
||||
WUX::Media::Animation::Timeline::AllowDependentAnimations(!_currentWindowSettings().DisableAnimations());
|
||||
|
||||
_tabRow.ShowElevationShield(IsRunningElevated() && _settings.GlobalSettings().ShowAdminShield());
|
||||
_tabRow.ShowElevationShield(IsRunningElevated() && _currentWindowSettings().ShowAdminShield());
|
||||
|
||||
Media::SolidColorBrush transparent{ Windows::UI::Colors::Transparent() };
|
||||
_tabView.Background(transparent);
|
||||
@@ -3904,7 +3965,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// our TabView, to match the tab.showCloseButton property in the theme.
|
||||
//
|
||||
// Also update every tab's individual IsClosable to match the same property.
|
||||
const auto theme = _settings.GlobalSettings().CurrentTheme();
|
||||
const auto theme = _settings.GlobalSettings().CurrentTheme(_currentWindowSettings());
|
||||
const auto visibility = (theme && theme.Tab()) ?
|
||||
theme.Tab().ShowCloseButton() :
|
||||
Settings::Model::TabCloseButtonVisibility::Always;
|
||||
@@ -4518,7 +4579,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalPage::_UpdateTeachingTipTheme(winrt::Windows::UI::Xaml::FrameworkElement element)
|
||||
{
|
||||
auto theme{ _settings.GlobalSettings().CurrentTheme() };
|
||||
auto theme{ _settings.GlobalSettings().CurrentTheme(_currentWindowSettings()) };
|
||||
auto requestedTheme{ theme.RequestedTheme() };
|
||||
while (element)
|
||||
{
|
||||
@@ -4671,7 +4732,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
if (profile == _settings.ProfileDefaults())
|
||||
{
|
||||
return _settings.FindProfile(_settings.GlobalSettings().DefaultProfile());
|
||||
return _settings.FindProfile(_currentWindowSettings().DefaultProfile());
|
||||
}
|
||||
return profile;
|
||||
}
|
||||
@@ -4892,7 +4953,7 @@ namespace winrt::TerminalApp::implementation
|
||||
return;
|
||||
}
|
||||
|
||||
const auto theme = _settings.GlobalSettings().CurrentTheme();
|
||||
const auto theme = _settings.GlobalSettings().CurrentTheme(_currentWindowSettings());
|
||||
auto requestedTheme{ theme.RequestedTheme() };
|
||||
|
||||
{
|
||||
@@ -4936,7 +4997,7 @@ namespace winrt::TerminalApp::implementation
|
||||
theme.TabRow().UnfocusedBackground()) :
|
||||
ThemeColor{ nullptr } };
|
||||
|
||||
if (_settings.GlobalSettings().UseAcrylicInTabRow() && (_activated || _settings.GlobalSettings().EnableUnfocusedAcrylic()))
|
||||
if (_currentWindowSettings().UseAcrylicInTabRow() && (_activated || _currentWindowSettings().EnableUnfocusedAcrylic()))
|
||||
{
|
||||
if (tabRowBg)
|
||||
{
|
||||
@@ -4966,7 +5027,7 @@ namespace winrt::TerminalApp::implementation
|
||||
TitlebarBrush(backgroundSolidBrush);
|
||||
}
|
||||
|
||||
if (!_settings.GlobalSettings().ShowTabsInTitlebar())
|
||||
if (!_currentWindowSettings().ShowTabsInTitlebar())
|
||||
{
|
||||
_tabRow.Background(TitlebarBrush());
|
||||
}
|
||||
@@ -5202,7 +5263,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// Feature_ShellCompletions::IsEnabled back in _RegisterTerminalEvents
|
||||
|
||||
// User must explicitly opt-in on Preview builds
|
||||
if (!_settings.GlobalSettings().EnableShellCompletionMenu())
|
||||
if (!_currentWindowSettings().EnableShellCompletionMenu())
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
@@ -283,6 +283,8 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
TerminalApp::ContentManager _manager{ nullptr };
|
||||
|
||||
Microsoft::Terminal::Settings::Model::WindowSettings _currentWindowSettings() const;
|
||||
|
||||
std::shared_ptr<TerminalSettingsCache> _terminalSettingsCache{};
|
||||
|
||||
struct StashedDragData
|
||||
@@ -422,8 +424,9 @@ namespace winrt::TerminalApp::implementation
|
||||
safe_void_coroutine _PasteFromClipboardHandler(const IInspectable sender,
|
||||
const Microsoft::Terminal::Control::PasteFromClipboardEventArgs eventArgs);
|
||||
|
||||
void _OpenHyperlinkHandler(const IInspectable sender, const Microsoft::Terminal::Control::OpenHyperlinkEventArgs eventArgs);
|
||||
bool _IsUriSupported(const winrt::Windows::Foundation::Uri& parsedUri);
|
||||
safe_void_coroutine _OpenHyperlinkHandler(const IInspectable sender, const Microsoft::Terminal::Control::OpenHyperlinkEventArgs eventArgs);
|
||||
static bool _IsUriSupported(const winrt::Windows::Foundation::Uri& parsedUri);
|
||||
static bool _IsUriConsideredSomewhatSafe(const winrt::Windows::Foundation::Uri& parsedUri);
|
||||
|
||||
void _ShowCouldNotOpenDialog(winrt::hstring reason, winrt::hstring uri);
|
||||
bool _CopyText(bool dismissSelection, bool singleLine, bool withControlSequences, Microsoft::Terminal::Control::CopyFormat formats);
|
||||
|
||||
@@ -41,8 +41,6 @@ namespace TerminalApp
|
||||
|
||||
String VirtualWorkingDirectory { get; set; };
|
||||
String VirtualEnvVars { get; set; };
|
||||
|
||||
Boolean IsQuakeWindow();
|
||||
};
|
||||
|
||||
runtimeclass LaunchPositionRequest
|
||||
|
||||
@@ -144,17 +144,17 @@
|
||||
</TextBlock>
|
||||
</ContentDialog>
|
||||
|
||||
<ContentDialog x:Name="CouldNotOpenUriDialog"
|
||||
x:Uid="CouldNotOpenUriDialog"
|
||||
<ContentDialog x:Name="UriErrorDialog"
|
||||
x:Uid="UriErrorDialog"
|
||||
Grid.Row="2"
|
||||
x:Load="False"
|
||||
DefaultButton="Primary">
|
||||
DefaultButton="Close">
|
||||
<TextBlock IsTextSelectionEnabled="True"
|
||||
TextWrapping="WrapWholeWords">
|
||||
<TextBlock.ContextFlyout>
|
||||
<mtu:TextMenuFlyout />
|
||||
</TextBlock.ContextFlyout>
|
||||
<Run x:Name="CouldNotOpenUriReason" /> <LineBreak />
|
||||
<Run x:Name="CouldNotOpenUriReason" /> <LineBreak /> <LineBreak />
|
||||
<Run x:Name="UnopenedUri"
|
||||
FontFamily="Cascadia Mono" />
|
||||
</TextBlock>
|
||||
|
||||
@@ -18,9 +18,9 @@ namespace winrt::TerminalApp::implementation
|
||||
result.UnfocusedSettings().try_as(_unfocusedSettings);
|
||||
}
|
||||
|
||||
TerminalSettingsCache::TerminalSettingsCache(const MTSM::CascadiaSettings& settings)
|
||||
TerminalSettingsCache::TerminalSettingsCache(const MTSM::CascadiaSettings& settings, const MTSM::WindowSettings& windowSettings)
|
||||
{
|
||||
Reset(settings);
|
||||
Reset(settings, windowSettings);
|
||||
}
|
||||
|
||||
std::optional<TerminalSettingsPair> TerminalSettingsCache::TryLookup(const MTSM::Profile& profile)
|
||||
@@ -35,7 +35,7 @@ namespace winrt::TerminalApp::implementation
|
||||
auto& pair{ found->second };
|
||||
if (!pair.second)
|
||||
{
|
||||
pair.second = winrt::Microsoft::Terminal::Settings::TerminalSettings::CreateWithProfile(_settings, pair.first);
|
||||
pair.second = winrt::Microsoft::Terminal::Settings::TerminalSettings::CreateWithProfile(_settings, pair.first, _windowSettings);
|
||||
}
|
||||
return std::optional{ TerminalSettingsPair{ *pair.second } };
|
||||
}
|
||||
@@ -43,9 +43,10 @@ namespace winrt::TerminalApp::implementation
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void TerminalSettingsCache::Reset(const MTSM::CascadiaSettings& settings)
|
||||
void TerminalSettingsCache::Reset(const MTSM::CascadiaSettings& settings, const MTSM::WindowSettings& windowSettings)
|
||||
{
|
||||
_settings = settings;
|
||||
_windowSettings = windowSettings;
|
||||
|
||||
// Mapping by GUID isn't _excellent_ because the defaults profile doesn't have a stable GUID; however,
|
||||
// when we stabilize its guid this will become fully safe.
|
||||
|
||||
@@ -38,12 +38,13 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
struct TerminalSettingsCache
|
||||
{
|
||||
TerminalSettingsCache(const Microsoft::Terminal::Settings::Model::CascadiaSettings& settings);
|
||||
TerminalSettingsCache(const Microsoft::Terminal::Settings::Model::CascadiaSettings& settings, const Microsoft::Terminal::Settings::Model::WindowSettings& windowSettings);
|
||||
std::optional<TerminalSettingsPair> TryLookup(const Microsoft::Terminal::Settings::Model::Profile& profile);
|
||||
void Reset(const Microsoft::Terminal::Settings::Model::CascadiaSettings& settings);
|
||||
void Reset(const Microsoft::Terminal::Settings::Model::CascadiaSettings& settings, const Microsoft::Terminal::Settings::Model::WindowSettings& windowSettings);
|
||||
|
||||
private:
|
||||
Microsoft::Terminal::Settings::Model::CascadiaSettings _settings{ nullptr };
|
||||
Microsoft::Terminal::Settings::Model::WindowSettings _windowSettings{ nullptr };
|
||||
std::unordered_map<winrt::guid, std::pair<Microsoft::Terminal::Settings::Model::Profile, std::optional<winrt::Microsoft::Terminal::Settings::TerminalSettingsCreateResult>>> profileGuidSettingsMap;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -232,7 +232,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// that the window size is _first_ set up as something sensible, so
|
||||
// leaving fullscreen returns to a reasonable size.
|
||||
const auto launchMode = this->GetLaunchMode();
|
||||
if (_WindowProperties->IsQuakeWindow() || WI_IsFlagSet(launchMode, LaunchMode::FocusMode))
|
||||
if (WI_IsFlagSet(launchMode, LaunchMode::FocusMode))
|
||||
{
|
||||
_root->SetFocusMode(true);
|
||||
}
|
||||
@@ -244,7 +244,7 @@ namespace winrt::TerminalApp::implementation
|
||||
_root->Maximized(true);
|
||||
}
|
||||
|
||||
if (WI_IsFlagSet(launchMode, LaunchMode::FullscreenMode) && !_WindowProperties->IsQuakeWindow())
|
||||
if (WI_IsFlagSet(launchMode, LaunchMode::FullscreenMode))
|
||||
{
|
||||
_root->SetFullscreen(true);
|
||||
}
|
||||
@@ -267,22 +267,22 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
bool TerminalWindow::GetShowTabsInTitlebar()
|
||||
{
|
||||
return _settings.GlobalSettings().ShowTabsInTitlebar();
|
||||
return _currentWindowSettings().ShowTabsInTitlebar();
|
||||
}
|
||||
|
||||
bool TerminalWindow::GetInitialAlwaysOnTop()
|
||||
{
|
||||
return _settings.GlobalSettings().AlwaysOnTop();
|
||||
return _currentWindowSettings().AlwaysOnTop();
|
||||
}
|
||||
|
||||
bool TerminalWindow::GetInitialShowTabsFullscreen()
|
||||
{
|
||||
return _settings.GlobalSettings().ShowTabsFullscreen();
|
||||
return _currentWindowSettings().ShowTabsFullscreen();
|
||||
}
|
||||
|
||||
bool TerminalWindow::GetMinimizeToNotificationArea()
|
||||
{
|
||||
return _settings.GlobalSettings().MinimizeToNotificationArea();
|
||||
return _currentWindowSettings().MinimizeToNotificationArea();
|
||||
}
|
||||
|
||||
bool TerminalWindow::GetAlwaysShowNotificationIcon()
|
||||
@@ -292,12 +292,12 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
bool TerminalWindow::GetShowTitleInTitlebar()
|
||||
{
|
||||
return _settings.GlobalSettings().ShowTitleInTitlebar();
|
||||
return _currentWindowSettings().ShowTitleInTitlebar();
|
||||
}
|
||||
|
||||
Microsoft::Terminal::Settings::Model::Theme TerminalWindow::Theme()
|
||||
{
|
||||
return _settings.GlobalSettings().CurrentTheme();
|
||||
return _settings.GlobalSettings().CurrentTheme(_currentWindowSettings());
|
||||
}
|
||||
|
||||
// WinUI can't show 2 dialogs simultaneously. Yes, really. If you do, you get an exception.
|
||||
@@ -374,7 +374,7 @@ namespace winrt::TerminalApp::implementation
|
||||
auto themingLambda{ [weak](const Windows::Foundation::IInspectable& sender, const RoutedEventArgs&) {
|
||||
if (const auto strong = weak.get())
|
||||
{
|
||||
auto theme{ strong->_settings.GlobalSettings().CurrentTheme() };
|
||||
auto theme{ strong->_settings.GlobalSettings().CurrentTheme(strong->_currentWindowSettings()) };
|
||||
auto requestedTheme{ theme.RequestedTheme() };
|
||||
auto element{ sender.try_as<winrt::Windows::UI::Xaml::FrameworkElement>() };
|
||||
while (element)
|
||||
@@ -598,7 +598,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// --focusMode on the commandline here, and the mode in the settings.
|
||||
// Below, we'll also account for if focus mode was persisted into the
|
||||
// session for restoration.
|
||||
bool focusMode = _appArgs && _appArgs->ParsedArgs().GetLaunchMode().value_or(_settings.GlobalSettings().LaunchMode()) == LaunchMode::FocusMode;
|
||||
bool focusMode = _appArgs && _appArgs->ParsedArgs().GetLaunchMode().value_or(_currentWindowSettings().LaunchMode()) == LaunchMode::FocusMode;
|
||||
|
||||
const auto scale = static_cast<float>(dpi) / static_cast<float>(USER_DEFAULT_SCREEN_DPI);
|
||||
if (const auto layout = LoadPersistedLayout())
|
||||
@@ -621,7 +621,7 @@ namespace winrt::TerminalApp::implementation
|
||||
if ((_appArgs && _appArgs->ParsedArgs().GetSize().has_value()) || (proposedSize.Width == 0 && proposedSize.Height == 0))
|
||||
{
|
||||
// Use the default profile to determine how big of a window we need.
|
||||
const auto settings{ Settings::TerminalSettings::CreateWithNewTerminalArgs(_settings, nullptr) };
|
||||
const auto settings{ Settings::TerminalSettings::CreateWithNewTerminalArgs(_settings, nullptr, _currentWindowSettings()) };
|
||||
|
||||
const til::size emptySize{};
|
||||
const auto commandlineSize = _appArgs ? _appArgs->ParsedArgs().GetSize().value_or(emptySize) : til::size{};
|
||||
@@ -645,7 +645,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// GH#2061 - If the global setting "Always show tab bar" is
|
||||
// set or if "Show tabs in title bar" is set, then we'll need to add
|
||||
// the height of the tab bar here.
|
||||
if (_settings.GlobalSettings().ShowTabsInTitlebar() && !focusMode)
|
||||
if (_currentWindowSettings().ShowTabsInTitlebar() && !focusMode)
|
||||
{
|
||||
// In the past, we used to actually instantiate a TitlebarControl
|
||||
// and use Measure() to determine the DesiredSize of the control, to
|
||||
@@ -663,7 +663,7 @@ namespace winrt::TerminalApp::implementation
|
||||
static constexpr auto titlebarHeight = 40;
|
||||
proposedSize.Height += (titlebarHeight)*scale;
|
||||
}
|
||||
else if (_settings.GlobalSettings().AlwaysShowTabs() && !focusMode)
|
||||
else if (_currentWindowSettings().AlwaysShowTabs() && !focusMode)
|
||||
{
|
||||
// Same comment as above, but with a TabRowControl.
|
||||
//
|
||||
@@ -696,7 +696,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
// GH#4620/#5801 - If the user passed --maximized or --fullscreen on the
|
||||
// commandline, then use that to override the value from the settings.
|
||||
const auto valueFromSettings = _settings.GlobalSettings().LaunchMode();
|
||||
const auto valueFromSettings = _currentWindowSettings().LaunchMode();
|
||||
const auto valueFromCommandlineArgs = _appArgs ? _appArgs->ParsedArgs().GetLaunchMode() : std::nullopt;
|
||||
if (const auto layout = LoadPersistedLayout())
|
||||
{
|
||||
@@ -722,7 +722,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - a point containing the requested initial position in pixels.
|
||||
TerminalApp::InitialPosition TerminalWindow::GetInitialPosition(int64_t defaultInitialX, int64_t defaultInitialY)
|
||||
{
|
||||
auto initialPosition{ _settings.GlobalSettings().InitialPosition() };
|
||||
auto initialPosition{ _currentWindowSettings().InitialPosition() };
|
||||
|
||||
if (const auto layout = LoadPersistedLayout())
|
||||
{
|
||||
@@ -770,10 +770,15 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
return !_contentBounds &&
|
||||
!hadPersistedPosition &&
|
||||
_settings.GlobalSettings().CenterOnLaunch() &&
|
||||
_currentWindowSettings().CenterOnLaunch() &&
|
||||
(_appArgs && !_appArgs->ParsedArgs().GetPosition().has_value());
|
||||
}
|
||||
|
||||
Microsoft::Terminal::Settings::Model::Docking TerminalWindow::Docking()
|
||||
{
|
||||
return _currentWindowSettings().DockWindow();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - See Pane::CalcSnappedDimension
|
||||
float TerminalWindow::CalcSnappedDimension(const bool widthOrHeight, const float dimension) const
|
||||
@@ -1188,7 +1193,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
bool TerminalWindow::AutoHideWindow()
|
||||
{
|
||||
return _settings.GlobalSettings().AutoHideWindow();
|
||||
return _currentWindowSettings().AutoHideWindow();
|
||||
}
|
||||
|
||||
void TerminalWindow::UpdateSettingsHandler(const winrt::IInspectable& /*sender*/,
|
||||
@@ -1207,21 +1212,22 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void TerminalWindow::WindowName(const winrt::hstring& name)
|
||||
{
|
||||
const auto oldIsQuakeMode = _WindowProperties->IsQuakeWindow();
|
||||
const auto oldName = _WindowProperties->WindowName();
|
||||
_WindowProperties->WindowName(name);
|
||||
if (!_root)
|
||||
if (!_root || oldName == name)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const auto newIsQuakeMode = _WindowProperties->IsQuakeWindow();
|
||||
if (newIsQuakeMode != oldIsQuakeMode)
|
||||
{
|
||||
// If we're entering Quake Mode from ~Focus Mode, then this will enter Focus Mode
|
||||
// If we're entering Quake Mode from Focus Mode, then this will do nothing
|
||||
// If we're leaving Quake Mode (we're already in Focus Mode), then this will do nothing
|
||||
_root->SetFocusMode(true);
|
||||
IsQuakeWindowChanged.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
// The window name determines which WindowSettings we use
|
||||
// (via _currentWindowSettings()). Since it changed, refresh
|
||||
// all downstream consumers of per-window settings:
|
||||
// - TerminalPage (settings cache, tab/pane settings)
|
||||
// - Theme (may differ per window)
|
||||
// - Docking & host-level properties (via IsQuakeWindowChanged -> AppHost)
|
||||
_root->SetSettings(_settings, true);
|
||||
_RefreshThemeRoutine();
|
||||
IsQuakeWindowChanged.raise(*this, nullptr);
|
||||
}
|
||||
void TerminalWindow::WindowId(const uint64_t& id)
|
||||
{
|
||||
@@ -1332,13 +1338,13 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
if (!FocusMode())
|
||||
{
|
||||
if (!_settings.GlobalSettings().AlwaysShowTabs())
|
||||
if (!_currentWindowSettings().AlwaysShowTabs())
|
||||
{
|
||||
// Hide the title bar = off, Always show tabs = off.
|
||||
static constexpr auto titlebarHeight = 10;
|
||||
pixelSize.Height += (titlebarHeight)*scale;
|
||||
}
|
||||
else if (!_settings.GlobalSettings().ShowTabsInTitlebar())
|
||||
else if (!_currentWindowSettings().ShowTabsInTitlebar())
|
||||
{
|
||||
// Hide the title bar = off, Always show tabs = on.
|
||||
static constexpr auto titlebarAndTabBarHeight = 40;
|
||||
@@ -1419,9 +1425,9 @@ namespace winrt::TerminalApp::implementation
|
||||
return _WindowName.empty() ? til::hstring_format(FMT_COMPILE(L"<{}>"), RS_(L"UnnamedWindowName")) : _WindowName;
|
||||
}
|
||||
|
||||
bool WindowProperties::IsQuakeWindow() const noexcept
|
||||
WindowSettings TerminalWindow::_currentWindowSettings() const
|
||||
{
|
||||
return _WindowName == L"_quake";
|
||||
return _settings.WindowSettings(_WindowProperties->WindowName());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -44,7 +44,6 @@ namespace winrt::TerminalApp::implementation
|
||||
void WindowId(const uint64_t& value);
|
||||
winrt::hstring WindowIdForDisplay() const noexcept;
|
||||
winrt::hstring WindowNameForDisplay() const noexcept;
|
||||
bool IsQuakeWindow() const noexcept;
|
||||
|
||||
til::property_changed_event PropertyChanged;
|
||||
|
||||
@@ -134,12 +133,12 @@ namespace winrt::TerminalApp::implementation
|
||||
void DismissDialog();
|
||||
|
||||
Microsoft::Terminal::Settings::Model::Theme Theme();
|
||||
Microsoft::Terminal::Settings::Model::Docking Docking();
|
||||
void UpdateSettingsHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::TerminalApp::SettingsLoadEventArgs& arg);
|
||||
|
||||
void WindowName(const winrt::hstring& value);
|
||||
void WindowId(const uint64_t& value);
|
||||
|
||||
bool IsQuakeWindow() const noexcept { return _WindowProperties->IsQuakeWindow(); }
|
||||
TerminalApp::WindowProperties WindowProperties() { return *_WindowProperties; }
|
||||
|
||||
void AttachContent(winrt::hstring content, uint32_t tabIndex);
|
||||
@@ -187,6 +186,8 @@ namespace winrt::TerminalApp::implementation
|
||||
TerminalApp::ContentManager _manager{ nullptr };
|
||||
std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs> _initialContentArgs;
|
||||
|
||||
Microsoft::Terminal::Settings::Model::WindowSettings _currentWindowSettings() const;
|
||||
|
||||
void _ShowLoadErrorsDialog(const winrt::hstring& titleKey,
|
||||
const winrt::hstring& contentKey,
|
||||
HRESULT settingsLoadedResult,
|
||||
|
||||
@@ -72,6 +72,8 @@ namespace TerminalApp
|
||||
Boolean AlwaysOnTop { get; };
|
||||
Boolean AutoHideWindow { get; };
|
||||
Boolean ShowTabsFullscreen { get; };
|
||||
Microsoft.Terminal.Settings.Model.Theme Theme { get; };
|
||||
Microsoft.Terminal.Settings.Model.Docking Docking { get; };
|
||||
|
||||
void IdentifyWindow();
|
||||
void SetPersistedLayoutIdx(UInt32 idx);
|
||||
@@ -105,7 +107,6 @@ namespace TerminalApp
|
||||
WindowProperties WindowProperties { get; };
|
||||
void WindowName(String name);
|
||||
void WindowId(UInt64 id);
|
||||
Boolean IsQuakeWindow();
|
||||
|
||||
// See IDialogPresenter and TerminalPage's DialogPresenter for more
|
||||
// information.
|
||||
|
||||
@@ -1935,8 +1935,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// - args: event data
|
||||
void TermControl::_TappedHandler(const IInspectable& /*sender*/, const TappedRoutedEventArgs& e)
|
||||
{
|
||||
Focus(FocusState::Pointer);
|
||||
|
||||
if (e.PointerDeviceType() == Windows::Devices::Input::PointerDeviceType::Touch)
|
||||
{
|
||||
// Normally TSF would be responsible for showing the touch keyboard, but it's buggy for us:
|
||||
@@ -2908,8 +2906,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do we ever get here (= uninitialized terminal)? If so: How?
|
||||
assert(false);
|
||||
return { 10, 10 };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,21 +50,21 @@ namespace winrt::Microsoft::Terminal::Settings
|
||||
return { horizAlign, vertAlign };
|
||||
}
|
||||
|
||||
winrt::com_ptr<TerminalSettings> TerminalSettings::_CreateWithProfileCommon(const Model::CascadiaSettings& appSettings, const Model::Profile& profile)
|
||||
winrt::com_ptr<TerminalSettings> TerminalSettings::_CreateWithProfileCommon(const Model::CascadiaSettings& appSettings, const Model::Profile& profile, const Model::WindowSettings& windowSettings)
|
||||
{
|
||||
auto settings{ winrt::make_self<TerminalSettings>() };
|
||||
|
||||
const auto globals = appSettings.GlobalSettings();
|
||||
settings->_ApplyProfileSettings(profile);
|
||||
settings->_ApplyGlobalSettings(globals);
|
||||
settings->_ApplyAppearanceSettings(profile.DefaultAppearance(), globals.ColorSchemes(), globals.CurrentTheme());
|
||||
settings->_ApplyWindowSettings(windowSettings);
|
||||
settings->_ApplyAppearanceSettings(profile.DefaultAppearance(), globals.ColorSchemes(), globals.CurrentTheme(windowSettings));
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
winrt::com_ptr<TerminalSettings> TerminalSettings::CreateForPreview(const Model::CascadiaSettings& appSettings, const Model::Profile& profile)
|
||||
winrt::com_ptr<TerminalSettings> TerminalSettings::CreateForPreview(const Model::CascadiaSettings& appSettings, const Model::Profile& profile, const Model::WindowSettings& windowSettings)
|
||||
{
|
||||
const auto settings = _CreateWithProfileCommon(appSettings, profile);
|
||||
const auto settings = _CreateWithProfileCommon(appSettings, profile, windowSettings);
|
||||
settings->_UseBackgroundImageForWindow = false;
|
||||
return settings;
|
||||
}
|
||||
@@ -80,9 +80,9 @@ namespace winrt::Microsoft::Terminal::Settings
|
||||
// Return Value:
|
||||
// - A TerminalSettingsCreateResult, which contains a pair of TerminalSettings objects,
|
||||
// one for when the terminal is focused and the other for when the terminal is unfocused
|
||||
TerminalSettingsCreateResult TerminalSettings::CreateWithProfile(const Model::CascadiaSettings& appSettings, const Model::Profile& profile)
|
||||
TerminalSettingsCreateResult TerminalSettings::CreateWithProfile(const Model::CascadiaSettings& appSettings, const Model::Profile& profile, const Model::WindowSettings& windowSettings)
|
||||
{
|
||||
const auto settings = _CreateWithProfileCommon(appSettings, profile);
|
||||
const auto settings = _CreateWithProfileCommon(appSettings, profile, windowSettings);
|
||||
|
||||
winrt::com_ptr<TerminalSettings> child{ nullptr };
|
||||
if (const auto& unfocusedAppearance{ profile.UnfocusedAppearance() })
|
||||
@@ -90,7 +90,7 @@ namespace winrt::Microsoft::Terminal::Settings
|
||||
const auto globals = appSettings.GlobalSettings();
|
||||
child = winrt::make_self<TerminalSettings>();
|
||||
child->_parent = settings->get_strong();
|
||||
child->_ApplyAppearanceSettings(unfocusedAppearance, globals.ColorSchemes(), globals.CurrentTheme());
|
||||
child->_ApplyAppearanceSettings(unfocusedAppearance, globals.ColorSchemes(), globals.CurrentTheme(windowSettings));
|
||||
}
|
||||
|
||||
return TerminalSettingsCreateResult{ settings.get(), child.get() };
|
||||
@@ -114,10 +114,11 @@ namespace winrt::Microsoft::Terminal::Settings
|
||||
// - A TerminalSettingsCreateResult object, which contains a pair of TerminalSettings
|
||||
// objects. One for when the terminal is focused and one for when the terminal is unfocused.
|
||||
TerminalSettingsCreateResult TerminalSettings::CreateWithNewTerminalArgs(const Model::CascadiaSettings& appSettings,
|
||||
const Model::NewTerminalArgs& newTerminalArgs)
|
||||
const Model::NewTerminalArgs& newTerminalArgs,
|
||||
const Model::WindowSettings& windowSettings)
|
||||
{
|
||||
const auto profile = appSettings.GetProfileForArgs(newTerminalArgs);
|
||||
auto settingsPair{ CreateWithProfile(appSettings, profile) };
|
||||
const auto profile = appSettings.GetProfileForArgs(newTerminalArgs, windowSettings);
|
||||
auto settingsPair{ CreateWithProfile(appSettings, profile, windowSettings) };
|
||||
auto defaultSettings = settingsPair.DefaultSettings();
|
||||
|
||||
if (newTerminalArgs)
|
||||
@@ -357,15 +358,15 @@ namespace winrt::Microsoft::Terminal::Settings
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Applies appropriate settings from the globals into the TerminalSettings object.
|
||||
// - Applies appropriate settings from the window settings into the TerminalSettings object.
|
||||
// Arguments:
|
||||
// - globalSettings: the global property values we're applying.
|
||||
// - windowSettings: the per-window property values we're applying.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalSettings::_ApplyGlobalSettings(const Model::GlobalAppSettings& globalSettings) noexcept
|
||||
void TerminalSettings::_ApplyWindowSettings(const Model::WindowSettings& windowSettings) noexcept
|
||||
{
|
||||
_InitialRows = globalSettings.InitialRows();
|
||||
_InitialCols = globalSettings.InitialCols();
|
||||
_InitialRows = windowSettings.InitialRows();
|
||||
_InitialCols = windowSettings.InitialCols();
|
||||
|
||||
_WordDelimiters = globalSettings.WordDelimiters();
|
||||
_CopyOnSelect = globalSettings.CopyOnSelect();
|
||||
|
||||
@@ -57,13 +57,15 @@ namespace winrt::Microsoft::Terminal::Settings
|
||||
{
|
||||
TerminalSettings() = default;
|
||||
|
||||
static winrt::com_ptr<TerminalSettings> CreateForPreview(const Model::CascadiaSettings& appSettings, const Model::Profile& profile);
|
||||
static winrt::com_ptr<TerminalSettings> CreateForPreview(const Model::CascadiaSettings& appSettings, const Model::Profile& profile, const Model::WindowSettings& windowSettings);
|
||||
|
||||
static TerminalSettingsCreateResult CreateWithProfile(const Model::CascadiaSettings& appSettings,
|
||||
const Model::Profile& profile);
|
||||
const Model::Profile& profile,
|
||||
const Model::WindowSettings& windowSettings);
|
||||
|
||||
static TerminalSettingsCreateResult CreateWithNewTerminalArgs(const Model::CascadiaSettings& appSettings,
|
||||
const Model::NewTerminalArgs& newTerminalArgs);
|
||||
const Model::NewTerminalArgs& newTerminalArgs,
|
||||
const Model::WindowSettings& windowSettings);
|
||||
|
||||
void ApplyColorScheme(const Model::ColorScheme& scheme);
|
||||
|
||||
@@ -102,10 +104,10 @@ namespace winrt::Microsoft::Terminal::Settings
|
||||
std::optional<std::array<Microsoft::Terminal::Core::Color, COLOR_TABLE_SIZE>> _ColorTable;
|
||||
std::span<Microsoft::Terminal::Core::Color> _getColorTableImpl();
|
||||
|
||||
static winrt::com_ptr<TerminalSettings> _CreateWithProfileCommon(const Model::CascadiaSettings& appSettings, const Model::Profile& profile);
|
||||
static winrt::com_ptr<TerminalSettings> _CreateWithProfileCommon(const Model::CascadiaSettings& appSettings, const Model::Profile& profile, const Model::WindowSettings& windowSettings);
|
||||
void _ApplyProfileSettings(const Model::Profile& profile);
|
||||
|
||||
void _ApplyGlobalSettings(const Model::GlobalAppSettings& globalSettings) noexcept;
|
||||
void _ApplyWindowSettings(const Model::WindowSettings& windowSettings) noexcept;
|
||||
void _ApplyAppearanceSettings(const Microsoft::Terminal::Settings::Model::IAppearanceConfig& appearance,
|
||||
const Windows::Foundation::Collections::IMapView<hstring, Microsoft::Terminal::Settings::Model::ColorScheme>& schemes,
|
||||
const winrt::Microsoft::Terminal::Settings::Model::Theme currentTheme);
|
||||
|
||||
@@ -25,8 +25,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.GlobalSettings(), AllowHeadless);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.GlobalSettings(), DebugFeaturesEnabled);
|
||||
GETSET_BINDABLE_ENUM_SETTING(TextMeasurement, winrt::Microsoft::Terminal::Control::TextMeasurement, _settings.GlobalSettings().TextMeasurement);
|
||||
GETSET_BINDABLE_ENUM_SETTING(AmbiguousWidth, winrt::Microsoft::Terminal::Control::AmbiguousWidth, _settings.GlobalSettings().AmbiguousWidth);
|
||||
GETSET_BINDABLE_ENUM_SETTING(TextMeasurement, winrt::Microsoft::Terminal::Control::TextMeasurement, _settings.WindowSettingsDefaults().TextMeasurement);
|
||||
GETSET_BINDABLE_ENUM_SETTING(AmbiguousWidth, winrt::Microsoft::Terminal::Control::AmbiguousWidth, _settings.WindowSettingsDefaults().AmbiguousWidth);
|
||||
|
||||
private:
|
||||
Model::CascadiaSettings _settings;
|
||||
|
||||
@@ -22,7 +22,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
constexpr std::wstring_view legacyDarkThemeName{ L"legacyDark" };
|
||||
constexpr std::wstring_view legacyLightThemeName{ L"legacyLight" };
|
||||
|
||||
GlobalAppearanceViewModel::GlobalAppearanceViewModel(Model::GlobalAppSettings globalSettings) :
|
||||
GlobalAppearanceViewModel::GlobalAppearanceViewModel(Model::GlobalAppSettings globalSettings, Model::WindowSettings windowSettings) :
|
||||
_windowSettings{ windowSettings },
|
||||
_GlobalSettings{ globalSettings },
|
||||
_ThemeList{ single_threaded_observable_vector<Model::Theme>() }
|
||||
{
|
||||
@@ -46,7 +47,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
winrt::Windows::Foundation::IInspectable GlobalAppearanceViewModel::CurrentTheme()
|
||||
{
|
||||
return _GlobalSettings.CurrentTheme();
|
||||
return _GlobalSettings.CurrentTheme(_windowSettings);
|
||||
}
|
||||
|
||||
// Get the name out of the newly selected item, stash that as the Theme name
|
||||
@@ -56,7 +57,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
if (const auto& theme{ tag.try_as<Model::Theme>() })
|
||||
{
|
||||
_GlobalSettings.Theme(Model::ThemePair{ theme.Name() });
|
||||
_windowSettings.Theme(Model::ThemePair{ theme.Name() });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,12 +104,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
bool GlobalAppearanceViewModel::InvertedDisableAnimations()
|
||||
{
|
||||
return !_GlobalSettings.DisableAnimations();
|
||||
return !_windowSettings.DisableAnimations();
|
||||
}
|
||||
|
||||
void GlobalAppearanceViewModel::InvertedDisableAnimations(bool value)
|
||||
{
|
||||
_GlobalSettings.DisableAnimations(!value);
|
||||
_windowSettings.DisableAnimations(!value);
|
||||
}
|
||||
|
||||
void GlobalAppearanceViewModel::ShowTitlebarToggled(const winrt::Windows::Foundation::IInspectable& /* sender */, const RoutedEventArgs& /* args */)
|
||||
|
||||
@@ -12,14 +12,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
struct GlobalAppearanceViewModel : GlobalAppearanceViewModelT<GlobalAppearanceViewModel>, ViewModelHelper<GlobalAppearanceViewModel>
|
||||
{
|
||||
public:
|
||||
GlobalAppearanceViewModel(Model::GlobalAppSettings globalSettings);
|
||||
GlobalAppearanceViewModel(Model::GlobalAppSettings globalSettings, Model::WindowSettings windowSettings);
|
||||
|
||||
// DON'T YOU DARE ADD A `WINRT_CALLBACK(PropertyChanged` TO A CLASS DERIVED FROM ViewModelHelper. Do this instead:
|
||||
using ViewModelHelper<GlobalAppearanceViewModel>::PropertyChanged;
|
||||
|
||||
WINRT_PROPERTY(Windows::Foundation::Collections::IObservableVector<Model::Theme>, ThemeList, nullptr);
|
||||
GETSET_BINDABLE_ENUM_SETTING(NewTabPosition, Model::NewTabPosition, _GlobalSettings.NewTabPosition);
|
||||
GETSET_BINDABLE_ENUM_SETTING(TabWidthMode, winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode, _GlobalSettings.TabWidthMode);
|
||||
GETSET_BINDABLE_ENUM_SETTING(NewTabPosition, Model::NewTabPosition, _windowSettings.NewTabPosition);
|
||||
GETSET_BINDABLE_ENUM_SETTING(TabWidthMode, winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode, _windowSettings.TabWidthMode);
|
||||
|
||||
public:
|
||||
winrt::Windows::Foundation::IInspectable CurrentTheme();
|
||||
@@ -31,19 +31,20 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
void ShowTitlebarToggled(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& args);
|
||||
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, AlwaysShowTabs);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ShowTabsFullscreen);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ShowTabsInTitlebar);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, UseAcrylicInTabRow);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ShowTitleInTitlebar);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, AlwaysOnTop);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, AutoHideWindow);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, AlwaysShowTabs);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, ShowTabsFullscreen);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, ShowTabsInTitlebar);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, UseAcrylicInTabRow);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, ShowTitleInTitlebar);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, AlwaysOnTop);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, AutoHideWindow);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, AlwaysShowNotificationIcon);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, MinimizeToNotificationArea);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ShowAdminShield);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, EnableUnfocusedAcrylic);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, MinimizeToNotificationArea);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, ShowAdminShield);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, EnableUnfocusedAcrylic);
|
||||
|
||||
private:
|
||||
Model::WindowSettings _windowSettings;
|
||||
Model::GlobalAppSettings _GlobalSettings;
|
||||
winrt::Windows::Foundation::IInspectable _currentTheme;
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
runtimeclass GlobalAppearanceViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
GlobalAppearanceViewModel(Microsoft.Terminal.Settings.Model.GlobalAppSettings globalSettings);
|
||||
GlobalAppearanceViewModel(Microsoft.Terminal.Settings.Model.GlobalAppSettings globalSettings,
|
||||
Microsoft.Terminal.Settings.Model.WindowSettings windowSettings);
|
||||
|
||||
IInspectable CurrentTheme;
|
||||
static String ThemeNameConverter(Microsoft.Terminal.Settings.Model.Theme theme);
|
||||
|
||||
@@ -12,8 +12,9 @@ using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
InteractionViewModel::InteractionViewModel(Model::GlobalAppSettings globalSettings) :
|
||||
_GlobalSettings{ globalSettings }
|
||||
InteractionViewModel::InteractionViewModel(Model::GlobalAppSettings globalSettings, Model::WindowSettings windowSettings) :
|
||||
_GlobalSettings{ globalSettings },
|
||||
_windowSettings{ windowSettings }
|
||||
{
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(TabSwitcherMode, TabSwitcherMode, TabSwitcherMode, L"Globals_TabSwitcherMode", L"Content");
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(CopyFormat, CopyFormat, winrt::Microsoft::Terminal::Control::CopyFormat, L"Globals_CopyFormat", L"Content");
|
||||
|
||||
@@ -12,32 +12,33 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
struct InteractionViewModel : InteractionViewModelT<InteractionViewModel>, ViewModelHelper<InteractionViewModel>
|
||||
{
|
||||
public:
|
||||
InteractionViewModel(Model::GlobalAppSettings globalSettings);
|
||||
InteractionViewModel(Model::GlobalAppSettings globalSettings, Model::WindowSettings windowSettings);
|
||||
|
||||
// DON'T YOU DARE ADD A `WINRT_CALLBACK(PropertyChanged` TO A CLASS DERIVED FROM ViewModelHelper. Do this instead:
|
||||
using ViewModelHelper<InteractionViewModel>::PropertyChanged;
|
||||
|
||||
GETSET_BINDABLE_ENUM_SETTING(TabSwitcherMode, Model::TabSwitcherMode, _GlobalSettings.TabSwitcherMode);
|
||||
GETSET_BINDABLE_ENUM_SETTING(CopyFormat, winrt::Microsoft::Terminal::Control::CopyFormat, _GlobalSettings.CopyFormatting);
|
||||
GETSET_BINDABLE_ENUM_SETTING(TabSwitcherMode, Model::TabSwitcherMode, _windowSettings.TabSwitcherMode);
|
||||
GETSET_BINDABLE_ENUM_SETTING(CopyFormat, winrt::Microsoft::Terminal::Control::CopyFormat, _windowSettings.CopyFormatting);
|
||||
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, CopyOnSelect);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, TrimBlockSelection);
|
||||
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);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ConfirmCloseAllTabs);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, CopyOnSelect);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, TrimBlockSelection);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, TrimPaste);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, SnapToGridOnResize);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, FocusFollowMouse);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, ScrollToZoom);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, ScrollToChangeOpacity);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, DetectURLs);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, SearchWebDefaultQueryUrl);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, WordDelimiters);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, ConfirmCloseAllTabs);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, InputServiceWarning);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, WarnAboutLargePaste);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, WarnAboutMultiLinePaste);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, WarnAboutLargePaste);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, WarnAboutMultiLinePaste);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, EnableColorSelection);
|
||||
|
||||
private:
|
||||
Model::GlobalAppSettings _GlobalSettings;
|
||||
Model::WindowSettings _windowSettings;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
runtimeclass InteractionViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
InteractionViewModel(Microsoft.Terminal.Settings.Model.GlobalAppSettings globalSettings);
|
||||
InteractionViewModel(Microsoft.Terminal.Settings.Model.GlobalAppSettings globalSettings,
|
||||
Microsoft.Terminal.Settings.Model.WindowSettings windowSettings);
|
||||
|
||||
IInspectable CurrentTabSwitcherMode;
|
||||
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> TabSwitcherModeList { get; };
|
||||
|
||||
@@ -231,7 +231,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
double LaunchViewModel::InitialPosX()
|
||||
{
|
||||
const auto x = _Settings.GlobalSettings().InitialPosition().X;
|
||||
const auto x = _Settings.WindowSettingsDefaults().InitialPosition().X;
|
||||
// If there's no value here, return NAN - XAML will ignore it and
|
||||
// put the placeholder text in the box instead
|
||||
const auto xCoord = x.try_as<int32_t>();
|
||||
@@ -240,7 +240,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
double LaunchViewModel::InitialPosY()
|
||||
{
|
||||
const auto y = _Settings.GlobalSettings().InitialPosition().Y;
|
||||
const auto y = _Settings.WindowSettingsDefaults().InitialPosition().Y;
|
||||
// If there's no value here, return NAN - XAML will ignore it and
|
||||
// put the placeholder text in the box instead
|
||||
const auto yCoord = y.try_as<int32_t>();
|
||||
@@ -255,8 +255,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
xCoordRef = gsl::narrow_cast<int32_t>(xCoord);
|
||||
}
|
||||
const LaunchPosition newPos{ xCoordRef, _Settings.GlobalSettings().InitialPosition().Y };
|
||||
_Settings.GlobalSettings().InitialPosition(newPos);
|
||||
const LaunchPosition newPos{ xCoordRef, _Settings.WindowSettingsDefaults().InitialPosition().Y };
|
||||
_Settings.WindowSettingsDefaults().InitialPosition(newPos);
|
||||
_NotifyChanges(L"LaunchParametersCurrentValue");
|
||||
}
|
||||
|
||||
@@ -268,8 +268,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
yCoordRef = gsl::narrow_cast<int32_t>(yCoord);
|
||||
}
|
||||
const LaunchPosition newPos{ _Settings.GlobalSettings().InitialPosition().X, yCoordRef };
|
||||
_Settings.GlobalSettings().InitialPosition(newPos);
|
||||
const LaunchPosition newPos{ _Settings.WindowSettingsDefaults().InitialPosition().X, yCoordRef };
|
||||
_Settings.WindowSettingsDefaults().InitialPosition(newPos);
|
||||
_NotifyChanges(L"LaunchParametersCurrentValue");
|
||||
}
|
||||
|
||||
@@ -291,7 +291,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
winrt::Windows::Foundation::IInspectable LaunchViewModel::CurrentLaunchMode()
|
||||
{
|
||||
return winrt::box_value<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>(_LaunchModeMap.Lookup(_Settings.GlobalSettings().LaunchMode()));
|
||||
return winrt::box_value<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>(_LaunchModeMap.Lookup(_Settings.WindowSettingsDefaults().LaunchMode()));
|
||||
}
|
||||
|
||||
void LaunchViewModel::CurrentLaunchMode(const winrt::Windows::Foundation::IInspectable& enumEntry)
|
||||
@@ -299,7 +299,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
if (const auto ee = enumEntry.try_as<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>())
|
||||
{
|
||||
const auto setting = winrt::unbox_value<LaunchMode>(ee.EnumValue());
|
||||
_Settings.GlobalSettings().LaunchMode(setting);
|
||||
_Settings.WindowSettingsDefaults().LaunchMode(setting);
|
||||
_NotifyChanges(L"LaunchParametersCurrentValue");
|
||||
}
|
||||
}
|
||||
@@ -311,14 +311,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
winrt::Windows::Foundation::IInspectable LaunchViewModel::CurrentDefaultProfile()
|
||||
{
|
||||
const auto defaultProfileGuid{ _Settings.GlobalSettings().DefaultProfile() };
|
||||
const auto defaultProfileGuid{ _Settings.WindowSettingsDefaults().DefaultProfile() };
|
||||
return winrt::box_value(_Settings.FindProfile(defaultProfileGuid));
|
||||
}
|
||||
|
||||
void LaunchViewModel::CurrentDefaultProfile(const IInspectable& value)
|
||||
{
|
||||
const auto profile{ winrt::unbox_value<Model::Profile>(value) };
|
||||
_Settings.GlobalSettings().DefaultProfile(profile.Guid());
|
||||
_Settings.WindowSettingsDefaults().DefaultProfile(profile.Guid());
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::Collections::IObservableVector<Model::Profile> LaunchViewModel::DefaultProfiles() const
|
||||
|
||||
@@ -46,13 +46,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
void CurrentLaunchMode(const winrt::Windows::Foundation::IInspectable& enumEntry);
|
||||
winrt::Windows::Foundation::Collections::IObservableVector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry> LaunchModeList();
|
||||
|
||||
GETSET_BINDABLE_ENUM_SETTING(DefaultInputScope, winrt::Microsoft::Terminal::Control::DefaultInputScope, _Settings.GlobalSettings().DefaultInputScope);
|
||||
GETSET_BINDABLE_ENUM_SETTING(DefaultInputScope, winrt::Microsoft::Terminal::Control::DefaultInputScope, _Settings.WindowSettingsDefaults().DefaultInputScope);
|
||||
GETSET_BINDABLE_ENUM_SETTING(FirstWindowPreference, Model::FirstWindowPreference, _Settings.GlobalSettings().FirstWindowPreference);
|
||||
GETSET_BINDABLE_ENUM_SETTING(WindowingBehavior, Model::WindowingMode, _Settings.GlobalSettings().WindowingBehavior);
|
||||
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_Settings.GlobalSettings(), CenterOnLaunch);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_Settings.GlobalSettings(), InitialRows);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_Settings.GlobalSettings(), InitialCols);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_Settings.WindowSettingsDefaults(), CenterOnLaunch);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_Settings.WindowSettingsDefaults(), InitialRows);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_Settings.WindowSettingsDefaults(), InitialCols);
|
||||
|
||||
bool StartOnUserLoginAvailable();
|
||||
safe_void_coroutine PrepareStartOnUserLoginSettings();
|
||||
|
||||
@@ -1127,7 +1127,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
}
|
||||
}
|
||||
|
||||
const auto theme = _settingsSource.GlobalSettings().CurrentTheme();
|
||||
const auto theme = _settingsSource.GlobalSettings().CurrentTheme(_settingsSource.WindowSettingsDefaults());
|
||||
const auto hasThemeForSettings{ theme.Settings() != nullptr };
|
||||
const auto appTheme = theme.RequestedTheme();
|
||||
const auto requestedTheme = (hasThemeForSettings) ? theme.Settings().RequestedTheme() : appTheme;
|
||||
@@ -1145,7 +1145,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
//
|
||||
// To mitigate this, don't set the transparent background in the case
|
||||
// that our theme is different than the app's.
|
||||
const bool actuallyUseMica = isMicaAvailable && (appTheme == requestedTheme);
|
||||
const bool actuallyUseMica = isMicaAvailable;
|
||||
|
||||
const auto bgKey = (theme.Window() != nullptr && theme.Window().UseMica()) && actuallyUseMica ?
|
||||
L"SettingsPageMicaBackground" :
|
||||
|
||||
@@ -325,7 +325,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
SelectedProfile(AvailableProfiles().GetAt(0));
|
||||
|
||||
_rootEntries = _ConvertToViewModelEntries(_Settings.GlobalSettings().NewTabMenu(), _Settings);
|
||||
_rootEntries = _ConvertToViewModelEntries(_Settings.WindowSettingsDefaults().NewTabMenu(), _Settings);
|
||||
_rootEntriesChangedRevoker = _rootEntries.VectorChanged(winrt::auto_revoke, [this](auto&&, const IVectorChangedEventArgs& args) {
|
||||
switch (args.CollectionChange())
|
||||
{
|
||||
@@ -337,25 +337,25 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
modelEntries.push_back(NewTabMenuEntryViewModel::GetModel(entry));
|
||||
}
|
||||
_Settings.GlobalSettings().NewTabMenu(single_threaded_vector<Model::NewTabMenuEntry>(std::move(modelEntries)));
|
||||
_Settings.WindowSettingsDefaults().NewTabMenu(single_threaded_vector<Model::NewTabMenuEntry>(std::move(modelEntries)));
|
||||
return;
|
||||
}
|
||||
case CollectionChange::ItemInserted:
|
||||
{
|
||||
const auto& insertedEntryVM = _rootEntries.GetAt(args.Index());
|
||||
const auto& insertedEntry = NewTabMenuEntryViewModel::GetModel(insertedEntryVM);
|
||||
_Settings.GlobalSettings().NewTabMenu().InsertAt(args.Index(), insertedEntry);
|
||||
_Settings.WindowSettingsDefaults().NewTabMenu().InsertAt(args.Index(), insertedEntry);
|
||||
return;
|
||||
}
|
||||
case CollectionChange::ItemRemoved:
|
||||
{
|
||||
_Settings.GlobalSettings().NewTabMenu().RemoveAt(args.Index());
|
||||
_Settings.WindowSettingsDefaults().NewTabMenu().RemoveAt(args.Index());
|
||||
return;
|
||||
}
|
||||
case CollectionChange::ItemChanged:
|
||||
{
|
||||
const auto& modifiedEntry = _rootEntries.GetAt(args.Index());
|
||||
_Settings.GlobalSettings().NewTabMenu().SetAt(args.Index(), NewTabMenuEntryViewModel::GetModel(modifiedEntry));
|
||||
_Settings.WindowSettingsDefaults().NewTabMenu().SetAt(args.Index(), NewTabMenuEntryViewModel::GetModel(modifiedEntry));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
// This may look pricey, but it only resolves resources that have not been visited
|
||||
// and the preview update is debounced.
|
||||
_appSettings.ResolveMediaResources();
|
||||
return *Settings::TerminalSettings::CreateForPreview(_appSettings, _profile);
|
||||
return *Settings::TerminalSettings::CreateForPreview(_appSettings, _profile, _appSettings.WindowSettingsDefaults());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -385,7 +385,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
Windows::UI::Color ProfileViewModel::TabThemeColorPreview() const
|
||||
{
|
||||
const auto currentTheme = _appSettings.GlobalSettings().CurrentTheme();
|
||||
const auto currentTheme = _appSettings.GlobalSettings().CurrentTheme(_appSettings.WindowSettingsDefaults());
|
||||
if (const auto tabTheme = currentTheme.Tab())
|
||||
{
|
||||
// theme.tab.background: theme color must be evaluated
|
||||
|
||||
@@ -13,9 +13,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
explicit RenderingViewModel(Model::CascadiaSettings settings) noexcept;
|
||||
|
||||
GETSET_BINDABLE_ENUM_SETTING(GraphicsAPI, winrt::Microsoft::Terminal::Control::GraphicsAPI, _settings.GlobalSettings().GraphicsAPI);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.GlobalSettings(), DisablePartialInvalidation);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.GlobalSettings(), SoftwareRendering);
|
||||
GETSET_BINDABLE_ENUM_SETTING(GraphicsAPI, winrt::Microsoft::Terminal::Control::GraphicsAPI, _settings.WindowSettingsDefaults().GraphicsAPI);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.WindowSettingsDefaults(), DisablePartialInvalidation);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.WindowSettingsDefaults(), SoftwareRendering);
|
||||
|
||||
private:
|
||||
Model::CascadiaSettings _settings{ nullptr };
|
||||
|
||||
@@ -2606,19 +2606,19 @@
|
||||
<comment>An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleWsl.Content" xml:space="preserve">
|
||||
<value>WSL (C:\ -> /mnt/c)</value>
|
||||
<value>WSL (C:\ 🡒 /mnt/c)</value>
|
||||
<comment>{Locked="WSL","C:\","/mnt/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleCygwin.Content" xml:space="preserve">
|
||||
<value>Cygwin (C:\ -> /cygdrive/c)</value>
|
||||
<value>Cygwin (C:\ 🡒 /cygdrive/c)</value>
|
||||
<comment>{Locked="Cygwin","C:\","/cygdrive/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMsys2.Content" xml:space="preserve">
|
||||
<value>MSYS2 (C:\ -> /c)</value>
|
||||
<value>MSYS2 (C:\ 🡒 /c)</value>
|
||||
<comment>{Locked="MSYS2","C:\","/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMinGW.Content" xml:space="preserve">
|
||||
<value>MinGW (C:\ -> C:/)</value>
|
||||
<value>MinGW (C:\ 🡒 C:/)</value>
|
||||
<comment>{Locked="MinGW","C:\","C:/"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_Delete_Orphaned.Header" xml:space="preserve">
|
||||
@@ -2744,4 +2744,12 @@
|
||||
<value>Tippen, um Symbole zu filtern</value>
|
||||
<comment>Placeholder text for a text box to filter and select an icon.</comment>
|
||||
</data>
|
||||
<data name="Profile_DragDropDelimiter.Header" xml:space="preserve">
|
||||
<value>Trennzeichen per Drag &amp; Drop</value>
|
||||
<comment>Header for a control to set the delimiter used when dragging multiple files into the terminal.</comment>
|
||||
</data>
|
||||
<data name="Profile_DragDropDelimiter.HelpText" xml:space="preserve">
|
||||
<value>Dieser Text wird zwischen den Pfaden mehrerer in das Terminal gezogener Dateien eingefügt.</value>
|
||||
<comment>A description for what the "drag drop delimiter" setting does.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -2610,19 +2610,19 @@
|
||||
<comment>An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleWsl.Content" xml:space="preserve">
|
||||
<value>WSL (C:\ -> /mnt/c)</value>
|
||||
<value>WSL (C:\ 🡒 /mnt/c)</value>
|
||||
<comment>{Locked="WSL","C:\","/mnt/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleCygwin.Content" xml:space="preserve">
|
||||
<value>Cygwin (C:\ -> /cygdrive/c)</value>
|
||||
<value>Cygwin (C:\ 🡒 /cygdrive/c)</value>
|
||||
<comment>{Locked="Cygwin","C:\","/cygdrive/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMsys2.Content" xml:space="preserve">
|
||||
<value>MSYS2 (C:\ -> /c)</value>
|
||||
<value>MSYS2 (C:\ 🡒 /c)</value>
|
||||
<comment>{Locked="MSYS2","C:\","/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMinGW.Content" xml:space="preserve">
|
||||
<value>MinGW (C:\ -> C:/)</value>
|
||||
<value>MinGW (C:\ 🡒 C:/)</value>
|
||||
<comment>{Locked="MinGW","C:\","C:/"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_Delete_Orphaned.Header" xml:space="preserve">
|
||||
|
||||
@@ -2606,19 +2606,19 @@
|
||||
<comment>An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleWsl.Content" xml:space="preserve">
|
||||
<value>WSL (C:\ -> /mnt/c)</value>
|
||||
<value>WSL (C:\ 🡒 /mnt/c)</value>
|
||||
<comment>{Locked="WSL","C:\","/mnt/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleCygwin.Content" xml:space="preserve">
|
||||
<value>Cygwin (C:\ -> /cygdrive/c)</value>
|
||||
<value>Cygwin (C:\ 🡒 /cygdrive/c)</value>
|
||||
<comment>{Locked="Cygwin","C:\","/cygdrive/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMsys2.Content" xml:space="preserve">
|
||||
<value>MSYS2 (C:\ -> /c)</value>
|
||||
<value>MSYS2 (C:\ 🡒 /c)</value>
|
||||
<comment>{Locked="MSYS2","C:\","/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMinGW.Content" xml:space="preserve">
|
||||
<value>MinGW (C:\ -> C:/)</value>
|
||||
<value>MinGW (C:\ 🡒 C:/)</value>
|
||||
<comment>{Locked="MinGW","C:\","C:/"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_Delete_Orphaned.Header" xml:space="preserve">
|
||||
@@ -2744,4 +2744,12 @@
|
||||
<value>Escriba para filtrar iconos</value>
|
||||
<comment>Placeholder text for a text box to filter and select an icon.</comment>
|
||||
</data>
|
||||
<data name="Profile_DragDropDelimiter.Header" xml:space="preserve">
|
||||
<value>Delimitador de arrastrar y colocar</value>
|
||||
<comment>Header for a control to set the delimiter used when dragging multiple files into the terminal.</comment>
|
||||
</data>
|
||||
<data name="Profile_DragDropDelimiter.HelpText" xml:space="preserve">
|
||||
<value>Este texto se insertará entre las rutas de acceso de varios archivos colocados en el terminal.</value>
|
||||
<comment>A description for what the "drag drop delimiter" setting does.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -2606,19 +2606,19 @@
|
||||
<comment>An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleWsl.Content" xml:space="preserve">
|
||||
<value>WSL (C :\ -> /mnt/c)</value>
|
||||
<value>WSL (C:\ 🡒 /mnt/c)</value>
|
||||
<comment>{Locked="WSL","C:\","/mnt/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleCygwin.Content" xml:space="preserve">
|
||||
<value>Cygwin (C :\ -> /cygdrive/c)</value>
|
||||
<value>Cygwin (C:\ 🡒 /cygdrive/c)</value>
|
||||
<comment>{Locked="Cygwin","C:\","/cygdrive/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMsys2.Content" xml:space="preserve">
|
||||
<value>MSYS2 (C:\ -> /c)</value>
|
||||
<value>MSYS2 (C:\ 🡒 /c)</value>
|
||||
<comment>{Locked="MSYS2","C:\","/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMinGW.Content" xml:space="preserve">
|
||||
<value>MinGW (C:\ -> C:/)</value>
|
||||
<value>MinGW (C:\ 🡒 C:/)</value>
|
||||
<comment>{Locked="MinGW","C:\","C:/"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_Delete_Orphaned.Header" xml:space="preserve">
|
||||
@@ -2744,4 +2744,12 @@
|
||||
<value>Taper pour filtrer les icônes</value>
|
||||
<comment>Placeholder text for a text box to filter and select an icon.</comment>
|
||||
</data>
|
||||
<data name="Profile_DragDropDelimiter.Header" xml:space="preserve">
|
||||
<value>Glisser-déplacer le délimiteur</value>
|
||||
<comment>Header for a control to set the delimiter used when dragging multiple files into the terminal.</comment>
|
||||
</data>
|
||||
<data name="Profile_DragDropDelimiter.HelpText" xml:space="preserve">
|
||||
<value>Ce texte sera inséré entre les chemins d’accès de plusieurs fichiers déposés dans le terminal.</value>
|
||||
<comment>A description for what the "drag drop delimiter" setting does.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -2606,19 +2606,19 @@
|
||||
<comment>An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleWsl.Content" xml:space="preserve">
|
||||
<value>WSL (C:\ -> /mnt/c)</value>
|
||||
<value>WSL (C:\ 🡒 /mnt/c)</value>
|
||||
<comment>{Locked="WSL","C:\","/mnt/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleCygwin.Content" xml:space="preserve">
|
||||
<value>Cygwin (C:\ -> /cygdrive/c)</value>
|
||||
<value>Cygwin (C:\ 🡒 /cygdrive/c)</value>
|
||||
<comment>{Locked="Cygwin","C:\","/cygdrive/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMsys2.Content" xml:space="preserve">
|
||||
<value>MSYS2 (C:\ -> /c)</value>
|
||||
<value>MSYS2 (C:\ 🡒 /c)</value>
|
||||
<comment>{Locked="MSYS2","C:\","/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMinGW.Content" xml:space="preserve">
|
||||
<value>MinGW (C:\ -> C:/)</value>
|
||||
<value>MinGW (C:\ 🡒 C:/)</value>
|
||||
<comment>{Locked="MinGW","C:\","C:/"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_Delete_Orphaned.Header" xml:space="preserve">
|
||||
@@ -2744,4 +2744,12 @@
|
||||
<value>Digita per filtrare icone</value>
|
||||
<comment>Placeholder text for a text box to filter and select an icon.</comment>
|
||||
</data>
|
||||
<data name="Profile_DragDropDelimiter.Header" xml:space="preserve">
|
||||
<value>Trascina e rilascia il delimitatore</value>
|
||||
<comment>Header for a control to set the delimiter used when dragging multiple files into the terminal.</comment>
|
||||
</data>
|
||||
<data name="Profile_DragDropDelimiter.HelpText" xml:space="preserve">
|
||||
<value>Questo testo verrà inserito tra i percorsi di più file trascinati nel terminale.</value>
|
||||
<comment>A description for what the "drag drop delimiter" setting does.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -2606,19 +2606,19 @@
|
||||
<comment>An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleWsl.Content" xml:space="preserve">
|
||||
<value>WSL (C:\ -> /mnt/c)</value>
|
||||
<value>WSL (C:\ 🡒 /mnt/c)</value>
|
||||
<comment>{Locked="WSL","C:\","/mnt/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleCygwin.Content" xml:space="preserve">
|
||||
<value>Cygwin (C:\ -> /cygdrive/c)</value>
|
||||
<value>Cygwin (C:\ 🡒 /cygdrive/c)</value>
|
||||
<comment>{Locked="Cygwin","C:\","/cygdrive/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMsys2.Content" xml:space="preserve">
|
||||
<value>MSYS2 (C:\ -> /c)</value>
|
||||
<value>MSYS2 (C:\ 🡒 /c)</value>
|
||||
<comment>{Locked="MSYS2","C:\","/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMinGW.Content" xml:space="preserve">
|
||||
<value>MinGW (C:\ -> C:/)</value>
|
||||
<value>MinGW (C:\ 🡒 C:/)</value>
|
||||
<comment>{Locked="MinGW","C:\","C:/"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_Delete_Orphaned.Header" xml:space="preserve">
|
||||
@@ -2744,4 +2744,12 @@
|
||||
<value>入力してアイコンをフィルター処理します</value>
|
||||
<comment>Placeholder text for a text box to filter and select an icon.</comment>
|
||||
</data>
|
||||
<data name="Profile_DragDropDelimiter.Header" xml:space="preserve">
|
||||
<value>ドラッグ アンド ドロップ区切り記号</value>
|
||||
<comment>Header for a control to set the delimiter used when dragging multiple files into the terminal.</comment>
|
||||
</data>
|
||||
<data name="Profile_DragDropDelimiter.HelpText" xml:space="preserve">
|
||||
<value>このテキストは、ターミナルにドロップされた複数のファイルのパスの間に挿入されます。</value>
|
||||
<comment>A description for what the "drag drop delimiter" setting does.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -2606,19 +2606,19 @@
|
||||
<comment>An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleWsl.Content" xml:space="preserve">
|
||||
<value>WSL(C:\ -> /mnt/c)</value>
|
||||
<value>WSL(C:\ 🡒 /mnt/c)</value>
|
||||
<comment>{Locked="WSL","C:\","/mnt/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleCygwin.Content" xml:space="preserve">
|
||||
<value>Cygwin(C:\ -> /cygdrive/c)</value>
|
||||
<value>Cygwin(C:\ 🡒 /cygdrive/c)</value>
|
||||
<comment>{Locked="Cygwin","C:\","/cygdrive/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMsys2.Content" xml:space="preserve">
|
||||
<value>MSYS2(C:\ -> /c)</value>
|
||||
<value>MSYS2(C:\ 🡒 /c)</value>
|
||||
<comment>{Locked="MSYS2","C:\","/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMinGW.Content" xml:space="preserve">
|
||||
<value>MinGW(C:\ -> C:/)</value>
|
||||
<value>MinGW(C:\ 🡒 C:/)</value>
|
||||
<comment>{Locked="MinGW","C:\","C:/"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_Delete_Orphaned.Header" xml:space="preserve">
|
||||
@@ -2744,4 +2744,12 @@
|
||||
<value>입력하여 아이콘 필터링</value>
|
||||
<comment>Placeholder text for a text box to filter and select an icon.</comment>
|
||||
</data>
|
||||
<data name="Profile_DragDropDelimiter.Header" xml:space="preserve">
|
||||
<value>끌어서 놓기 구분 기호</value>
|
||||
<comment>Header for a control to set the delimiter used when dragging multiple files into the terminal.</comment>
|
||||
</data>
|
||||
<data name="Profile_DragDropDelimiter.HelpText" xml:space="preserve">
|
||||
<value>이 텍스트는 터미널에 놓인 여러 파일의 경로 사이에 삽입됩니다.</value>
|
||||
<comment>A description for what the "drag drop delimiter" setting does.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -2606,19 +2606,19 @@
|
||||
<comment>An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleWsl.Content" xml:space="preserve">
|
||||
<value>WSL (C:\ -> /mnt/c)</value>
|
||||
<value>WSL (C:\ 🡒 /mnt/c)</value>
|
||||
<comment>{Locked="WSL","C:\","/mnt/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleCygwin.Content" xml:space="preserve">
|
||||
<value>Cygwin (C:\ -> /cygdrive/c)</value>
|
||||
<value>Cygwin (C:\ 🡒 /cygdrive/c)</value>
|
||||
<comment>{Locked="Cygwin","C:\","/cygdrive/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMsys2.Content" xml:space="preserve">
|
||||
<value>MSYS2 (C:\ -> /c)</value>
|
||||
<value>MSYS2 (C:\ 🡒 /c)</value>
|
||||
<comment>{Locked="MSYS2","C:\","/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMinGW.Content" xml:space="preserve">
|
||||
<value>MinGW (C:\ -> C:/)</value>
|
||||
<value>MinGW (C:\ 🡒 C:/)</value>
|
||||
<comment>{Locked="MinGW","C:\","C:/"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_Delete_Orphaned.Header" xml:space="preserve">
|
||||
@@ -2744,4 +2744,12 @@
|
||||
<value>Digite para filtrar ícones</value>
|
||||
<comment>Placeholder text for a text box to filter and select an icon.</comment>
|
||||
</data>
|
||||
<data name="Profile_DragDropDelimiter.Header" xml:space="preserve">
|
||||
<value>Delimitador de Arrastar e soltar</value>
|
||||
<comment>Header for a control to set the delimiter used when dragging multiple files into the terminal.</comment>
|
||||
</data>
|
||||
<data name="Profile_DragDropDelimiter.HelpText" xml:space="preserve">
|
||||
<value>Este texto será inserido entre os caminhos de vários arquivos descartados no terminal.</value>
|
||||
<comment>A description for what the "drag drop delimiter" setting does.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -2610,19 +2610,19 @@
|
||||
<comment>An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleWsl.Content" xml:space="preserve">
|
||||
<value>WSL (C:\ -> /mnt/c) !!! !!!</value>
|
||||
<value>WSL (C:\ 🡒 /mnt/c) !!! !!!</value>
|
||||
<comment>{Locked="WSL","C:\","/mnt/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleCygwin.Content" xml:space="preserve">
|
||||
<value>Cygwin (C:\ -> /cygdrive/c) !!! !!! !!</value>
|
||||
<value>Cygwin (C:\ 🡒 /cygdrive/c) !!! !!! !!</value>
|
||||
<comment>{Locked="Cygwin","C:\","/cygdrive/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMsys2.Content" xml:space="preserve">
|
||||
<value>MSYS2 (C:\ -> /c) !!! !!</value>
|
||||
<value>MSYS2 (C:\ 🡒 /c) !!! !!</value>
|
||||
<comment>{Locked="MSYS2","C:\","/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMinGW.Content" xml:space="preserve">
|
||||
<value>MinGW (C:\ -> C:/) !!! !!</value>
|
||||
<value>MinGW (C:\ 🡒 C:/) !!! !!</value>
|
||||
<comment>{Locked="MinGW","C:\","C:/"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_Delete_Orphaned.Header" xml:space="preserve">
|
||||
@@ -2748,4 +2748,12 @@
|
||||
<value>Тÿρě ţθ ƒíŀŧēŗ īçōйš !!! !!!</value>
|
||||
<comment>Placeholder text for a text box to filter and select an icon.</comment>
|
||||
</data>
|
||||
</root>
|
||||
<data name="Profile_DragDropDelimiter.Header" xml:space="preserve">
|
||||
<value>Đґâġ ąńð δŗορ ďèŀιмïţ℮я !!! !!! </value>
|
||||
<comment>Header for a control to set the delimiter used when dragging multiple files into the terminal.</comment>
|
||||
</data>
|
||||
<data name="Profile_DragDropDelimiter.HelpText" xml:space="preserve">
|
||||
<value>Тĥїś ťэхť ẃĭŀł вё îⁿŝέŗŧеď вēťщ℮ěπ τĥę ρªτħѕ óƒ мџĺţīрℓé ƒĭļèś đяǿρрεδ ιйţθ ţħê ţèřмĭлªŀ. !!! !!! !!! !!! !!! !!! !!! !!! !!!</value>
|
||||
<comment>A description for what the "drag drop delimiter" setting does.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2610,19 +2610,19 @@
|
||||
<comment>An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleWsl.Content" xml:space="preserve">
|
||||
<value>WSL (C:\ -> /mnt/c) !!! !!!</value>
|
||||
<value>WSL (C:\ 🡒 /mnt/c) !!! !!!</value>
|
||||
<comment>{Locked="WSL","C:\","/mnt/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleCygwin.Content" xml:space="preserve">
|
||||
<value>Cygwin (C:\ -> /cygdrive/c) !!! !!! !!</value>
|
||||
<value>Cygwin (C:\ 🡒 /cygdrive/c) !!! !!! !!</value>
|
||||
<comment>{Locked="Cygwin","C:\","/cygdrive/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMsys2.Content" xml:space="preserve">
|
||||
<value>MSYS2 (C:\ -> /c) !!! !!</value>
|
||||
<value>MSYS2 (C:\ 🡒 /c) !!! !!</value>
|
||||
<comment>{Locked="MSYS2","C:\","/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMinGW.Content" xml:space="preserve">
|
||||
<value>MinGW (C:\ -> C:/) !!! !!</value>
|
||||
<value>MinGW (C:\ 🡒 C:/) !!! !!</value>
|
||||
<comment>{Locked="MinGW","C:\","C:/"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_Delete_Orphaned.Header" xml:space="preserve">
|
||||
@@ -2748,4 +2748,12 @@
|
||||
<value>Тÿρě ţθ ƒíŀŧēŗ īçōйš !!! !!!</value>
|
||||
<comment>Placeholder text for a text box to filter and select an icon.</comment>
|
||||
</data>
|
||||
</root>
|
||||
<data name="Profile_DragDropDelimiter.Header" xml:space="preserve">
|
||||
<value>Đґâġ ąńð δŗορ ďèŀιмïţ℮я !!! !!! </value>
|
||||
<comment>Header for a control to set the delimiter used when dragging multiple files into the terminal.</comment>
|
||||
</data>
|
||||
<data name="Profile_DragDropDelimiter.HelpText" xml:space="preserve">
|
||||
<value>Тĥїś ťэхť ẃĭŀł вё îⁿŝέŗŧеď вēťщ℮ěπ τĥę ρªτħѕ óƒ мџĺţīрℓé ƒĭļèś đяǿρрεδ ιйţθ ţħê ţèřмĭлªŀ. !!! !!! !!! !!! !!! !!! !!! !!! !!!</value>
|
||||
<comment>A description for what the "drag drop delimiter" setting does.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2610,19 +2610,19 @@
|
||||
<comment>An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleWsl.Content" xml:space="preserve">
|
||||
<value>WSL (C:\ -> /mnt/c) !!! !!!</value>
|
||||
<value>WSL (C:\ 🡒 /mnt/c) !!! !!!</value>
|
||||
<comment>{Locked="WSL","C:\","/mnt/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleCygwin.Content" xml:space="preserve">
|
||||
<value>Cygwin (C:\ -> /cygdrive/c) !!! !!! !!</value>
|
||||
<value>Cygwin (C:\ 🡒 /cygdrive/c) !!! !!! !!</value>
|
||||
<comment>{Locked="Cygwin","C:\","/cygdrive/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMsys2.Content" xml:space="preserve">
|
||||
<value>MSYS2 (C:\ -> /c) !!! !!</value>
|
||||
<value>MSYS2 (C:\ 🡒 /c) !!! !!</value>
|
||||
<comment>{Locked="MSYS2","C:\","/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMinGW.Content" xml:space="preserve">
|
||||
<value>MinGW (C:\ -> C:/) !!! !!</value>
|
||||
<value>MinGW (C:\ 🡒 C:/) !!! !!</value>
|
||||
<comment>{Locked="MinGW","C:\","C:/"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_Delete_Orphaned.Header" xml:space="preserve">
|
||||
@@ -2748,4 +2748,12 @@
|
||||
<value>Тÿρě ţθ ƒíŀŧēŗ īçōйš !!! !!!</value>
|
||||
<comment>Placeholder text for a text box to filter and select an icon.</comment>
|
||||
</data>
|
||||
</root>
|
||||
<data name="Profile_DragDropDelimiter.Header" xml:space="preserve">
|
||||
<value>Đґâġ ąńð δŗορ ďèŀιмïţ℮я !!! !!! </value>
|
||||
<comment>Header for a control to set the delimiter used when dragging multiple files into the terminal.</comment>
|
||||
</data>
|
||||
<data name="Profile_DragDropDelimiter.HelpText" xml:space="preserve">
|
||||
<value>Тĥїś ťэхť ẃĭŀł вё îⁿŝέŗŧеď вēťщ℮ěπ τĥę ρªτħѕ óƒ мџĺţīрℓé ƒĭļèś đяǿρрεδ ιйţθ ţħê ţèřмĭлªŀ. !!! !!! !!! !!! !!! !!! !!! !!! !!!</value>
|
||||
<comment>A description for what the "drag drop delimiter" setting does.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2606,19 +2606,19 @@
|
||||
<comment>An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleWsl.Content" xml:space="preserve">
|
||||
<value>WSL (C:\ -> /mnt/c)</value>
|
||||
<value>WSL (C:\ 🡒 /mnt/c)</value>
|
||||
<comment>{Locked="WSL","C:\","/mnt/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleCygwin.Content" xml:space="preserve">
|
||||
<value>Cygwin (C:\ -> /cygdrive/c)</value>
|
||||
<value>Cygwin (C:\ 🡒 /cygdrive/c)</value>
|
||||
<comment>{Locked="Cygwin","C:\","/cygdrive/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMsys2.Content" xml:space="preserve">
|
||||
<value>MSYS2 (C:\ -> /c)</value>
|
||||
<value>MSYS2 (C:\ 🡒 /c)</value>
|
||||
<comment>{Locked="MSYS2","C:\","/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMinGW.Content" xml:space="preserve">
|
||||
<value>MinGW (C:\ -> C:/)</value>
|
||||
<value>MinGW (C:\ 🡒 C:/)</value>
|
||||
<comment>{Locked="MinGW","C:\","C:/"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_Delete_Orphaned.Header" xml:space="preserve">
|
||||
@@ -2744,4 +2744,12 @@
|
||||
<value>Введите текст для фильтрации значков</value>
|
||||
<comment>Placeholder text for a text box to filter and select an icon.</comment>
|
||||
</data>
|
||||
<data name="Profile_DragDropDelimiter.Header" xml:space="preserve">
|
||||
<value>Перетащите разделитель</value>
|
||||
<comment>Header for a control to set the delimiter used when dragging multiple files into the terminal.</comment>
|
||||
</data>
|
||||
<data name="Profile_DragDropDelimiter.HelpText" xml:space="preserve">
|
||||
<value>Этот текст будет вставлен между путями нескольких файлов, перетащенных в терминал.</value>
|
||||
<comment>A description for what the "drag drop delimiter" setting does.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -2606,19 +2606,19 @@
|
||||
<comment>An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleWsl.Content" xml:space="preserve">
|
||||
<value>WSL (C:\ -> /mnt/c)</value>
|
||||
<value>WSL (C:\ 🡒 /mnt/c)</value>
|
||||
<comment>{Locked="WSL","C:\","/mnt/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleCygwin.Content" xml:space="preserve">
|
||||
<value>Cygwin (C:\ -> /cygdrive/c)</value>
|
||||
<value>Cygwin (C:\ 🡒 /cygdrive/c)</value>
|
||||
<comment>{Locked="Cygwin","C:\","/cygdrive/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMsys2.Content" xml:space="preserve">
|
||||
<value>MSYS2 (C:\ -> /c)</value>
|
||||
<value>MSYS2 (C:\ 🡒 /c)</value>
|
||||
<comment>{Locked="MSYS2","C:\","/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMinGW.Content" xml:space="preserve">
|
||||
<value>MinGW (C:\ -> C:/)</value>
|
||||
<value>MinGW (C:\ 🡒 C:/)</value>
|
||||
<comment>{Locked="MinGW","C:\","C:/"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_Delete_Orphaned.Header" xml:space="preserve">
|
||||
@@ -2744,4 +2744,12 @@
|
||||
<value>键入以筛选图标</value>
|
||||
<comment>Placeholder text for a text box to filter and select an icon.</comment>
|
||||
</data>
|
||||
<data name="Profile_DragDropDelimiter.Header" xml:space="preserve">
|
||||
<value>拖放分隔符</value>
|
||||
<comment>Header for a control to set the delimiter used when dragging multiple files into the terminal.</comment>
|
||||
</data>
|
||||
<data name="Profile_DragDropDelimiter.HelpText" xml:space="preserve">
|
||||
<value>此文本将在放置到终端的多个文件的路径之间插入。</value>
|
||||
<comment>A description for what the "drag drop delimiter" setting does.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -2606,19 +2606,19 @@
|
||||
<comment>An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleWsl.Content" xml:space="preserve">
|
||||
<value>WSL (C:\ -> /mnt/c)</value>
|
||||
<value>WSL (C:\ 🡒 /mnt/c)</value>
|
||||
<comment>{Locked="WSL","C:\","/mnt/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleCygwin.Content" xml:space="preserve">
|
||||
<value>Cygwin (C:\ -> /cygdrive/c)</value>
|
||||
<value>Cygwin (C:\ 🡒 /cygdrive/c)</value>
|
||||
<comment>{Locked="Cygwin","C:\","/cygdrive/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMsys2.Content" xml:space="preserve">
|
||||
<value>MSYS2 (C:\ -> /c)</value>
|
||||
<value>MSYS2 (C:\ 🡒 /c)</value>
|
||||
<comment>{Locked="MSYS2","C:\","/c"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_PathTranslationStyleMinGW.Content" xml:space="preserve">
|
||||
<value>MinGW (C:\ -> C:/)</value>
|
||||
<value>MinGW (C:\ 🡒 C:/)</value>
|
||||
<comment>{Locked="MinGW","C:\","C:/"} An option to choose from for the "path translation" setting.</comment>
|
||||
</data>
|
||||
<data name="Profile_Delete_Orphaned.Header" xml:space="preserve">
|
||||
@@ -2744,4 +2744,12 @@
|
||||
<value>輸入以篩選圖示</value>
|
||||
<comment>Placeholder text for a text box to filter and select an icon.</comment>
|
||||
</data>
|
||||
<data name="Profile_DragDropDelimiter.Header" xml:space="preserve">
|
||||
<value>拖放分隔符號</value>
|
||||
<comment>Header for a control to set the delimiter used when dragging multiple files into the terminal.</comment>
|
||||
</data>
|
||||
<data name="Profile_DragDropDelimiter.HelpText" xml:space="preserve">
|
||||
<value>這些文字會插入多個丟入終端機的檔案路徑之間。</value>
|
||||
<comment>A description for what the "drag drop delimiter" setting does.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -113,6 +113,7 @@ Model::CascadiaSettings CascadiaSettings::Copy() const
|
||||
settings->_globals = _globals->Copy();
|
||||
settings->_allProfiles = winrt::single_threaded_observable_vector(std::move(allProfiles));
|
||||
settings->_activeProfiles = winrt::single_threaded_observable_vector(std::move(activeProfiles));
|
||||
settings->_baseWindowSettings = _baseWindowSettings->Copy();
|
||||
|
||||
// extension packages don't need a deep clone
|
||||
// because they're fully immutable. We can just copy the reference over instead.
|
||||
@@ -220,6 +221,37 @@ Model::Profile CascadiaSettings::ProfileDefaults() const
|
||||
return *_baseLayerProfile;
|
||||
}
|
||||
|
||||
Model::WindowSettings CascadiaSettings::WindowSettingsDefaults() const
|
||||
{
|
||||
return *_baseWindowSettings;
|
||||
}
|
||||
|
||||
Model::WindowSettings CascadiaSettings::WindowSettings(const winrt::hstring& windowName) const
|
||||
{
|
||||
if (const auto& forName = _windows.TryLookup(windowName))
|
||||
{
|
||||
return forName;
|
||||
}
|
||||
else if (windowName == L"_quake")
|
||||
{
|
||||
const auto& quakeSettings{ winrt::make_self<implementation::WindowSettings>() };
|
||||
quakeSettings->AddLeastImportantParent(_baseWindowSettings);
|
||||
_resolveDefaultProfileForWindow(*quakeSettings, _allProfiles.GetAt(0).Guid());
|
||||
quakeSettings->InitializeForQuakeMode();
|
||||
|
||||
return *quakeSettings;
|
||||
}
|
||||
else
|
||||
{
|
||||
return *_baseWindowSettings;
|
||||
}
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::Collections::IMap<winrt::hstring, Model::WindowSettings> CascadiaSettings::AllWindowSettings() const noexcept
|
||||
{
|
||||
return _windows;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Create a new profile based off the default profile settings.
|
||||
// Arguments:
|
||||
@@ -709,7 +741,7 @@ static bool _validateNTMEntries(const IVector<Model::NewTabMenuEntry>& entries)
|
||||
|
||||
void CascadiaSettings::_validateRegexes()
|
||||
{
|
||||
if (!_validateNTMEntries(_globals->NewTabMenu()))
|
||||
if (!_validateNTMEntries(_baseWindowSettings->NewTabMenu()))
|
||||
{
|
||||
_warnings.Append(SettingsLoadWarnings::InvalidRegex);
|
||||
}
|
||||
@@ -731,7 +763,9 @@ void CascadiaSettings::_validateRegexes()
|
||||
// and attempt to look the profile up by name instead.
|
||||
// Return Value:
|
||||
// - the GUID of the profile corresponding to this combination of index and NewTerminalArgs
|
||||
Model::Profile CascadiaSettings::GetProfileForArgs(const Model::NewTerminalArgs& newTerminalArgs) const
|
||||
Model::Profile CascadiaSettings::GetProfileForArgs(
|
||||
const Model::NewTerminalArgs& newTerminalArgs,
|
||||
const Model::WindowSettings& currentWindowSettings) const
|
||||
{
|
||||
if (newTerminalArgs)
|
||||
{
|
||||
@@ -775,7 +809,7 @@ Model::Profile CascadiaSettings::GetProfileForArgs(const Model::NewTerminalArgs&
|
||||
// Case 2 above could be the result of a "nt" or "sp" invocation that doesn't specify anything.
|
||||
// TODO GH#10952: Detect the profile based on the commandline (add matching support)
|
||||
return (!newTerminalArgs || newTerminalArgs.Commandline().empty()) ?
|
||||
FindProfile(GlobalSettings().DefaultProfile()) :
|
||||
FindProfile(currentWindowSettings.DefaultProfile()) :
|
||||
ProfileDefaults();
|
||||
}
|
||||
|
||||
@@ -1235,10 +1269,10 @@ void CascadiaSettings::_validateThemeExists()
|
||||
auto newTheme = winrt::make_self<Theme>();
|
||||
newTheme->Name(L"system");
|
||||
_globals->AddTheme(*newTheme);
|
||||
_globals->Theme(Model::ThemePair{ L"system" });
|
||||
_baseWindowSettings->Theme(Model::ThemePair{ L"system" });
|
||||
}
|
||||
|
||||
const auto& theme{ _globals->Theme() };
|
||||
const auto& theme{ _baseWindowSettings->Theme() };
|
||||
if (theme.DarkName() == theme.LightName())
|
||||
{
|
||||
// Only one theme. We'll treat it as such.
|
||||
@@ -1246,7 +1280,7 @@ void CascadiaSettings::_validateThemeExists()
|
||||
{
|
||||
_warnings.Append(SettingsLoadWarnings::UnknownTheme);
|
||||
// safely fall back to system as the theme.
|
||||
_globals->Theme(*winrt::make_self<ThemePair>(L"system"));
|
||||
_baseWindowSettings->Theme(*winrt::make_self<ThemePair>(L"system"));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -69,8 +69,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
{
|
||||
winrt::com_ptr<implementation::GlobalAppSettings> globals;
|
||||
winrt::com_ptr<implementation::Profile> baseLayerProfile;
|
||||
winrt::com_ptr<implementation::WindowSettings> baseWindowSettings;
|
||||
std::vector<winrt::com_ptr<implementation::Profile>> profiles;
|
||||
std::unordered_map<winrt::guid, winrt::com_ptr<implementation::Profile>> profilesByGuid;
|
||||
std::unordered_map<winrt::hstring, winrt::com_ptr<implementation::WindowSettings>> windowsByName;
|
||||
std::unordered_map<winrt::hstring, winrt::com_ptr<implementation::ColorScheme>> colorSchemes;
|
||||
std::unordered_map<winrt::hstring, winrt::hstring> colorSchemeRemappings;
|
||||
bool fixupsAppliedDuringLoad{ false };
|
||||
@@ -111,6 +113,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
const Json::Value& profileDefaults;
|
||||
const Json::Value& profilesList;
|
||||
const Json::Value& themes;
|
||||
const Json::Value& windowDefaults;
|
||||
const Json::Value& windowsList;
|
||||
};
|
||||
struct ParseFragmentMetadata
|
||||
{
|
||||
@@ -163,6 +167,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
winrt::hstring Hash() const noexcept;
|
||||
Model::CascadiaSettings Copy() const;
|
||||
Model::GlobalAppSettings GlobalSettings() const;
|
||||
|
||||
Model::WindowSettings WindowSettingsDefaults() const;
|
||||
Model::WindowSettings WindowSettings(const winrt::hstring& windowName) const;
|
||||
Windows::Foundation::Collections::IMap<winrt::hstring, Model::WindowSettings> AllWindowSettings() const noexcept;
|
||||
|
||||
winrt::Windows::Foundation::Collections::IObservableVector<Model::Profile> AllProfiles() const noexcept;
|
||||
winrt::Windows::Foundation::Collections::IObservableVector<Model::Profile> ActiveProfiles() const noexcept;
|
||||
Model::ActionMap ActionMap() const noexcept;
|
||||
@@ -175,7 +184,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
Model::Profile CreateNewProfile();
|
||||
Model::Profile FindProfile(const winrt::guid& guid) const noexcept;
|
||||
void UpdateColorSchemeReferences(const winrt::hstring& oldName, const winrt::hstring& newName);
|
||||
Model::Profile GetProfileForArgs(const Model::NewTerminalArgs& newTerminalArgs) const;
|
||||
Model::Profile GetProfileForArgs(const Model::NewTerminalArgs& newTerminalArgs, const Model::WindowSettings& currentWindowSettings) const;
|
||||
Model::Profile GetProfileByName(const winrt::hstring& name) const;
|
||||
Model::Profile GetProfileByIndex(uint32_t index) const;
|
||||
Model::Profile DuplicateProfile(const Model::Profile& source);
|
||||
@@ -209,7 +218,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
void _writeSettingsToDisk(std::string_view contents);
|
||||
|
||||
void _resolveDefaultProfile() const;
|
||||
bool _resolveDefaultProfileForWindow(const Model::WindowSettings& window,
|
||||
const winrt::guid firstProfileGuid) const;
|
||||
void _resolveNewTabMenuProfiles() const;
|
||||
void _resolveNewTabMenuProfilesForWindow(const Model::WindowSettings& window) const;
|
||||
void _resolveNewTabMenuProfilesSet(const winrt::Windows::Foundation::Collections::IVector<Model::NewTabMenuEntry> entries, winrt::Windows::Foundation::Collections::IMap<int, Model::Profile>& remainingProfiles, Model::RemainingProfilesEntry& remainingProfilesEntry) const;
|
||||
|
||||
void _validateSettings();
|
||||
@@ -228,6 +240,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
// user settings
|
||||
winrt::hstring _hash;
|
||||
winrt::com_ptr<implementation::GlobalAppSettings> _globals = winrt::make_self<implementation::GlobalAppSettings>();
|
||||
|
||||
winrt::com_ptr<implementation::WindowSettings> _baseWindowSettings = winrt::make_self<implementation::WindowSettings>();
|
||||
Windows::Foundation::Collections::IMap<winrt::hstring, Model::WindowSettings> _windows{ winrt::single_threaded_map<winrt::hstring, Model::WindowSettings>() };
|
||||
|
||||
winrt::com_ptr<implementation::Profile> _baseLayerProfile = winrt::make_self<implementation::Profile>();
|
||||
winrt::Windows::Foundation::Collections::IObservableVector<Model::Profile> _allProfiles = winrt::single_threaded_observable_vector<Model::Profile>();
|
||||
winrt::Windows::Foundation::Collections::IObservableVector<Model::Profile> _activeProfiles = winrt::single_threaded_observable_vector<Model::Profile>();
|
||||
|
||||
@@ -36,7 +36,9 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
|
||||
String Hash { get; };
|
||||
|
||||
GlobalAppSettings GlobalSettings { get; };
|
||||
GlobalAppSettings GlobalSettings();
|
||||
WindowSettings WindowSettings(String windowName);
|
||||
WindowSettings WindowSettingsDefaults();
|
||||
|
||||
Profile ProfileDefaults { get; };
|
||||
|
||||
@@ -56,7 +58,7 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
Profile FindProfile(Guid profileGuid);
|
||||
void UpdateColorSchemeReferences(String oldName, String newName);
|
||||
|
||||
Profile GetProfileForArgs(NewTerminalArgs newTerminalArgs);
|
||||
Profile GetProfileForArgs(NewTerminalArgs newTerminalArgs, WindowSettings currentWindowSettings);
|
||||
|
||||
static Boolean IsDefaultTerminalAvailable { get; };
|
||||
static Boolean IsDefaultTerminalSet { get; };
|
||||
|
||||
@@ -39,6 +39,7 @@ static constexpr std::string_view DefaultSettingsKey{ "defaults" };
|
||||
static constexpr std::string_view ProfilesListKey{ "list" };
|
||||
static constexpr std::string_view SchemesKey{ "schemes" };
|
||||
static constexpr std::string_view ThemesKey{ "themes" };
|
||||
static constexpr std::string_view WindowsListKey{ "windows" };
|
||||
|
||||
constexpr std::wstring_view systemThemeName{ L"system" };
|
||||
constexpr std::wstring_view darkThemeName{ L"dark" };
|
||||
@@ -103,9 +104,11 @@ void ParsedSettings::clear()
|
||||
{
|
||||
globals = {};
|
||||
baseLayerProfile = {};
|
||||
baseWindowSettings = {};
|
||||
profiles.clear();
|
||||
profilesByGuid.clear();
|
||||
colorSchemes.clear();
|
||||
windowsByName.clear();
|
||||
fixupsAppliedDuringLoad = false;
|
||||
themesChangeLog.clear();
|
||||
}
|
||||
@@ -291,7 +294,7 @@ void SettingsLoader::ApplyRuntimeInitialSettings()
|
||||
}
|
||||
}
|
||||
|
||||
userSettings.globals->DefaultProfile(guid);
|
||||
userSettings.baseWindowSettings->DefaultProfile(guid);
|
||||
}
|
||||
|
||||
// 2.
|
||||
@@ -470,6 +473,7 @@ void SettingsLoader::FinalizeLayering()
|
||||
|
||||
// Layer default globals -> user globals
|
||||
userSettings.globals->AddLeastImportantParent(inboxSettings.globals);
|
||||
userSettings.baseWindowSettings->AddLeastImportantParent(inboxSettings.baseWindowSettings);
|
||||
|
||||
// Actions are currently global, so if we want to conditionally light up a bunch of
|
||||
// actions, this is the time to do it.
|
||||
@@ -500,6 +504,13 @@ void SettingsLoader::FinalizeLayering()
|
||||
profile->Hidden(profile->Hidden());
|
||||
}
|
||||
}
|
||||
|
||||
// Layer user window settings defaults -> user named windows
|
||||
for (const auto& [_, window] : userSettings.windowsByName)
|
||||
{
|
||||
window->AddMostImportantParent(userSettings.baseWindowSettings);
|
||||
window->_FinalizeInheritance();
|
||||
}
|
||||
}
|
||||
|
||||
// Let's say a user doesn't know that they need to write `"hidden": true` in
|
||||
@@ -559,7 +570,7 @@ bool SettingsLoader::AddDynamicProfileFolders()
|
||||
folderEntry->RawEntries(winrt::single_threaded_vector<Model::NewTabMenuEntry>({ *matchProfilesEntry }));
|
||||
|
||||
// NewTabMenu is guaranteed to exist by FixupUserSettings, which runs before this fixup.
|
||||
userSettings.globals->NewTabMenu().Append(folderEntry.as<Model::NewTabMenuEntry>());
|
||||
userSettings.baseWindowSettings->NewTabMenu().Append(folderEntry.as<Model::NewTabMenuEntry>());
|
||||
state->SSHFolderGenerated(true);
|
||||
return true;
|
||||
}
|
||||
@@ -693,9 +704,9 @@ bool SettingsLoader::FixupUserSettings()
|
||||
// Ensure that the user always has a newTabMenu. We used to do this last, after
|
||||
// resolving all of the new tab menu entries, but there was no conceivable reason
|
||||
// that it should happen so late.
|
||||
if (!userSettings.globals->HasNewTabMenu())
|
||||
if (!userSettings.baseWindowSettings->HasNewTabMenu())
|
||||
{
|
||||
userSettings.globals->NewTabMenu(winrt::single_threaded_vector<Model::NewTabMenuEntry>({ Model::RemainingProfilesEntry{} }));
|
||||
userSettings.baseWindowSettings->NewTabMenu(winrt::single_threaded_vector<Model::NewTabMenuEntry>({ Model::RemainingProfilesEntry{} }));
|
||||
// This one does not need to be written back to the settings file immediately, it can wait until we write one for another reason.
|
||||
}
|
||||
|
||||
@@ -818,6 +829,18 @@ void SettingsLoader::_parse(const OriginTag origin, const winrt::hstring& source
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
settings.baseWindowSettings = WindowSettings::FromJson(json.root);
|
||||
|
||||
for (const auto& windowJson : json.windowsList)
|
||||
{
|
||||
if (auto window = WindowSettings::FromJson(windowJson))
|
||||
{
|
||||
settings.windowsByName.insert({ window->Name(), window });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
for (const auto& themeJson : json.themes)
|
||||
{
|
||||
@@ -1014,10 +1037,15 @@ SettingsLoader::JsonSettings SettingsLoader::_parseJson(const std::string_view&
|
||||
auto root = content.empty() ? Json::Value{ Json::ValueType::objectValue } : _parseJSON(content);
|
||||
const auto& colorSchemes = _getJSONValue(root, SchemesKey);
|
||||
const auto& themes = _getJSONValue(root, ThemesKey);
|
||||
|
||||
const auto& profilesObject = _getJSONValue(root, ProfilesKey);
|
||||
const auto& profileDefaults = _getJSONValue(profilesObject, DefaultSettingsKey);
|
||||
const auto& profilesList = profilesObject.isArray() ? profilesObject : _getJSONValue(profilesObject, ProfilesListKey);
|
||||
return JsonSettings{ std::move(root), colorSchemes, profileDefaults, profilesList, themes };
|
||||
|
||||
const auto& windowDefaults = content.empty() ? Json::Value{ Json::ValueType::objectValue } : _parseJSON(content);
|
||||
const auto& windowsList = _getJSONValue(root, WindowsListKey);
|
||||
|
||||
return JsonSettings{ std::move(root), colorSchemes, profileDefaults, profilesList, themes, windowDefaults, windowsList };
|
||||
}
|
||||
|
||||
// Just a common helper function between _parse and _parseFragment.
|
||||
@@ -1316,8 +1344,8 @@ void CascadiaSettings::_researchOnLoad()
|
||||
{
|
||||
// ----------------------------- RE: Themes ----------------------------
|
||||
const auto numThemes = GlobalSettings().Themes().Size();
|
||||
const auto themeInUse = GlobalSettings().CurrentTheme().Name();
|
||||
const auto changedTheme = GlobalSettings().HasTheme();
|
||||
const auto themeInUse = GlobalSettings().CurrentTheme(*_baseWindowSettings).Name();
|
||||
const auto changedTheme = _baseWindowSettings->HasTheme();
|
||||
|
||||
// system: 0
|
||||
// light: 1
|
||||
@@ -1478,6 +1506,12 @@ CascadiaSettings::CascadiaSettings(SettingsLoader&& loader) :
|
||||
_warnings = winrt::single_threaded_vector(std::move(warnings));
|
||||
_themesChangeLog = std::move(loader.userSettings.themesChangeLog);
|
||||
|
||||
_baseWindowSettings = loader.userSettings.baseWindowSettings;
|
||||
for (const auto& [name, window] : loader.userSettings.windowsByName)
|
||||
{
|
||||
_windows.Insert(name, *window);
|
||||
}
|
||||
|
||||
_resolveDefaultProfile();
|
||||
_resolveNewTabMenuProfiles();
|
||||
_validateSettings();
|
||||
@@ -1643,6 +1677,15 @@ Json::Value CascadiaSettings::ToJson() const
|
||||
{
|
||||
// top-level json object
|
||||
auto json{ _globals->ToJson() };
|
||||
|
||||
// Merge the base window settings into the root JSON.
|
||||
// (Window-level settings are written to the top level, just like globals.)
|
||||
const auto windowJson = _baseWindowSettings->ToJson();
|
||||
for (const auto& key : windowJson.getMemberNames())
|
||||
{
|
||||
json[key] = windowJson[key];
|
||||
}
|
||||
|
||||
json["$help"] = "https://aka.ms/terminal-documentation";
|
||||
json["$schema"] =
|
||||
#if defined(WT_BRANDING_RELEASE)
|
||||
@@ -1697,27 +1740,63 @@ Json::Value CascadiaSettings::ToJson() const
|
||||
}
|
||||
json[JsonKey(ThemesKey)] = themes;
|
||||
|
||||
// Serialize named windows (if any)
|
||||
if (_windows.Size() > 0)
|
||||
{
|
||||
Json::Value windowsList{ Json::ValueType::arrayValue };
|
||||
for (const auto& [name, window] : _windows)
|
||||
{
|
||||
const auto windowImpl = winrt::get_self<implementation::WindowSettings>(window);
|
||||
auto windowJson = windowImpl->ToJson();
|
||||
windowJson["name"] = til::u16u8(name);
|
||||
windowsList.append(std::move(windowJson));
|
||||
}
|
||||
json[JsonKey(WindowsListKey)] = windowsList;
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Resolves the "defaultProfile", which can be a profile name, to a GUID
|
||||
// and stores it back to the globals.
|
||||
// and stores it back to the window settings.
|
||||
void CascadiaSettings::_resolveDefaultProfile() const
|
||||
{
|
||||
if (const auto unparsedDefaultProfile = _globals->UnparsedDefaultProfile(); !unparsedDefaultProfile.empty())
|
||||
const auto firstProfileGuid = _allProfiles.GetAt(0).Guid();
|
||||
|
||||
// Resolve for the base window settings first.
|
||||
_resolveDefaultProfileForWindow(*_baseWindowSettings, firstProfileGuid);
|
||||
|
||||
// Then resolve for each named window.
|
||||
for (const auto& [_, window] : _windows)
|
||||
{
|
||||
_resolveDefaultProfileForWindow(window, firstProfileGuid);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Resolves the "defaultProfile" for a single WindowSettings instance.
|
||||
// Returns:
|
||||
// - true if a warning was produced (missing default profile)
|
||||
bool CascadiaSettings::_resolveDefaultProfileForWindow(const Model::WindowSettings& window,
|
||||
const winrt::guid firstProfileGuid) const
|
||||
{
|
||||
const auto windowImpl = winrt::get_self<implementation::WindowSettings>(window);
|
||||
if (const auto unparsedDefaultProfile = windowImpl->UnparsedDefaultProfile(); !unparsedDefaultProfile.empty())
|
||||
{
|
||||
if (const auto profile = GetProfileByName(unparsedDefaultProfile))
|
||||
{
|
||||
_globals->DefaultProfile(profile.Guid());
|
||||
return;
|
||||
windowImpl->DefaultProfile(profile.Guid());
|
||||
return false;
|
||||
}
|
||||
|
||||
_warnings.Append(SettingsLoadWarnings::MissingDefaultProfile);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Use the first profile as the new default.
|
||||
GlobalSettings().DefaultProfile(_allProfiles.GetAt(0).Guid());
|
||||
windowImpl->DefaultProfile(firstProfileGuid);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -1729,6 +1808,22 @@ void CascadiaSettings::_resolveDefaultProfile() const
|
||||
// multiple of these entries are found.
|
||||
void CascadiaSettings::_resolveNewTabMenuProfiles() const
|
||||
{
|
||||
// Resolve for the base window settings first.
|
||||
_resolveNewTabMenuProfilesForWindow(*_baseWindowSettings);
|
||||
|
||||
// Then resolve for each named window.
|
||||
for (const auto& [_, window] : _windows)
|
||||
{
|
||||
_resolveNewTabMenuProfilesForWindow(window);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Resolves the new tab menu profile entries for a single WindowSettings instance.
|
||||
void CascadiaSettings::_resolveNewTabMenuProfilesForWindow(const Model::WindowSettings& window) const
|
||||
{
|
||||
const auto windowImpl = winrt::get_self<implementation::WindowSettings>(window);
|
||||
|
||||
Model::RemainingProfilesEntry remainingProfilesEntry = nullptr;
|
||||
|
||||
// The TerminalPage needs to know which profile has which profile ID. To prevent
|
||||
@@ -1741,16 +1836,11 @@ void CascadiaSettings::_resolveNewTabMenuProfiles() const
|
||||
remainingProfilesMap.emplace(profileIndex, _activeProfiles.GetAt(profileIndex));
|
||||
}
|
||||
|
||||
// We keep track of the "remaining profiles" - those that have not yet been resolved
|
||||
// in either a "profile" or "source" entry. They will possibly be assigned to a
|
||||
// "remainingProfiles" entry
|
||||
auto remainingProfiles = single_threaded_map(std::move(remainingProfilesMap));
|
||||
|
||||
// We call a recursive helper function to process the entries
|
||||
auto entries = _globals->NewTabMenu();
|
||||
auto entries = windowImpl->NewTabMenu();
|
||||
_resolveNewTabMenuProfilesSet(entries, remainingProfiles, remainingProfilesEntry);
|
||||
|
||||
// If a "remainingProfiles" entry has been found, assign to it the remaining profiles
|
||||
if (remainingProfilesEntry != nullptr)
|
||||
{
|
||||
remainingProfilesEntry.Profiles(remainingProfiles);
|
||||
|
||||
@@ -59,9 +59,6 @@ winrt::com_ptr<GlobalAppSettings> GlobalAppSettings::Copy() const
|
||||
{
|
||||
auto globals{ winrt::make_self<GlobalAppSettings>() };
|
||||
|
||||
globals->_UnparsedDefaultProfile = _UnparsedDefaultProfile;
|
||||
|
||||
globals->_defaultProfile = _defaultProfile;
|
||||
globals->_actionMap = _actionMap->Copy();
|
||||
globals->_keybindingsWarnings = _keybindingsWarnings;
|
||||
|
||||
@@ -86,14 +83,6 @@ winrt::com_ptr<GlobalAppSettings> GlobalAppSettings::Copy() const
|
||||
globals->_themes.Insert(kv.Key(), *themeImpl->Copy());
|
||||
}
|
||||
}
|
||||
if (_NewTabMenu)
|
||||
{
|
||||
globals->_NewTabMenu = winrt::single_threaded_vector<Model::NewTabMenuEntry>();
|
||||
for (const auto& entry : *_NewTabMenu)
|
||||
{
|
||||
globals->_NewTabMenu->Append(get_self<NewTabMenuEntry>(entry)->Copy());
|
||||
}
|
||||
}
|
||||
if (_DisabledProfileSources)
|
||||
{
|
||||
globals->_DisabledProfileSources = winrt::single_threaded_vector<hstring>();
|
||||
@@ -117,17 +106,6 @@ winrt::Windows::Foundation::Collections::IMapView<winrt::hstring, winrt::Microso
|
||||
|
||||
#pragma region DefaultProfile
|
||||
|
||||
void GlobalAppSettings::DefaultProfile(const winrt::guid& defaultProfile) noexcept
|
||||
{
|
||||
_defaultProfile = defaultProfile;
|
||||
_UnparsedDefaultProfile = Utils::GuidToString(defaultProfile);
|
||||
}
|
||||
|
||||
winrt::guid GlobalAppSettings::DefaultProfile() const
|
||||
{
|
||||
return _defaultProfile;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::ActionMap GlobalAppSettings::ActionMap() const noexcept
|
||||
@@ -150,17 +128,7 @@ winrt::com_ptr<GlobalAppSettings> GlobalAppSettings::FromJson(const Json::Value&
|
||||
|
||||
void GlobalAppSettings::LayerJson(const Json::Value& json, const OriginTag origin)
|
||||
{
|
||||
JsonUtils::GetValueForKey(json, DefaultProfileKey, _UnparsedDefaultProfile);
|
||||
|
||||
// GH#8076 - when adding enum values to this key, we also changed it from
|
||||
// "useTabSwitcher" to "tabSwitcherMode". Continue supporting
|
||||
// "useTabSwitcher", but prefer "tabSwitcherMode"
|
||||
_fixupsAppliedDuringLoad = JsonUtils::GetValueForKey(json, LegacyUseTabSwitcherModeKey, _TabSwitcherMode) || _fixupsAppliedDuringLoad;
|
||||
|
||||
_fixupsAppliedDuringLoad = JsonUtils::GetValueForKey(json, LegacyInputServiceWarningKey, _InputServiceWarning) || _fixupsAppliedDuringLoad;
|
||||
_fixupsAppliedDuringLoad = JsonUtils::GetValueForKey(json, LegacyWarnAboutLargePasteKey, _WarnAboutLargePaste) || _fixupsAppliedDuringLoad;
|
||||
_fixupsAppliedDuringLoad = JsonUtils::GetValueForKey(json, LegacyWarnAboutMultiLinePasteKey, _WarnAboutMultiLinePaste) || _fixupsAppliedDuringLoad;
|
||||
_fixupsAppliedDuringLoad = JsonUtils::GetValueForKey(json, LegacyConfirmCloseAllTabsKey, _ConfirmCloseAllTabs) || _fixupsAppliedDuringLoad;
|
||||
|
||||
#define GLOBAL_SETTINGS_LAYER_JSON(type, name, jsonKey, ...) \
|
||||
JsonUtils::GetValueForKey(json, jsonKey, _##name); \
|
||||
@@ -169,17 +137,6 @@ void GlobalAppSettings::LayerJson(const Json::Value& json, const OriginTag origi
|
||||
MTSM_GLOBAL_SETTINGS(GLOBAL_SETTINGS_LAYER_JSON)
|
||||
#undef GLOBAL_SETTINGS_LAYER_JSON
|
||||
|
||||
// GH#11975 We only want to allow sensible values and prevent crashes, so we are clamping those values
|
||||
// We only want to assign if the value did change through clamping,
|
||||
// otherwise we could end up setting defaults that get persisted
|
||||
if (this->HasInitialCols())
|
||||
{
|
||||
this->InitialCols(std::clamp(this->InitialCols(), 1, 999));
|
||||
}
|
||||
if (this->HasInitialRows())
|
||||
{
|
||||
this->InitialRows(std::clamp(this->InitialRows(), 1, 999));
|
||||
}
|
||||
LayerActionsFrom(json, origin, true);
|
||||
|
||||
// No need to update _fixupsAppliedDuringLoad here.
|
||||
@@ -203,20 +160,11 @@ void GlobalAppSettings::LayerJson(const Json::Value& json, const OriginTag origi
|
||||
_fixupsAppliedDuringLoad |= firstWindowPreferenceValue == LegacyPersistedWindowLayout.data();
|
||||
}
|
||||
|
||||
// Remove settings included in userDefaults
|
||||
static constexpr std::array<std::pair<std::string_view, std::string_view>, 2> userDefaultSettings{ { { "copyOnSelect", "false" },
|
||||
{ "copyFormatting", "false" } } };
|
||||
for (const auto& [setting, val] : userDefaultSettings)
|
||||
{
|
||||
if (const auto settingJson{ json.find(&*setting.cbegin(), (&*setting.cbegin()) + setting.size()) })
|
||||
{
|
||||
if (settingJson->asString() == val)
|
||||
{
|
||||
// false positive!
|
||||
_changeLog.erase(std::string{ setting });
|
||||
}
|
||||
}
|
||||
}
|
||||
// NOTE: "copyOnSelect" and "copyFormatting" used to be global settings.
|
||||
// They were moved to WindowSettings and are now handled by
|
||||
// WindowSettings::LayerJson. No cleanup is needed here because
|
||||
// MTSM_GLOBAL_SETTINGS no longer includes them, so they never enter
|
||||
// the changeLog in the first place.
|
||||
}
|
||||
|
||||
void GlobalAppSettings::LayerActionsFrom(const Json::Value& json, const OriginTag origin, const bool withKeybindings)
|
||||
@@ -332,8 +280,6 @@ Json::Value GlobalAppSettings::ToJson()
|
||||
|
||||
Json::Value json{ Json::ValueType::objectValue };
|
||||
|
||||
JsonUtils::SetValueForKey(json, DefaultProfileKey, _UnparsedDefaultProfile);
|
||||
|
||||
#define GLOBAL_SETTINGS_TO_JSON(type, name, jsonKey, ...) \
|
||||
JsonUtils::SetValueForKey(json, jsonKey, _##name);
|
||||
MTSM_GLOBAL_SETTINGS(GLOBAL_SETTINGS_TO_JSON)
|
||||
@@ -350,19 +296,20 @@ bool GlobalAppSettings::FixupsAppliedDuringLoad()
|
||||
return _fixupsAppliedDuringLoad || _actionMap->FixupsAppliedDuringLoad();
|
||||
}
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::Theme GlobalAppSettings::CurrentTheme() noexcept
|
||||
winrt::Microsoft::Terminal::Settings::Model::Theme GlobalAppSettings::CurrentTheme(const Model::WindowSettings& window) noexcept
|
||||
{
|
||||
auto requestedTheme = Model::Theme::IsSystemInDarkTheme() ?
|
||||
winrt::Windows::UI::Xaml::ElementTheme::Dark :
|
||||
winrt::Windows::UI::Xaml::ElementTheme::Light;
|
||||
|
||||
const auto& themePair{ window.Theme() };
|
||||
switch (requestedTheme)
|
||||
{
|
||||
case winrt::Windows::UI::Xaml::ElementTheme::Light:
|
||||
return _themes.TryLookup(Theme().LightName());
|
||||
return _themes.TryLookup(themePair.LightName());
|
||||
|
||||
case winrt::Windows::UI::Xaml::ElementTheme::Dark:
|
||||
return _themes.TryLookup(Theme().DarkName());
|
||||
return _themes.TryLookup(themePair.DarkName());
|
||||
|
||||
case winrt::Windows::UI::Xaml::ElementTheme::Default:
|
||||
default:
|
||||
@@ -394,16 +341,6 @@ bool GlobalAppSettings::ShouldUsePersistedLayout() const
|
||||
void GlobalAppSettings::ResolveMediaResources(const Model::MediaResourceResolver& resolver)
|
||||
{
|
||||
_actionMap->ResolveMediaResourcesWithBasePath(SourceBasePath, resolver);
|
||||
if (_NewTabMenu)
|
||||
{
|
||||
for (const auto& entry : *_NewTabMenu)
|
||||
{
|
||||
if (const auto resolvable{ entry.try_as<IPathlessMediaResourceContainer>() })
|
||||
{
|
||||
resolvable->ResolveMediaResourcesWithBasePath(SourceBasePath, resolver);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto& parent : _parents)
|
||||
{
|
||||
parent->ResolveMediaResources(resolver);
|
||||
@@ -412,115 +349,20 @@ void GlobalAppSettings::ResolveMediaResources(const Model::MediaResourceResolver
|
||||
|
||||
void GlobalAppSettings::_logSettingSet(const std::string_view& setting)
|
||||
{
|
||||
if (setting == "theme")
|
||||
{
|
||||
if (_Theme.has_value())
|
||||
{
|
||||
// ThemePair always has a Dark/Light value,
|
||||
// so we need to check if they were explicitly set
|
||||
if (_Theme->DarkName() == _Theme->LightName())
|
||||
{
|
||||
_changeLog.emplace(setting);
|
||||
}
|
||||
else
|
||||
{
|
||||
_changeLog.emplace(fmt::format(FMT_COMPILE("{}.{}"), setting, "dark"));
|
||||
_changeLog.emplace(fmt::format(FMT_COMPILE("{}.{}"), setting, "light"));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (setting == "newTabMenu")
|
||||
{
|
||||
if (_NewTabMenu.has_value())
|
||||
{
|
||||
for (const auto& entry : *_NewTabMenu)
|
||||
{
|
||||
std::string entryType;
|
||||
switch (entry.Type())
|
||||
{
|
||||
case NewTabMenuEntryType::Profile:
|
||||
entryType = "profile";
|
||||
break;
|
||||
case NewTabMenuEntryType::Separator:
|
||||
entryType = "separator";
|
||||
break;
|
||||
case NewTabMenuEntryType::Folder:
|
||||
entryType = "folder";
|
||||
break;
|
||||
case NewTabMenuEntryType::RemainingProfiles:
|
||||
entryType = "remainingProfiles";
|
||||
break;
|
||||
case NewTabMenuEntryType::MatchProfiles:
|
||||
entryType = "matchProfiles";
|
||||
break;
|
||||
case NewTabMenuEntryType::Action:
|
||||
entryType = "action";
|
||||
break;
|
||||
case NewTabMenuEntryType::Invalid:
|
||||
// ignore invalid
|
||||
continue;
|
||||
}
|
||||
_changeLog.emplace(fmt::format(FMT_COMPILE("{}.{}"), setting, entryType));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_changeLog.emplace(setting);
|
||||
}
|
||||
_changeLog.emplace(setting);
|
||||
}
|
||||
|
||||
void GlobalAppSettings::UpdateCommandID(const Model::Command& cmd, winrt::hstring newID)
|
||||
{
|
||||
const auto oldID = cmd.ID();
|
||||
_actionMap->UpdateCommandID(cmd, newID);
|
||||
// newID might have been empty when this function was called, if so actionMap would have generated a new ID, use that
|
||||
newID = cmd.ID();
|
||||
if (_NewTabMenu)
|
||||
{
|
||||
// Recursive lambda function to look through all the new tab menu entries and update IDs accordingly
|
||||
std::function<void(const Model::NewTabMenuEntry&)> recursiveEntryIdUpdate;
|
||||
recursiveEntryIdUpdate = [&](const Model::NewTabMenuEntry& entry) {
|
||||
if (entry.Type() == NewTabMenuEntryType::Action)
|
||||
{
|
||||
if (const auto actionEntry{ entry.try_as<ActionEntry>() })
|
||||
{
|
||||
if (actionEntry.ActionId() == oldID)
|
||||
{
|
||||
actionEntry.ActionId(newID);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (entry.Type() == NewTabMenuEntryType::Folder)
|
||||
{
|
||||
if (const auto folderEntry{ entry.try_as<FolderEntry>() })
|
||||
{
|
||||
for (const auto& nestedEntry : folderEntry.RawEntries())
|
||||
{
|
||||
recursiveEntryIdUpdate(nestedEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (const auto& entry : *_NewTabMenu)
|
||||
{
|
||||
recursiveEntryIdUpdate(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GlobalAppSettings::_logSettingIfSet(const std::string_view& setting, const bool isSet)
|
||||
{
|
||||
if (isSet)
|
||||
{
|
||||
// Exclude some false positives from userDefaults.json
|
||||
const bool settingCopyFormattingToDefault = til::equals_insensitive_ascii(setting, "copyFormatting") && _CopyFormatting.has_value() && _CopyFormatting.value() == static_cast<Control::CopyFormat>(0);
|
||||
const bool settingNTMToDefault = til::equals_insensitive_ascii(setting, "newTabMenu") && _NewTabMenu.has_value() && _NewTabMenu->Size() == 1 && _NewTabMenu->GetAt(0).Type() == NewTabMenuEntryType::RemainingProfiles;
|
||||
if (!settingCopyFormattingToDefault && !settingNTMToDefault)
|
||||
{
|
||||
_logSettingSet(setting);
|
||||
}
|
||||
_logSettingSet(setting);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ Author(s):
|
||||
#include "Theme.h"
|
||||
#include "NewTabMenuEntry.h"
|
||||
#include "RemainingProfilesEntry.h"
|
||||
#include "WindowSettings.h"
|
||||
|
||||
// fwdecl unittest classes
|
||||
namespace SettingsModelUnitTests
|
||||
@@ -58,14 +59,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
|
||||
const std::vector<SettingsLoadWarnings>& KeybindingsWarnings() const;
|
||||
|
||||
// This DefaultProfile() setter is called by CascadiaSettings,
|
||||
// when it parses UnparsedDefaultProfile in _finalizeSettings().
|
||||
void DefaultProfile(const guid& defaultProfile) noexcept;
|
||||
guid DefaultProfile() const;
|
||||
|
||||
|
||||
Windows::Foundation::Collections::IMapView<hstring, Model::Theme> Themes() noexcept;
|
||||
void AddTheme(const Model::Theme& theme);
|
||||
Model::Theme CurrentTheme() noexcept;
|
||||
Model::Theme CurrentTheme(const Model::WindowSettings& window) noexcept;
|
||||
bool ShouldUsePersistedLayout() const;
|
||||
|
||||
void ExpandCommands(const Windows::Foundation::Collections::IVectorView<Model::Profile>& profiles,
|
||||
@@ -80,8 +78,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
|
||||
winrt::hstring SourceBasePath;
|
||||
|
||||
INHERITABLE_SETTING(Model::GlobalAppSettings, hstring, UnparsedDefaultProfile, L"");
|
||||
|
||||
#define GLOBAL_SETTINGS_INITIALIZE(type, name, jsonKey, ...) \
|
||||
INHERITABLE_SETTING_WITH_LOGGING(Model::GlobalAppSettings, type, name, jsonKey, ##__VA_ARGS__)
|
||||
MTSM_GLOBAL_SETTINGS(GLOBAL_SETTINGS_INITIALIZE)
|
||||
@@ -94,7 +90,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
static constexpr bool debugFeaturesDefault{ true };
|
||||
#endif
|
||||
|
||||
winrt::guid _defaultProfile{};
|
||||
bool _fixupsAppliedDuringLoad{ false };
|
||||
bool _legacyReloadEnvironmentVariables{ true };
|
||||
bool _legacyForceVTInput{ false };
|
||||
|
||||
@@ -50,63 +50,34 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
AfterCurrentTab,
|
||||
};
|
||||
|
||||
enum DockPosition
|
||||
{
|
||||
None,
|
||||
Top,
|
||||
Bottom,
|
||||
Left,
|
||||
Right
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass Docking
|
||||
{
|
||||
Docking();
|
||||
DockPosition Side { get; };
|
||||
Double Width { get; };
|
||||
Double Height { get; };
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass GlobalAppSettings {
|
||||
Guid DefaultProfile;
|
||||
|
||||
INHERITABLE_SETTING(String, UnparsedDefaultProfile);
|
||||
|
||||
INHERITABLE_SETTING(Int32, InitialRows);
|
||||
INHERITABLE_SETTING(Int32, InitialCols);
|
||||
INHERITABLE_SETTING(Boolean, AlwaysShowTabs);
|
||||
INHERITABLE_SETTING(Boolean, ShowTabsFullscreen);
|
||||
INHERITABLE_SETTING(NewTabPosition, NewTabPosition);
|
||||
INHERITABLE_SETTING(Boolean, ShowTitleInTitlebar);
|
||||
INHERITABLE_SETTING(Boolean, ConfirmCloseAllTabs);
|
||||
INHERITABLE_SETTING(String, Language);
|
||||
INHERITABLE_SETTING(Microsoft.UI.Xaml.Controls.TabViewWidthMode, TabWidthMode);
|
||||
INHERITABLE_SETTING(Boolean, UseAcrylicInTabRow);
|
||||
INHERITABLE_SETTING(Boolean, ShowTabsInTitlebar);
|
||||
INHERITABLE_SETTING(String, WordDelimiters);
|
||||
INHERITABLE_SETTING(Boolean, CopyOnSelect);
|
||||
INHERITABLE_SETTING(Boolean, InputServiceWarning);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.CopyFormat, CopyFormatting);
|
||||
INHERITABLE_SETTING(Boolean, WarnAboutLargePaste);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.WarnAboutMultiLinePaste, WarnAboutMultiLinePaste);
|
||||
INHERITABLE_SETTING(Boolean, TrimPaste);
|
||||
INHERITABLE_SETTING(LaunchPosition, InitialPosition);
|
||||
INHERITABLE_SETTING(Boolean, CenterOnLaunch);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.DefaultInputScope, DefaultInputScope);
|
||||
INHERITABLE_SETTING(FirstWindowPreference, FirstWindowPreference);
|
||||
INHERITABLE_SETTING(LaunchMode, LaunchMode);
|
||||
INHERITABLE_SETTING(Boolean, SnapToGridOnResize);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.GraphicsAPI, GraphicsAPI);
|
||||
INHERITABLE_SETTING(Boolean, DisablePartialInvalidation);
|
||||
INHERITABLE_SETTING(Boolean, SoftwareRendering);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.TextMeasurement, TextMeasurement);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.AmbiguousWidth, AmbiguousWidth);
|
||||
INHERITABLE_SETTING(Boolean, UseBackgroundImageForWindow);
|
||||
INHERITABLE_SETTING(Boolean, DebugFeaturesEnabled);
|
||||
INHERITABLE_SETTING(Boolean, AlwaysOnTop);
|
||||
INHERITABLE_SETTING(Boolean, AutoHideWindow);
|
||||
INHERITABLE_SETTING(TabSwitcherMode, TabSwitcherMode);
|
||||
INHERITABLE_SETTING(Boolean, DisableAnimations);
|
||||
INHERITABLE_SETTING(String, StartupActions);
|
||||
INHERITABLE_SETTING(Boolean, FocusFollowMouse);
|
||||
INHERITABLE_SETTING(Boolean, ScrollToZoom);
|
||||
INHERITABLE_SETTING(Boolean, ScrollToChangeOpacity);
|
||||
INHERITABLE_SETTING(WindowingMode, WindowingBehavior);
|
||||
INHERITABLE_SETTING(Boolean, TrimBlockSelection);
|
||||
INHERITABLE_SETTING(Boolean, DetectURLs);
|
||||
INHERITABLE_SETTING(Boolean, MinimizeToNotificationArea);
|
||||
INHERITABLE_SETTING(Boolean, AlwaysShowNotificationIcon);
|
||||
INHERITABLE_SETTING(IVector<String>, DisabledProfileSources);
|
||||
INHERITABLE_SETTING(Boolean, ShowAdminShield);
|
||||
INHERITABLE_SETTING(IVector<NewTabMenuEntry>, NewTabMenu);
|
||||
INHERITABLE_SETTING(Boolean, EnableColorSelection);
|
||||
INHERITABLE_SETTING(Boolean, EnableShellCompletionMenu);
|
||||
INHERITABLE_SETTING(Boolean, EnableUnfocusedAcrylic);
|
||||
INHERITABLE_SETTING(Boolean, AllowHeadless);
|
||||
INHERITABLE_SETTING(String, SearchWebDefaultQueryUrl);
|
||||
INHERITABLE_SETTING(Boolean, EnableColorSelection);
|
||||
|
||||
Windows.Foundation.Collections.IMapView<String, ColorScheme> ColorSchemes();
|
||||
void AddColorScheme(ColorScheme scheme);
|
||||
@@ -117,9 +88,62 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
|
||||
Windows.Foundation.Collections.IMapView<String, Theme> Themes();
|
||||
void AddTheme(Theme theme);
|
||||
INHERITABLE_SETTING(ThemePair, Theme);
|
||||
Theme CurrentTheme { get; };
|
||||
Theme CurrentTheme(WindowSettings window);
|
||||
|
||||
Boolean ShouldUsePersistedLayout();
|
||||
}
|
||||
|
||||
[default_interface] runtimeclass WindowSettings {
|
||||
|
||||
String Name { get; };
|
||||
|
||||
Guid DefaultProfile;
|
||||
INHERITABLE_SETTING(String, UnparsedDefaultProfile);
|
||||
|
||||
INHERITABLE_SETTING(Int32, InitialRows);
|
||||
INHERITABLE_SETTING(Int32, InitialCols);
|
||||
INHERITABLE_SETTING(Boolean, AlwaysShowTabs);
|
||||
INHERITABLE_SETTING(Boolean, ShowTabsFullscreen);
|
||||
INHERITABLE_SETTING(NewTabPosition, NewTabPosition);
|
||||
INHERITABLE_SETTING(Boolean, ShowTitleInTitlebar);
|
||||
INHERITABLE_SETTING(Boolean, ConfirmCloseAllTabs);
|
||||
INHERITABLE_SETTING(Microsoft.UI.Xaml.Controls.TabViewWidthMode, TabWidthMode);
|
||||
INHERITABLE_SETTING(Boolean, UseAcrylicInTabRow);
|
||||
INHERITABLE_SETTING(Boolean, ShowTabsInTitlebar);
|
||||
INHERITABLE_SETTING(String, WordDelimiters);
|
||||
INHERITABLE_SETTING(Boolean, CopyOnSelect);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.CopyFormat, CopyFormatting);
|
||||
INHERITABLE_SETTING(Boolean, WarnAboutLargePaste);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.WarnAboutMultiLinePaste, WarnAboutMultiLinePaste);
|
||||
INHERITABLE_SETTING(Boolean, TrimPaste);
|
||||
INHERITABLE_SETTING(LaunchPosition, InitialPosition);
|
||||
INHERITABLE_SETTING(Boolean, CenterOnLaunch);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.DefaultInputScope, DefaultInputScope);
|
||||
INHERITABLE_SETTING(LaunchMode, LaunchMode);
|
||||
INHERITABLE_SETTING(Boolean, SnapToGridOnResize);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.GraphicsAPI, GraphicsAPI);
|
||||
INHERITABLE_SETTING(Boolean, DisablePartialInvalidation);
|
||||
INHERITABLE_SETTING(Boolean, SoftwareRendering);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.TextMeasurement, TextMeasurement);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.AmbiguousWidth, AmbiguousWidth);
|
||||
INHERITABLE_SETTING(Boolean, UseBackgroundImageForWindow);
|
||||
INHERITABLE_SETTING(Boolean, AlwaysOnTop);
|
||||
INHERITABLE_SETTING(Boolean, AutoHideWindow);
|
||||
INHERITABLE_SETTING(TabSwitcherMode, TabSwitcherMode);
|
||||
INHERITABLE_SETTING(Boolean, DisableAnimations);
|
||||
INHERITABLE_SETTING(String, StartupActions);
|
||||
INHERITABLE_SETTING(Boolean, FocusFollowMouse);
|
||||
INHERITABLE_SETTING(Boolean, ScrollToZoom);
|
||||
INHERITABLE_SETTING(Boolean, ScrollToChangeOpacity);
|
||||
INHERITABLE_SETTING(Boolean, TrimBlockSelection);
|
||||
INHERITABLE_SETTING(Boolean, DetectURLs);
|
||||
INHERITABLE_SETTING(Boolean, MinimizeToNotificationArea);
|
||||
INHERITABLE_SETTING(Boolean, ShowAdminShield);
|
||||
INHERITABLE_SETTING(IVector<NewTabMenuEntry>, NewTabMenu);
|
||||
INHERITABLE_SETTING(Boolean, EnableShellCompletionMenu);
|
||||
INHERITABLE_SETTING(Boolean, EnableUnfocusedAcrylic);
|
||||
INHERITABLE_SETTING(String, SearchWebDefaultQueryUrl);
|
||||
INHERITABLE_SETTING(ThemePair, Theme);
|
||||
INHERITABLE_SETTING(Docking, DockWindow);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ Author(s):
|
||||
#include <json/json.h>
|
||||
|
||||
#include "../types/inc/utils.hpp"
|
||||
#include <til/winrt.h>
|
||||
|
||||
namespace winrt
|
||||
{
|
||||
@@ -59,6 +60,35 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||
std::string TypeDescription() const { return "<unknown>"; }
|
||||
};
|
||||
|
||||
// Specialization for til::property<T> so we can deserialize directly into properties
|
||||
template<typename T>
|
||||
struct ConversionTrait<til::property<T>>
|
||||
{
|
||||
til::property<T> FromJson(const Json::Value& json)
|
||||
{
|
||||
ConversionTrait<T> trait;
|
||||
return til::property<T>{ trait.FromJson(json) };
|
||||
}
|
||||
|
||||
bool CanConvert(const Json::Value& json)
|
||||
{
|
||||
ConversionTrait<T> trait;
|
||||
return trait.CanConvert(json);
|
||||
}
|
||||
|
||||
Json::Value ToJson(const til::property<T>& val)
|
||||
{
|
||||
ConversionTrait<T> trait;
|
||||
return trait.ToJson(val());
|
||||
}
|
||||
|
||||
std::string TypeDescription() const
|
||||
{
|
||||
ConversionTrait<T> trait;
|
||||
return trait.TypeDescription();
|
||||
}
|
||||
};
|
||||
|
||||
namespace Detail
|
||||
{
|
||||
// Function Description:
|
||||
|
||||
@@ -18,7 +18,22 @@ Author(s):
|
||||
// Macro format (defaultArgs are optional):
|
||||
// (type, name, jsonKey, defaultArgs)
|
||||
|
||||
#define MTSM_GLOBAL_SETTINGS(X) \
|
||||
// These are truly global settings - they apply to the entire application,
|
||||
// not to any specific window.
|
||||
#define MTSM_GLOBAL_SETTINGS(X) \
|
||||
X(hstring, Language, "language") \
|
||||
X(bool, InputServiceWarning, "warning.inputService", true) \
|
||||
X(Model::FirstWindowPreference, FirstWindowPreference, "firstWindowPreference", FirstWindowPreference::DefaultProfile) \
|
||||
X(bool, DebugFeaturesEnabled, "debugFeatures", debugFeaturesDefault) \
|
||||
X(Model::WindowingMode, WindowingBehavior, "windowingBehavior", Model::WindowingMode::UseNew) \
|
||||
X(bool, AlwaysShowNotificationIcon, "alwaysShowNotificationIcon", false) \
|
||||
X(winrt::Windows::Foundation::Collections::IVector<winrt::hstring>, DisabledProfileSources, "disabledProfileSources", nullptr) \
|
||||
X(bool, AllowHeadless, "compatibility.allowHeadless", false) \
|
||||
X(bool, EnableColorSelection, "experimental.enableColorSelection", false)
|
||||
|
||||
// These are per-window settings - different windows can have different values.
|
||||
// The "base" window settings act as the defaults for all windows.
|
||||
#define MTSM_WINDOW_SETTINGS(X) \
|
||||
X(int32_t, InitialRows, "initialRows", 30) \
|
||||
X(int32_t, InitialCols, "initialCols", 80) \
|
||||
X(hstring, WordDelimiters, "wordDelimiters", DEFAULT_WORD_DELIMITERS) \
|
||||
@@ -40,36 +55,28 @@ Author(s):
|
||||
X(bool, ShowTitleInTitlebar, "showTerminalTitleInTitlebar", true) \
|
||||
X(bool, ConfirmCloseAllTabs, "warning.confirmCloseAllTabs", true) \
|
||||
X(Model::ThemePair, Theme, "theme") \
|
||||
X(hstring, Language, "language") \
|
||||
X(Model::Docking, DockWindow, "dockWindow", nullptr) \
|
||||
X(winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode, TabWidthMode, "tabWidthMode", winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode::Equal) \
|
||||
X(bool, UseAcrylicInTabRow, "useAcrylicInTabRow", false) \
|
||||
X(bool, ShowTabsInTitlebar, "showTabsInTitlebar", true) \
|
||||
X(bool, InputServiceWarning, "warning.inputService", true) \
|
||||
X(winrt::Microsoft::Terminal::Control::CopyFormat, CopyFormatting, "copyFormatting", 0) \
|
||||
X(bool, WarnAboutLargePaste, "warning.largePaste", true) \
|
||||
X(winrt::Microsoft::Terminal::Control::WarnAboutMultiLinePaste, WarnAboutMultiLinePaste, "warning.multiLinePaste", winrt::Microsoft::Terminal::Control::WarnAboutMultiLinePaste::Automatic) \
|
||||
X(Model::LaunchPosition, InitialPosition, "initialPosition", nullptr, nullptr) \
|
||||
X(bool, CenterOnLaunch, "centerOnLaunch", false) \
|
||||
X(Model::FirstWindowPreference, FirstWindowPreference, "firstWindowPreference", FirstWindowPreference::DefaultProfile) \
|
||||
X(Model::LaunchMode, LaunchMode, "launchMode", LaunchMode::DefaultMode) \
|
||||
X(bool, SnapToGridOnResize, "snapToGridOnResize", true) \
|
||||
X(bool, DebugFeaturesEnabled, "debugFeatures", debugFeaturesDefault) \
|
||||
X(bool, AlwaysOnTop, "alwaysOnTop", false) \
|
||||
X(bool, AutoHideWindow, "autoHideWindow", false) \
|
||||
X(bool, MinimizeToNotificationArea, "minimizeToNotificationArea", false) \
|
||||
X(Model::TabSwitcherMode, TabSwitcherMode, "tabSwitcherMode", Model::TabSwitcherMode::InOrder) \
|
||||
X(bool, DisableAnimations, "disableAnimations", false) \
|
||||
X(hstring, StartupActions, "startupActions", L"") \
|
||||
X(Model::WindowingMode, WindowingBehavior, "windowingBehavior", Model::WindowingMode::UseNew) \
|
||||
X(bool, MinimizeToNotificationArea, "minimizeToNotificationArea", false) \
|
||||
X(bool, AlwaysShowNotificationIcon, "alwaysShowNotificationIcon", false) \
|
||||
X(winrt::Windows::Foundation::Collections::IVector<winrt::hstring>, DisabledProfileSources, "disabledProfileSources", nullptr) \
|
||||
X(bool, ShowAdminShield, "showAdminShield", true) \
|
||||
X(bool, TrimPaste, "trimPaste", true) \
|
||||
X(bool, EnableColorSelection, "experimental.enableColorSelection", false) \
|
||||
X(bool, EnableShellCompletionMenu, "experimental.enableShellCompletionMenu", false) \
|
||||
X(bool, EnableUnfocusedAcrylic, "compatibility.enableUnfocusedAcrylic", true) \
|
||||
X(winrt::Windows::Foundation::Collections::IVector<Model::NewTabMenuEntry>, NewTabMenu, "newTabMenu", winrt::single_threaded_vector<Model::NewTabMenuEntry>({ Model::RemainingProfilesEntry{} })) \
|
||||
X(bool, AllowHeadless, "compatibility.allowHeadless", false) \
|
||||
X(hstring, SearchWebDefaultQueryUrl, "searchWebDefaultQueryUrl", L"https://www.bing.com/search?q=%22%s%22") \
|
||||
X(bool, ShowTabsFullscreen, "showTabsFullscreen", false)
|
||||
|
||||
|
||||
@@ -82,6 +82,9 @@
|
||||
<ClInclude Include="GlobalAppSettings.h">
|
||||
<DependentUpon>GlobalAppSettings.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="WindowSettings.h">
|
||||
<DependentUpon>GlobalAppSettings.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IInheritable.h" />
|
||||
<ClInclude Include="MTSMSettings.h" />
|
||||
<ClInclude Include="IDynamicProfileGenerator.h" />
|
||||
@@ -161,6 +164,9 @@
|
||||
<ClCompile Include="GlobalAppSettings.cpp">
|
||||
<DependentUpon>GlobalAppSettings.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="WindowSettings.cpp">
|
||||
<DependentUpon>GlobalAppSettings.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="KeyChordSerialization.cpp">
|
||||
<DependentUpon>KeyChordSerialization.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
|
||||
@@ -528,6 +528,17 @@ JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::WindowingMode)
|
||||
};
|
||||
};
|
||||
|
||||
JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::DockPosition)
|
||||
{
|
||||
JSON_MAPPINGS(5) = {
|
||||
pair_type{ "none", ValueType::None },
|
||||
pair_type{ "top", ValueType::Top },
|
||||
pair_type{ "bottom", ValueType::Bottom },
|
||||
pair_type{ "left", ValueType::Left },
|
||||
pair_type{ "right", ValueType::Right },
|
||||
};
|
||||
};
|
||||
|
||||
JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::DesktopBehavior)
|
||||
{
|
||||
JSON_MAPPINGS(3) = {
|
||||
|
||||
203
src/cascadia/TerminalSettingsModel/WindowSettings.cpp
Normal file
203
src/cascadia/TerminalSettingsModel/WindowSettings.cpp
Normal file
@@ -0,0 +1,203 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "WindowSettings.h"
|
||||
#include "../../types/inc/Utils.hpp"
|
||||
#include "JsonUtils.h"
|
||||
#include "KeyChordSerialization.h"
|
||||
|
||||
#include "WindowSettings.g.cpp"
|
||||
#include "Docking.g.cpp"
|
||||
|
||||
#include "ProfileEntry.h"
|
||||
#include "FolderEntry.h"
|
||||
#include "MatchProfilesEntry.h"
|
||||
|
||||
using namespace ::Microsoft::Console;
|
||||
using namespace ::Microsoft::Terminal::Settings::Model;
|
||||
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model::implementation;
|
||||
using namespace winrt::Microsoft::Terminal::Settings;
|
||||
|
||||
using namespace winrt::Microsoft::UI::Xaml::Controls;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
|
||||
static constexpr std::string_view NameKey{ "name" };
|
||||
static constexpr std::string_view ThemeKey{ "theme" };
|
||||
static constexpr std::string_view DefaultProfileKey{ "defaultProfile" };
|
||||
static constexpr std::string_view LegacyUseTabSwitcherModeKey{ "useTabSwitcher" };
|
||||
|
||||
// Method Description:
|
||||
// - Copies any extraneous data from the parent before completing a CreateChild call
|
||||
void WindowSettings::_FinalizeInheritance()
|
||||
{
|
||||
for (const auto& parent : _parents)
|
||||
{
|
||||
parent;
|
||||
}
|
||||
}
|
||||
|
||||
winrt::com_ptr<WindowSettings> WindowSettings::Copy() const
|
||||
{
|
||||
auto globals{ winrt::make_self<WindowSettings>() };
|
||||
|
||||
globals->_UnparsedDefaultProfile = _UnparsedDefaultProfile;
|
||||
globals->_defaultProfile = _defaultProfile;
|
||||
|
||||
#define WINDOW_SETTINGS_COPY(type, name, jsonKey, ...) \
|
||||
globals->_##name = _##name;
|
||||
MTSM_WINDOW_SETTINGS(WINDOW_SETTINGS_COPY)
|
||||
#undef WINDOW_SETTINGS_COPY
|
||||
|
||||
if (_NewTabMenu)
|
||||
{
|
||||
globals->_NewTabMenu = winrt::single_threaded_vector<Model::NewTabMenuEntry>();
|
||||
for (const auto& entry : *_NewTabMenu)
|
||||
{
|
||||
globals->_NewTabMenu->Append(get_self<NewTabMenuEntry>(entry)->Copy());
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& parent : _parents)
|
||||
{
|
||||
globals->AddLeastImportantParent(parent->Copy());
|
||||
}
|
||||
return globals;
|
||||
}
|
||||
|
||||
#pragma region DefaultProfile
|
||||
|
||||
void WindowSettings::DefaultProfile(const winrt::guid& defaultProfile) noexcept
|
||||
{
|
||||
_defaultProfile = defaultProfile;
|
||||
_UnparsedDefaultProfile = Utils::GuidToString(defaultProfile);
|
||||
}
|
||||
|
||||
winrt::guid WindowSettings::DefaultProfile() const
|
||||
{
|
||||
return _defaultProfile;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
// Method Description:
|
||||
// - Create a new instance of this class from a serialized JsonObject.
|
||||
winrt::com_ptr<WindowSettings> WindowSettings::FromJson(const Json::Value& json)
|
||||
{
|
||||
auto result = winrt::make_self<WindowSettings>();
|
||||
result->LayerJson(json);
|
||||
return result;
|
||||
}
|
||||
|
||||
void WindowSettings::LayerJson(const Json::Value& json)
|
||||
{
|
||||
JsonUtils::GetValueForKey(json, NameKey, Name);
|
||||
|
||||
// If the name is _quake, set up some default window settings:
|
||||
if (Name() == L"_quake")
|
||||
{
|
||||
InitializeForQuakeMode();
|
||||
}
|
||||
|
||||
JsonUtils::GetValueForKey(json, DefaultProfileKey, _UnparsedDefaultProfile);
|
||||
// GH#8076 - when adding enum values to this key, we also changed it from
|
||||
// "useTabSwitcher" to "tabSwitcherMode". Continue supporting
|
||||
// "useTabSwitcher", but prefer "tabSwitcherMode"
|
||||
JsonUtils::GetValueForKey(json, LegacyUseTabSwitcherModeKey, _TabSwitcherMode);
|
||||
|
||||
#define WINDOW_SETTINGS_LAYER_JSON(type, name, jsonKey, ...) \
|
||||
JsonUtils::GetValueForKey(json, jsonKey, _##name);
|
||||
MTSM_WINDOW_SETTINGS(WINDOW_SETTINGS_LAYER_JSON)
|
||||
#undef WINDOW_SETTINGS_LAYER_JSON
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Create a new serialized JsonObject from an instance of this class
|
||||
Json::Value WindowSettings::ToJson()
|
||||
{
|
||||
// These experimental options should be removed from the settings file if they're at their default value.
|
||||
// This prevents them from sticking around forever, even if the user was just experimenting with them.
|
||||
// One could consider this a workaround for the settings UI right now not having a "reset to default" button for these.
|
||||
if (_GraphicsAPI == winrt::Microsoft::Terminal::Control::GraphicsAPI::Automatic)
|
||||
{
|
||||
_GraphicsAPI.reset();
|
||||
}
|
||||
if (_TextMeasurement == winrt::Microsoft::Terminal::Control::TextMeasurement::Graphemes)
|
||||
{
|
||||
_TextMeasurement.reset();
|
||||
}
|
||||
if (_DefaultInputScope == winrt::Microsoft::Terminal::Control::DefaultInputScope::Default)
|
||||
{
|
||||
_DefaultInputScope.reset();
|
||||
}
|
||||
if (_DisablePartialInvalidation == false)
|
||||
{
|
||||
_DisablePartialInvalidation.reset();
|
||||
}
|
||||
if (_SoftwareRendering == false)
|
||||
{
|
||||
_SoftwareRendering.reset();
|
||||
}
|
||||
|
||||
Json::Value json{ Json::ValueType::objectValue };
|
||||
|
||||
JsonUtils::SetValueForKey(json, DefaultProfileKey, _UnparsedDefaultProfile);
|
||||
|
||||
#define WINDOW_SETTINGS_TO_JSON(type, name, jsonKey, ...) \
|
||||
JsonUtils::SetValueForKey(json, jsonKey, _##name);
|
||||
MTSM_WINDOW_SETTINGS(WINDOW_SETTINGS_TO_JSON)
|
||||
#undef WINDOW_SETTINGS_TO_JSON
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
// Set up anything that we need that's quake-mode specific.
|
||||
void WindowSettings::InitializeForQuakeMode()
|
||||
{
|
||||
LaunchMode(LaunchMode::FocusMode);
|
||||
|
||||
auto dockSettings{ winrt::make_self<Docking>() };
|
||||
dockSettings->Side(Model::DockPosition::Top);
|
||||
dockSettings->Width(1.0);
|
||||
dockSettings->Height(0.5);
|
||||
_DockWindow = *dockSettings;
|
||||
_MinimizeToNotificationArea = true;
|
||||
}
|
||||
|
||||
static constexpr std::string_view SideKey{ "side" };
|
||||
static constexpr std::string_view WidthKey{ "width" };
|
||||
static constexpr std::string_view HeightKey{ "height" };
|
||||
|
||||
winrt::com_ptr<Docking> Docking::FromJson(const Json::Value& json)
|
||||
{
|
||||
auto result = winrt::make_self<Docking>();
|
||||
|
||||
if (json.isObject())
|
||||
{
|
||||
JsonUtils::GetValueForKey(json, SideKey, result->Side);
|
||||
JsonUtils::GetValueForKey(json, WidthKey, result->Width);
|
||||
JsonUtils::GetValueForKey(json, HeightKey, result->Height);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Json::Value Docking::ToJson() const
|
||||
{
|
||||
Json::Value json{ Json::ValueType::objectValue };
|
||||
|
||||
JsonUtils::SetValueForKey(json, SideKey, Side);
|
||||
JsonUtils::SetValueForKey(json, WidthKey, Width);
|
||||
JsonUtils::SetValueForKey(json, HeightKey, Height);
|
||||
return json;
|
||||
}
|
||||
|
||||
winrt::com_ptr<Docking> Docking::Copy() const
|
||||
{
|
||||
auto pair{ winrt::make_self<Docking>() };
|
||||
pair->Side = Side;
|
||||
pair->Width = Width;
|
||||
pair->Height = Height;
|
||||
return pair;
|
||||
}
|
||||
123
src/cascadia/TerminalSettingsModel/WindowSettings.h
Normal file
123
src/cascadia/TerminalSettingsModel/WindowSettings.h
Normal file
@@ -0,0 +1,123 @@
|
||||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- WindowSettings.h
|
||||
|
||||
Abstract:
|
||||
- This class encapsulates all of the settings that are specific to a single
|
||||
window. Broader than Profile settings (which are more like, per-pane
|
||||
settings). Different windows can have different settings for things like
|
||||
Theme, default profile, launch mode, etc.
|
||||
|
||||
Author(s):
|
||||
- Mike Griese - Sept 2023
|
||||
|
||||
--*/
|
||||
#pragma once
|
||||
|
||||
#include "WindowSettings.g.h"
|
||||
#include "Docking.g.h"
|
||||
#include "IInheritable.h"
|
||||
#include "MTSMSettings.h"
|
||||
|
||||
#include "TerminalSettingsSerializationHelpers.h"
|
||||
#include "ColorScheme.h"
|
||||
#include "Theme.h"
|
||||
#include "NewTabMenuEntry.h"
|
||||
#include "RemainingProfilesEntry.h"
|
||||
|
||||
// fwdecl unittest classes
|
||||
namespace SettingsModelUnitTests
|
||||
{
|
||||
class DeserializationTests;
|
||||
class ColorSchemeTests;
|
||||
};
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
{
|
||||
struct WindowSettings : WindowSettingsT<WindowSettings>, IInheritable<WindowSettings>
|
||||
{
|
||||
public:
|
||||
void _FinalizeInheritance() override;
|
||||
com_ptr<WindowSettings> Copy() const;
|
||||
|
||||
static com_ptr<WindowSettings> FromJson(const Json::Value& json);
|
||||
void LayerJson(const Json::Value& json);
|
||||
|
||||
Json::Value ToJson();
|
||||
|
||||
void InitializeForQuakeMode();
|
||||
|
||||
// This DefaultProfile() setter is called by CascadiaSettings,
|
||||
// when it parses UnparsedDefaultProfile in _finalizeSettings().
|
||||
void DefaultProfile(const guid& defaultProfile) noexcept;
|
||||
guid DefaultProfile() const;
|
||||
|
||||
til::property<winrt::hstring> Name;
|
||||
|
||||
INHERITABLE_SETTING(Model::WindowSettings, hstring, UnparsedDefaultProfile, L"");
|
||||
|
||||
#define WINDOW_SETTINGS_INITIALIZE(type, name, jsonKey, ...) \
|
||||
INHERITABLE_SETTING(Model::WindowSettings, type, name, ##__VA_ARGS__)
|
||||
MTSM_WINDOW_SETTINGS(WINDOW_SETTINGS_INITIALIZE)
|
||||
#undef WINDOW_SETTINGS_INITIALIZE
|
||||
|
||||
private:
|
||||
winrt::guid _defaultProfile;
|
||||
};
|
||||
|
||||
struct Docking : DockingT<Docking>
|
||||
{
|
||||
Docking() = default;
|
||||
|
||||
til::property<Model::DockPosition> Side{ Model::DockPosition::None };
|
||||
til::property<double> Width{ 1.0 };
|
||||
til::property<double> Height{ 1.0 };
|
||||
|
||||
static com_ptr<Docking> FromJson(const Json::Value& json);
|
||||
Json::Value ToJson() const;
|
||||
com_ptr<Docking> Copy() const;
|
||||
};
|
||||
}
|
||||
|
||||
namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||
{
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
|
||||
template<>
|
||||
struct ConversionTrait<Docking>
|
||||
{
|
||||
Docking FromJson(const Json::Value& json)
|
||||
{
|
||||
const auto entry = implementation::Docking::FromJson(json);
|
||||
if (entry == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return *entry;
|
||||
}
|
||||
|
||||
bool CanConvert(const Json::Value& json) const
|
||||
{
|
||||
return json.isObject();
|
||||
}
|
||||
|
||||
Json::Value ToJson(const Docking& val)
|
||||
{
|
||||
return winrt::get_self<implementation::Docking>(val)->ToJson();
|
||||
}
|
||||
|
||||
std::string TypeDescription() const
|
||||
{
|
||||
return "Docking";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(Docking);
|
||||
}
|
||||
@@ -235,7 +235,7 @@ namespace SettingsModelUnitTests
|
||||
const auto settings = createSettings(goodProfiles);
|
||||
VERIFY_ARE_EQUAL(static_cast<size_t>(0), settings->Warnings().Size());
|
||||
VERIFY_ARE_EQUAL(static_cast<size_t>(2), settings->AllProfiles().Size());
|
||||
VERIFY_ARE_EQUAL(settings->GlobalSettings().DefaultProfile(), settings->AllProfiles().GetAt(0).Guid());
|
||||
VERIFY_ARE_EQUAL(settings->WindowSettingsDefaults().DefaultProfile(), settings->AllProfiles().GetAt(0).Guid());
|
||||
}
|
||||
{
|
||||
// Case 2: Bad settings
|
||||
@@ -246,7 +246,7 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_ARE_EQUAL(SettingsLoadWarnings::MissingDefaultProfile, settings->Warnings().GetAt(0));
|
||||
|
||||
VERIFY_ARE_EQUAL(static_cast<size_t>(2), settings->AllProfiles().Size());
|
||||
VERIFY_ARE_EQUAL(settings->GlobalSettings().DefaultProfile(), settings->AllProfiles().GetAt(0).Guid());
|
||||
VERIFY_ARE_EQUAL(settings->WindowSettingsDefaults().DefaultProfile(), settings->AllProfiles().GetAt(0).Guid());
|
||||
}
|
||||
{
|
||||
// Case 2: Bad settings
|
||||
@@ -257,7 +257,7 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_ARE_EQUAL(SettingsLoadWarnings::MissingDefaultProfile, settings->Warnings().GetAt(0));
|
||||
|
||||
VERIFY_ARE_EQUAL(static_cast<size_t>(2), settings->AllProfiles().Size());
|
||||
VERIFY_ARE_EQUAL(settings->GlobalSettings().DefaultProfile(), settings->AllProfiles().GetAt(0).Guid());
|
||||
VERIFY_ARE_EQUAL(settings->WindowSettingsDefaults().DefaultProfile(), settings->AllProfiles().GetAt(0).Guid());
|
||||
}
|
||||
{
|
||||
// Case 4: Good settings, default profile is a string
|
||||
@@ -266,7 +266,7 @@ namespace SettingsModelUnitTests
|
||||
const auto settings = createSettings(goodProfilesSpecifiedByName);
|
||||
VERIFY_ARE_EQUAL(static_cast<size_t>(0), settings->Warnings().Size());
|
||||
VERIFY_ARE_EQUAL(static_cast<size_t>(2), settings->AllProfiles().Size());
|
||||
VERIFY_ARE_EQUAL(settings->GlobalSettings().DefaultProfile(), settings->AllProfiles().GetAt(1).Guid());
|
||||
VERIFY_ARE_EQUAL(settings->WindowSettingsDefaults().DefaultProfile(), settings->AllProfiles().GetAt(1).Guid());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,7 +354,7 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_ARE_EQUAL(SettingsLoadWarnings::MissingDefaultProfile, settings->Warnings().GetAt(1));
|
||||
|
||||
VERIFY_ARE_EQUAL(3u, settings->AllProfiles().Size());
|
||||
VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(0).Guid(), settings->GlobalSettings().DefaultProfile());
|
||||
VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(0).Guid(), settings->WindowSettingsDefaults().DefaultProfile());
|
||||
}
|
||||
|
||||
void DeserializationTests::LayerGlobalProperties()
|
||||
@@ -376,10 +376,10 @@ namespace SettingsModelUnitTests
|
||||
})" };
|
||||
|
||||
const auto settings = winrt::make_self<implementation::CascadiaSettings>(userSettings, inboxSettings);
|
||||
VERIFY_ARE_EQUAL(true, settings->GlobalSettings().AlwaysShowTabs());
|
||||
VERIFY_ARE_EQUAL(240, settings->GlobalSettings().InitialCols());
|
||||
VERIFY_ARE_EQUAL(60, settings->GlobalSettings().InitialRows());
|
||||
VERIFY_ARE_EQUAL(false, settings->GlobalSettings().ShowTabsInTitlebar());
|
||||
VERIFY_ARE_EQUAL(true, settings->WindowSettingsDefaults().AlwaysShowTabs());
|
||||
VERIFY_ARE_EQUAL(240, settings->WindowSettingsDefaults().InitialCols());
|
||||
VERIFY_ARE_EQUAL(60, settings->WindowSettingsDefaults().InitialRows());
|
||||
VERIFY_ARE_EQUAL(false, settings->WindowSettingsDefaults().ShowTabsInTitlebar());
|
||||
}
|
||||
|
||||
void DeserializationTests::ValidateProfileOrdering()
|
||||
@@ -989,7 +989,7 @@ namespace SettingsModelUnitTests
|
||||
|
||||
VERIFY_IS_NOT_NULL(settings->ProfileDefaults());
|
||||
|
||||
VERIFY_ARE_EQUAL(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}", settings->GlobalSettings().UnparsedDefaultProfile());
|
||||
VERIFY_ARE_EQUAL(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}", settings->WindowSettingsDefaults().UnparsedDefaultProfile());
|
||||
VERIFY_ARE_EQUAL(2u, settings->AllProfiles().Size());
|
||||
|
||||
VERIFY_ARE_EQUAL(2345, settings->AllProfiles().GetAt(0).HistorySize());
|
||||
@@ -1027,7 +1027,7 @@ namespace SettingsModelUnitTests
|
||||
|
||||
const auto settings = winrt::make_self<implementation::CascadiaSettings>(settings0String, implementation::LoadStringResource(IDR_DEFAULTS));
|
||||
|
||||
VERIFY_ARE_EQUAL(guid1String, settings->GlobalSettings().UnparsedDefaultProfile());
|
||||
VERIFY_ARE_EQUAL(guid1String, settings->WindowSettingsDefaults().UnparsedDefaultProfile());
|
||||
VERIFY_ARE_EQUAL(4u, settings->AllProfiles().Size());
|
||||
VERIFY_ARE_EQUAL(guid1, settings->AllProfiles().GetAt(0).Guid());
|
||||
VERIFY_ARE_NOT_EQUAL(guid1, settings->AllProfiles().GetAt(1).Guid());
|
||||
@@ -1273,8 +1273,8 @@ namespace SettingsModelUnitTests
|
||||
|
||||
const auto settings = createSettings(inputSettings);
|
||||
|
||||
VERIFY_ARE_EQUAL(999, settings->GlobalSettings().InitialCols());
|
||||
VERIFY_ARE_EQUAL(1, settings->GlobalSettings().InitialRows());
|
||||
VERIFY_ARE_EQUAL(999, settings->WindowSettingsDefaults().InitialCols());
|
||||
VERIFY_ARE_EQUAL(1, settings->WindowSettingsDefaults().InitialRows());
|
||||
}
|
||||
|
||||
void DeserializationTests::TestTrailingCommas()
|
||||
@@ -1757,7 +1757,7 @@ namespace SettingsModelUnitTests
|
||||
const auto copyImpl{ winrt::get_self<implementation::CascadiaSettings>(copy) };
|
||||
|
||||
// test globals
|
||||
VERIFY_ARE_EQUAL(settings->GlobalSettings().DefaultProfile(), copyImpl->GlobalSettings().DefaultProfile());
|
||||
VERIFY_ARE_EQUAL(settings->WindowSettingsDefaults().DefaultProfile(), copyImpl->WindowSettingsDefaults().DefaultProfile());
|
||||
|
||||
// test profiles
|
||||
VERIFY_ARE_EQUAL(settings->AllProfiles().Size(), copyImpl->AllProfiles().Size());
|
||||
@@ -1775,9 +1775,9 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_ARE_EQUAL(nameMapOriginal.Size(), nameMapCopy.Size());
|
||||
|
||||
// Test that changing the copy should not change the original
|
||||
VERIFY_ARE_EQUAL(settings->GlobalSettings().WordDelimiters(), copyImpl->GlobalSettings().WordDelimiters());
|
||||
copyImpl->GlobalSettings().WordDelimiters(L"changed value");
|
||||
VERIFY_ARE_NOT_EQUAL(settings->GlobalSettings().WordDelimiters(), copyImpl->GlobalSettings().WordDelimiters());
|
||||
VERIFY_ARE_EQUAL(settings->WindowSettingsDefaults().WordDelimiters(), copyImpl->WindowSettingsDefaults().WordDelimiters());
|
||||
copyImpl->WindowSettingsDefaults().WordDelimiters(L"changed value");
|
||||
VERIFY_ARE_NOT_EQUAL(settings->WindowSettingsDefaults().WordDelimiters(), copyImpl->WindowSettingsDefaults().WordDelimiters());
|
||||
}
|
||||
|
||||
void DeserializationTests::TestCloneInheritanceTree()
|
||||
@@ -1813,7 +1813,7 @@ namespace SettingsModelUnitTests
|
||||
const auto copyImpl{ winrt::get_self<implementation::CascadiaSettings>(copy) };
|
||||
|
||||
// test globals
|
||||
VERIFY_ARE_EQUAL(settings->GlobalSettings().DefaultProfile(), copyImpl->GlobalSettings().DefaultProfile());
|
||||
VERIFY_ARE_EQUAL(settings->WindowSettingsDefaults().DefaultProfile(), copyImpl->WindowSettingsDefaults().DefaultProfile());
|
||||
|
||||
// test profiles
|
||||
VERIFY_ARE_EQUAL(settings->AllProfiles().Size(), copyImpl->AllProfiles().Size());
|
||||
|
||||
@@ -105,9 +105,10 @@ namespace SettingsModelUnitTests
|
||||
TEST_METHOD(RealResolverUrlCases);
|
||||
TEST_METHOD(RealResolverUNCCases);
|
||||
|
||||
static constexpr std::wstring_view pingCommandline{ LR"(C:\Windows\System32\PING.EXE)" }; // Normalized by Profile (this is the casing that Windows stores on disk)
|
||||
static constexpr std::wstring_view overrideCommandline{ LR"(C:\Windows\System32\cscript.exe)" };
|
||||
static constexpr std::wstring_view cmdCommandline{ LR"(C:\Windows\System32\cmd.exe)" }; // The default commandline for a profile
|
||||
// These are normalized by NormalizeCommandLine, which resolves to the on-disk casing.
|
||||
// They are used in test cases where media paths fall back to profile command lines.
|
||||
static inline std::wstring overrideCommandline;
|
||||
static inline std::wstring cmdCommandline;
|
||||
static constexpr std::wstring_view fragmentBasePath1{ LR"(C:\Windows\Media)" };
|
||||
|
||||
private:
|
||||
@@ -218,6 +219,9 @@ namespace SettingsModelUnitTests
|
||||
// Some of our tests use paths under system32. Just don't redirect them.
|
||||
Wow64DisableWow64FsRedirection(&redirectionFlag);
|
||||
#endif
|
||||
// Normalize these AFTER the call above so that we get the correctly redirected paths.
|
||||
overrideCommandline = implementation::Profile::NormalizeCommandLine(LR"(C:\Windows\System32\cscript.exe)");
|
||||
cmdCommandline = implementation::Profile::NormalizeCommandLine(LR"(C:\Windows\System32\cmd.exe)");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace SettingsModelUnitTests
|
||||
|
||||
VERIFY_ARE_EQUAL(0u, settings->Warnings().Size());
|
||||
|
||||
const auto& entries = settings->GlobalSettings().NewTabMenu();
|
||||
const auto& entries = settings->WindowSettingsDefaults().NewTabMenu();
|
||||
VERIFY_ARE_EQUAL(1u, entries.Size());
|
||||
VERIFY_ARE_EQUAL(winrt::Microsoft::Terminal::Settings::Model::NewTabMenuEntryType::RemainingProfiles, entries.GetAt(0).Type());
|
||||
}
|
||||
@@ -74,7 +74,7 @@ namespace SettingsModelUnitTests
|
||||
|
||||
VERIFY_ARE_EQUAL(0u, settings->Warnings().Size());
|
||||
|
||||
const auto& entries = settings->GlobalSettings().NewTabMenu();
|
||||
const auto& entries = settings->WindowSettingsDefaults().NewTabMenu();
|
||||
VERIFY_ARE_EQUAL(1u, entries.Size());
|
||||
}
|
||||
catch (const SettingsException& ex)
|
||||
|
||||
@@ -244,7 +244,7 @@ namespace SettingsModelUnitTests
|
||||
NewTerminalArgs args;
|
||||
args.Commandline(testCase.input);
|
||||
|
||||
const auto profile = settings->GetProfileForArgs(args);
|
||||
const auto profile = settings->GetProfileForArgs(args, settings->WindowSettingsDefaults());
|
||||
VERIFY_IS_NOT_NULL(profile);
|
||||
|
||||
if (testCase.expected < 0)
|
||||
@@ -332,8 +332,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_IS_TRUE(terminalArgs.TabTitle().empty());
|
||||
VERIFY_IS_TRUE(terminalArgs.Profile().empty());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(guid0, profile.Guid());
|
||||
VERIFY_ARE_EQUAL(L"cmd.exe", termSettings->Commandline());
|
||||
@@ -356,8 +356,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_IS_FALSE(terminalArgs.Profile().empty());
|
||||
VERIFY_ARE_EQUAL(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}", terminalArgs.Profile());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(guid1, profile.Guid());
|
||||
VERIFY_ARE_EQUAL(L"pwsh.exe", termSettings->Commandline());
|
||||
@@ -380,8 +380,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_IS_FALSE(terminalArgs.Profile().empty());
|
||||
VERIFY_ARE_EQUAL(L"profile1", terminalArgs.Profile());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(guid1, profile.Guid());
|
||||
VERIFY_ARE_EQUAL(L"pwsh.exe", termSettings->Commandline());
|
||||
@@ -404,8 +404,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_IS_FALSE(terminalArgs.Profile().empty());
|
||||
VERIFY_ARE_EQUAL(L"profile2", terminalArgs.Profile());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(profile2Guid, profile.Guid());
|
||||
VERIFY_ARE_EQUAL(L"wsl.exe", termSettings->Commandline());
|
||||
@@ -428,8 +428,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_IS_TRUE(terminalArgs.Profile().empty());
|
||||
VERIFY_ARE_EQUAL(L"foo.exe", terminalArgs.Commandline());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
// This action specified a command but no profile; it gets reassigned to the base profile
|
||||
VERIFY_ARE_EQUAL(settings->ProfileDefaults(), profile);
|
||||
@@ -454,8 +454,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_ARE_EQUAL(L"profile1", terminalArgs.Profile());
|
||||
VERIFY_ARE_EQUAL(L"foo.exe", terminalArgs.Commandline());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(guid1, profile.Guid());
|
||||
VERIFY_ARE_EQUAL(L"foo.exe", termSettings->Commandline());
|
||||
@@ -476,8 +476,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_IS_TRUE(terminalArgs.TabTitle().empty());
|
||||
VERIFY_IS_TRUE(terminalArgs.Profile().empty());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(guid0, profile.Guid());
|
||||
VERIFY_ARE_EQUAL(L"cmd.exe", termSettings->Commandline());
|
||||
@@ -499,8 +499,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_IS_TRUE(terminalArgs.Profile().empty());
|
||||
VERIFY_ARE_EQUAL(L"c:\\foo", terminalArgs.StartingDirectory());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(guid0, profile.Guid());
|
||||
VERIFY_ARE_EQUAL(L"cmd.exe", termSettings->Commandline());
|
||||
@@ -524,8 +524,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_ARE_EQUAL(L"c:\\foo", terminalArgs.StartingDirectory());
|
||||
VERIFY_ARE_EQUAL(L"profile2", terminalArgs.Profile());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(profile2Guid, profile.Guid());
|
||||
VERIFY_ARE_EQUAL(L"wsl.exe", termSettings->Commandline());
|
||||
@@ -548,8 +548,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_IS_TRUE(terminalArgs.Profile().empty());
|
||||
VERIFY_ARE_EQUAL(L"bar", terminalArgs.TabTitle());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(guid0, profile.Guid());
|
||||
VERIFY_ARE_EQUAL(L"cmd.exe", termSettings->Commandline());
|
||||
@@ -573,8 +573,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_ARE_EQUAL(L"bar", terminalArgs.TabTitle());
|
||||
VERIFY_ARE_EQUAL(L"profile2", terminalArgs.Profile());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(profile2Guid, profile.Guid());
|
||||
VERIFY_ARE_EQUAL(L"wsl.exe", termSettings->Commandline());
|
||||
@@ -600,8 +600,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_ARE_EQUAL(L"bar", terminalArgs.TabTitle());
|
||||
VERIFY_ARE_EQUAL(L"profile1", terminalArgs.Profile());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(guid1, profile.Guid());
|
||||
VERIFY_ARE_EQUAL(L"foo.exe", termSettings->Commandline());
|
||||
@@ -640,7 +640,7 @@ namespace SettingsModelUnitTests
|
||||
|
||||
try
|
||||
{
|
||||
auto settingsStruct{ TerminalSettings::CreateWithProfile(*settings, profile1) };
|
||||
auto settingsStruct{ TerminalSettings::CreateWithProfile(*settings, profile1, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(1, settingsStruct.DefaultSettings()->HistorySize());
|
||||
}
|
||||
catch (...)
|
||||
@@ -650,7 +650,7 @@ namespace SettingsModelUnitTests
|
||||
|
||||
try
|
||||
{
|
||||
auto settingsStruct{ TerminalSettings::CreateWithProfile(*settings, profile2) };
|
||||
auto settingsStruct{ TerminalSettings::CreateWithProfile(*settings, profile2, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(2, settingsStruct.DefaultSettings()->HistorySize());
|
||||
}
|
||||
catch (...)
|
||||
@@ -660,7 +660,7 @@ namespace SettingsModelUnitTests
|
||||
|
||||
try
|
||||
{
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, nullptr) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, nullptr, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(1, settingsStruct.DefaultSettings()->HistorySize());
|
||||
}
|
||||
catch (...)
|
||||
@@ -695,10 +695,10 @@ namespace SettingsModelUnitTests
|
||||
|
||||
VERIFY_ARE_EQUAL(2u, settings->Warnings().Size());
|
||||
VERIFY_ARE_EQUAL(2u, settings->ActiveProfiles().Size());
|
||||
VERIFY_ARE_EQUAL(settings->GlobalSettings().DefaultProfile(), settings->ActiveProfiles().GetAt(0).Guid());
|
||||
VERIFY_ARE_EQUAL(settings->WindowSettingsDefaults().DefaultProfile(), settings->ActiveProfiles().GetAt(0).Guid());
|
||||
try
|
||||
{
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, nullptr) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, nullptr, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(1, settingsStruct.DefaultSettings()->HistorySize());
|
||||
}
|
||||
catch (...)
|
||||
@@ -799,7 +799,7 @@ namespace SettingsModelUnitTests
|
||||
|
||||
const auto activeProfiles = settings->ActiveProfiles();
|
||||
const auto colorSchemes = settings->GlobalSettings().ColorSchemes();
|
||||
const auto currentTheme = settings->GlobalSettings().CurrentTheme();
|
||||
const auto currentTheme = settings->GlobalSettings().CurrentTheme(settings->WindowSettingsDefaults());
|
||||
const auto terminalSettings0 = createTerminalSettings(activeProfiles.GetAt(0), colorSchemes, currentTheme);
|
||||
const auto terminalSettings1 = createTerminalSettings(activeProfiles.GetAt(1), colorSchemes, currentTheme);
|
||||
const auto terminalSettings2 = createTerminalSettings(activeProfiles.GetAt(2), colorSchemes, currentTheme);
|
||||
@@ -838,58 +838,58 @@ namespace SettingsModelUnitTests
|
||||
{ // just a profile (profile wins)
|
||||
NewTerminalArgs args{};
|
||||
args.Profile(L"profile0");
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(L"profile0", settingsStruct.DefaultSettings()->StartingTitle());
|
||||
}
|
||||
{ // profile and command line -> no promotion (profile wins)
|
||||
NewTerminalArgs args{};
|
||||
args.Profile(L"profile0");
|
||||
args.Commandline(L"foo.exe");
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(L"profile0", settingsStruct.DefaultSettings()->StartingTitle());
|
||||
}
|
||||
{ // just a title -> it is propagated
|
||||
NewTerminalArgs args{};
|
||||
args.TabTitle(L"Analog Kid");
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(L"Analog Kid", settingsStruct.DefaultSettings()->StartingTitle());
|
||||
}
|
||||
{ // title and command line -> no promotion
|
||||
NewTerminalArgs args{};
|
||||
args.TabTitle(L"Digital Man");
|
||||
args.Commandline(L"foo.exe");
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(L"Digital Man", settingsStruct.DefaultSettings()->StartingTitle());
|
||||
}
|
||||
{ // just a commandline -> promotion
|
||||
NewTerminalArgs args{};
|
||||
args.Commandline(L"foo.exe");
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(L"foo.exe", settingsStruct.DefaultSettings()->StartingTitle());
|
||||
}
|
||||
// various typesof commandline follow
|
||||
{
|
||||
NewTerminalArgs args{};
|
||||
args.Commandline(L"foo.exe bar");
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(L"foo.exe", settingsStruct.DefaultSettings()->StartingTitle());
|
||||
}
|
||||
{
|
||||
NewTerminalArgs args{};
|
||||
args.Commandline(L"\"foo exe.exe\" bar");
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(L"foo exe.exe", settingsStruct.DefaultSettings()->StartingTitle());
|
||||
}
|
||||
{
|
||||
NewTerminalArgs args{};
|
||||
args.Commandline(L"\"\" grand designs");
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(L"", settingsStruct.DefaultSettings()->StartingTitle());
|
||||
}
|
||||
{
|
||||
NewTerminalArgs args{};
|
||||
args.Commandline(L" imagine a man");
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(L"", settingsStruct.DefaultSettings()->StartingTitle());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,7 +248,7 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_IS_NULL(bar.TabRow().Background());
|
||||
}
|
||||
|
||||
const auto currentTheme{ settings->GlobalSettings().CurrentTheme() };
|
||||
const auto currentTheme{ settings->GlobalSettings().CurrentTheme(settings->WindowSettingsDefaults()) };
|
||||
VERIFY_IS_NOT_NULL(currentTheme);
|
||||
VERIFY_ARE_EQUAL(L"system", currentTheme.Name());
|
||||
}
|
||||
|
||||
@@ -556,21 +556,66 @@ void AppHost::_initialResizeAndRepositionWindow(const HWND hwnd, til::rect propo
|
||||
til::point origin{ (proposedRect.left + nonClientFrame.left),
|
||||
(proposedRect.top) };
|
||||
|
||||
if (_windowLogic.IsQuakeWindow())
|
||||
if (const auto dockingSettings{ _windowLogic.Docking() })
|
||||
{
|
||||
// If we just use rcWork by itself, we'll fail to account for the invisible
|
||||
// space reserved for the resize handles. So retrieve that size here.
|
||||
const auto availableSpace = desktopDimensions + nonClientSize;
|
||||
const auto singleBorderWidth = nonClientSize.width / 2;
|
||||
const auto singleBorderHeight = nonClientSize.height / 2;
|
||||
|
||||
origin = {
|
||||
(nearestMonitorInfo.rcWork.left - (nonClientSize.width / 2)),
|
||||
(nearestMonitorInfo.rcWork.top)
|
||||
};
|
||||
dimensions = {
|
||||
availableSpace.width,
|
||||
availableSpace.height / 2
|
||||
};
|
||||
launchMode = LaunchMode::FocusMode;
|
||||
// If it's >1, then use that as a number of px.
|
||||
// If it's <= 1, then use that as a multiplier on the available space
|
||||
const auto settingsWidth = dockingSettings.Width();
|
||||
const auto width{ settingsWidth > 1.0 ? settingsWidth : (availableSpace.width * settingsWidth) };
|
||||
const auto settingsHeight = dockingSettings.Height();
|
||||
const auto height{ settingsHeight > 1.0 ? settingsHeight : (availableSpace.height * settingsHeight) };
|
||||
|
||||
dimensions = { til::math::rounding,
|
||||
width,
|
||||
height };
|
||||
|
||||
// Account for centerOnLaunch too
|
||||
const til::size fromSide = centerOnLaunch ? (til::size{ til::math::rounding,
|
||||
(availableSpace.width - width) / 2.0,
|
||||
(availableSpace.height - height) / 2.0 }) :
|
||||
(til::size{ 0, 0 });
|
||||
|
||||
switch (dockingSettings.Side())
|
||||
{
|
||||
case winrt::Microsoft::Terminal::Settings::Model::DockPosition::Top:
|
||||
{
|
||||
origin = {
|
||||
(nearestMonitorInfo.rcWork.left - (singleBorderWidth) + fromSide.width),
|
||||
(nearestMonitorInfo.rcWork.top)
|
||||
};
|
||||
break;
|
||||
}
|
||||
case winrt::Microsoft::Terminal::Settings::Model::DockPosition::Bottom:
|
||||
{
|
||||
origin = {
|
||||
(nearestMonitorInfo.rcWork.left - (singleBorderWidth) + fromSide.width),
|
||||
(nearestMonitorInfo.rcWork.bottom - singleBorderHeight - (dimensions.height))
|
||||
};
|
||||
break;
|
||||
}
|
||||
case winrt::Microsoft::Terminal::Settings::Model::DockPosition::Left:
|
||||
{
|
||||
origin = {
|
||||
(nearestMonitorInfo.rcWork.left - (singleBorderWidth)),
|
||||
(nearestMonitorInfo.rcWork.top) + fromSide.height
|
||||
};
|
||||
break;
|
||||
}
|
||||
case winrt::Microsoft::Terminal::Settings::Model::DockPosition::Right:
|
||||
{
|
||||
origin = {
|
||||
(nearestMonitorInfo.rcWork.right - (singleBorderWidth) - (dimensions.width)),
|
||||
(nearestMonitorInfo.rcWork.top) + fromSide.height
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (centerOnLaunch)
|
||||
{
|
||||
@@ -930,7 +975,7 @@ void _frameColorHelper(const HWND h, const COLORREF color)
|
||||
|
||||
void AppHost::_updateTheme()
|
||||
{
|
||||
auto theme = _appLogic.Settings().GlobalSettings().CurrentTheme();
|
||||
auto theme = _windowLogic.Theme();
|
||||
|
||||
_window->OnApplicationThemeChanged(theme.RequestedTheme());
|
||||
|
||||
@@ -1027,7 +1072,13 @@ void AppHost::_HandleSettingsChanged(const winrt::Windows::Foundation::IInspecta
|
||||
void AppHost::_IsQuakeWindowChanged(const winrt::Windows::Foundation::IInspectable&,
|
||||
const winrt::Windows::Foundation::IInspectable&)
|
||||
{
|
||||
_window->IsQuakeWindow(_windowLogic.IsQuakeWindow());
|
||||
// The window's per-window settings identity changed (e.g. window
|
||||
// name changed, or settings reloaded). Re-push every host-level
|
||||
// per-window property so the IslandWindow stays in sync.
|
||||
_window->DockSettings(_windowLogic.Docking(), _windowLogic.CenterOnLaunch());
|
||||
_window->SetMinimizeToNotificationAreaBehavior(_windowLogic.GetMinimizeToNotificationArea());
|
||||
_window->SetAutoHideWindow(_windowLogic.AutoHideWindow());
|
||||
_window->SetShowTabsFullscreen(_windowLogic.ShowTabsFullscreen());
|
||||
}
|
||||
|
||||
// Raised from TerminalWindow. We handle by bubbling the request to the window manager.
|
||||
|
||||
@@ -17,6 +17,7 @@ using namespace winrt::Windows::UI::Composition;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Hosting;
|
||||
using namespace winrt::Windows::Foundation::Numerics;
|
||||
using namespace winrt::Microsoft::Terminal::Settings;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::Microsoft::Terminal::Control;
|
||||
using namespace winrt::Microsoft::Terminal;
|
||||
@@ -230,6 +231,14 @@ void IslandWindow::_HandleCreateWindow(const WPARAM, const LPARAM lParam) noexce
|
||||
UpdateWindowIconForActiveMetrics(_window.get());
|
||||
}
|
||||
|
||||
bool _preventSizingForDocked(const Model::DockPosition side, const WPARAM sizingSide)
|
||||
{
|
||||
return (side == Model::DockPosition::Top && sizingSide == WMSZ_TOP) ||
|
||||
(side == Model::DockPosition::Bottom && sizingSide == WMSZ_BOTTOM) ||
|
||||
(side == Model::DockPosition::Left && sizingSide == WMSZ_LEFT) ||
|
||||
(side == Model::DockPosition::Right && sizingSide == WMSZ_RIGHT);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Handles a WM_SIZING message, which occurs when user drags a window border
|
||||
// or corner. It intercepts this resize action and applies 'snapping' i.e.
|
||||
@@ -253,14 +262,16 @@ LRESULT IslandWindow::_OnSizing(const WPARAM wParam, const LPARAM lParam)
|
||||
|
||||
auto winRect = reinterpret_cast<LPRECT>(lParam);
|
||||
|
||||
// If we're the quake window, prevent resizing on all sides except the
|
||||
// bottom. This also applies to resizing with the Alt+Space menu
|
||||
if (IsQuakeWindow() && wParam != WMSZ_BOTTOM)
|
||||
// I think it's okay to resize a docked window on any side that's not the side we're docked to.
|
||||
if (_docked())
|
||||
{
|
||||
// Stuff our current window size into the lParam, and return true. This
|
||||
// will tell User32 to use our current dimensions to resize to.
|
||||
::GetWindowRect(_window.get(), winRect);
|
||||
return true;
|
||||
if (_preventSizingForDocked(_dockingSettings.Side(), wParam))
|
||||
{
|
||||
// Stuff our current window size into the lParam, and return true. This
|
||||
// will tell User32 to use our current dimensions to resize to.
|
||||
::GetWindowRect(_window.get(), winRect);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Find nearest monitor.
|
||||
@@ -355,7 +366,7 @@ LRESULT IslandWindow::_OnMoving(const WPARAM /*wParam*/, const LPARAM lParam)
|
||||
|
||||
// If we're the quake window, prevent moving the window. If we don't do
|
||||
// this, then Alt+Space...Move will still be able to move the window.
|
||||
if (IsQuakeWindow())
|
||||
if (_docked())
|
||||
{
|
||||
// Stuff our current window into the lParam, and return true. This
|
||||
// will tell User32 to use our current position to move to.
|
||||
@@ -520,7 +531,7 @@ void IslandWindow::_OnGetMinMaxInfo(const WPARAM /*wParam*/, const LPARAM lParam
|
||||
|
||||
if (_autoHideWindow && !activated)
|
||||
{
|
||||
if (_isQuakeWindow || _minimizeToNotificationArea)
|
||||
if (_minimizeToNotificationArea)
|
||||
{
|
||||
HideWindow();
|
||||
}
|
||||
@@ -569,7 +580,8 @@ void IslandWindow::_OnGetMinMaxInfo(const WPARAM /*wParam*/, const LPARAM lParam
|
||||
if (wparam == SIZE_MINIMIZED)
|
||||
{
|
||||
WindowVisibilityChanged.raise(false);
|
||||
if (_isQuakeWindow)
|
||||
|
||||
if (_minimizeToNotificationArea)
|
||||
{
|
||||
ShowWindow(GetHandle(), SW_HIDE);
|
||||
return 0;
|
||||
@@ -643,7 +655,7 @@ void IslandWindow::_OnGetMinMaxInfo(const WPARAM /*wParam*/, const LPARAM lParam
|
||||
{
|
||||
// GH#10274 - if the quake window gets moved to another monitor via aero
|
||||
// snap (win+shift+arrows), then re-adjust the size for the new monitor.
|
||||
if (IsQuakeWindow())
|
||||
if (_docked())
|
||||
{
|
||||
// Retrieve the suggested dimensions and make a rect and size.
|
||||
auto lpwpos = (LPWINDOWPOS)lparam;
|
||||
@@ -679,10 +691,10 @@ void IslandWindow::_OnGetMinMaxInfo(const WPARAM /*wParam*/, const LPARAM lParam
|
||||
if (til::rect{ proposedInfo.rcMonitor } !=
|
||||
til::rect{ currentInfo.rcMonitor })
|
||||
{
|
||||
const auto newWindowRect{ _getQuakeModeSize(proposed) };
|
||||
const auto newWindowRect{ _getDockedSize(proposed) };
|
||||
|
||||
// Inform User32 that we want to be placed at the position
|
||||
// and dimensions that _getQuakeModeSize returned. When we
|
||||
// and dimensions that _getDockedSize returned. When we
|
||||
// snap across monitor boundaries, this will re-evaluate our
|
||||
// size for the new monitor.
|
||||
lpwpos->x = newWindowRect.left;
|
||||
@@ -1309,7 +1321,10 @@ void IslandWindow::SummonWindow(winrt::TerminalApp::SummonWindowBehavior args)
|
||||
|
||||
// Method Description:
|
||||
// - Helper for performing a sliding animation. This will animate our _Xaml
|
||||
// Island_, either growing down or shrinking up, using SetWindowRgn.
|
||||
// Island_ using SetWindowRgn, revealing or hiding the window from the edge
|
||||
// it is docked to. For Top-docked windows the region grows/shrinks
|
||||
// vertically from the top; for Bottom from the bottom; for Left horizontally
|
||||
// from the left; for Right from the right.
|
||||
// - This function does the entire animation on the main thread (the UI thread),
|
||||
// and **DOES NOT YIELD IT**. The window will be animating for the entire
|
||||
// duration of dropdownDuration.
|
||||
@@ -1318,15 +1333,22 @@ void IslandWindow::SummonWindow(winrt::TerminalApp::SummonWindowBehavior args)
|
||||
// Arguments:
|
||||
// - dropdownDuration: The duration to play the animation, in milliseconds. If
|
||||
// 0, we won't perform a dropdown animation.
|
||||
// - down: if true, increase the height from top to bottom. otherwise, decrease
|
||||
// the height, from bottom to top.
|
||||
// - appearing: if true, the window is sliding into view (the visible region
|
||||
// grows). If false, it is sliding out of view (the visible region shrinks).
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void IslandWindow::_doSlideAnimation(const uint32_t dropdownDuration, const bool down)
|
||||
void IslandWindow::_doSlideAnimation(const uint32_t dropdownDuration, const bool appearing)
|
||||
{
|
||||
til::rect fullWindowSize{ GetWindowRect() };
|
||||
const auto fullWidth = fullWindowSize.width();
|
||||
const auto fullHeight = fullWindowSize.height();
|
||||
|
||||
// Determine which axis and direction to animate based on the dock side.
|
||||
// Default to Top for the (unlikely) case where there is no docking config.
|
||||
const auto side = _dockingSettings ? _dockingSettings.Side() : Model::DockPosition::Top;
|
||||
const bool horizontal = (side == Model::DockPosition::Left || side == Model::DockPosition::Right);
|
||||
const auto fullExtent = horizontal ? fullWidth : fullHeight;
|
||||
|
||||
const double animationDuration = dropdownDuration; // use floating-point math throughout
|
||||
const auto start = std::chrono::system_clock::now();
|
||||
|
||||
@@ -1343,12 +1365,31 @@ void IslandWindow::_doSlideAnimation(const uint32_t dropdownDuration, const bool
|
||||
break;
|
||||
}
|
||||
|
||||
// If going down, increase the height over time. If going up, decrease the height.
|
||||
const auto currentHeight = ::base::saturated_cast<int>(
|
||||
down ? ((dt / animationDuration) * fullHeight) :
|
||||
((1.0 - (dt / animationDuration)) * fullHeight));
|
||||
// Progress goes 0→1 when appearing and 1→0 when disappearing.
|
||||
const auto progress = appearing ? (dt / animationDuration) : (1.0 - (dt / animationDuration));
|
||||
const auto currentExtent = ::base::saturated_cast<int>(progress * fullExtent);
|
||||
|
||||
wil::unique_hrgn rgn{ CreateRectRgn(0, 0, fullWindowSize.width(), currentHeight) };
|
||||
wil::unique_hrgn rgn;
|
||||
switch (side)
|
||||
{
|
||||
case Model::DockPosition::Top:
|
||||
default:
|
||||
// Reveal/hide from the top edge downward.
|
||||
rgn.reset(CreateRectRgn(0, 0, fullWidth, currentExtent));
|
||||
break;
|
||||
case Model::DockPosition::Bottom:
|
||||
// Reveal/hide from the bottom edge upward.
|
||||
rgn.reset(CreateRectRgn(0, fullHeight - currentExtent, fullWidth, fullHeight));
|
||||
break;
|
||||
case Model::DockPosition::Left:
|
||||
// Reveal/hide from the left edge rightward.
|
||||
rgn.reset(CreateRectRgn(0, 0, currentExtent, fullHeight));
|
||||
break;
|
||||
case Model::DockPosition::Right:
|
||||
// Reveal/hide from the right edge leftward.
|
||||
rgn.reset(CreateRectRgn(fullWidth - currentExtent, 0, fullWidth, fullHeight));
|
||||
break;
|
||||
}
|
||||
SetWindowRgn(_interopWindowHandle, rgn.get(), true);
|
||||
|
||||
// Go immediately into another frame. This prevents the window from
|
||||
@@ -1388,13 +1429,13 @@ void IslandWindow::_dropdownWindow(const uint32_t dropdownDuration,
|
||||
// Possibly go to the monitor of the mouse / old foreground window.
|
||||
_moveToMonitor(oldForegroundWindow, toMonitor);
|
||||
|
||||
// Now that we're visible, animate the dropdown.
|
||||
// Now that we're visible, animate the window sliding into view.
|
||||
_doSlideAnimation(dropdownDuration, true);
|
||||
}
|
||||
|
||||
void IslandWindow::_slideUpWindow(const uint32_t dropdownDuration)
|
||||
{
|
||||
// First, animate the window sliding up.
|
||||
// First, animate the window sliding out of view.
|
||||
_doSlideAnimation(dropdownDuration, false);
|
||||
|
||||
// Then, use SetWindowPlacement to minimize without the animation.
|
||||
@@ -1616,46 +1657,56 @@ void IslandWindow::_moveToMonitor(const MONITORINFO activeMonitor)
|
||||
|
||||
// GH#10274, GH#10182: Re-evaluate the size of the quake window when we
|
||||
// move to another monitor.
|
||||
if (IsQuakeWindow())
|
||||
{
|
||||
_enterQuakeMode();
|
||||
}
|
||||
_applyDocking();
|
||||
}
|
||||
}
|
||||
|
||||
bool IslandWindow::IsQuakeWindow() const noexcept
|
||||
Docking IslandWindow::DockSettings() const noexcept
|
||||
{
|
||||
return _isQuakeWindow;
|
||||
return _dockingSettings;
|
||||
}
|
||||
|
||||
void IslandWindow::IsQuakeWindow(bool isQuakeWindow) noexcept
|
||||
void IslandWindow::DockSettings(Docking settings, const bool centered) noexcept
|
||||
{
|
||||
if (_isQuakeWindow != isQuakeWindow)
|
||||
_centered = centered;
|
||||
if (_dockingSettings != settings)
|
||||
{
|
||||
_isQuakeWindow = isQuakeWindow;
|
||||
// Don't enter quake mode if we don't have an HWND yet
|
||||
if (IsQuakeWindow() && _window)
|
||||
_dockingSettings = settings;
|
||||
|
||||
// If the window has already been created, immediately apply the
|
||||
// new docking configuration so it snaps into place. When called
|
||||
// before window creation (e.g. during startup) the docking will
|
||||
// be applied later by _initialResizeAndRepositionWindow.
|
||||
if (settings && _window)
|
||||
{
|
||||
_enterQuakeMode();
|
||||
_applyDocking();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IslandWindow::_docked() const noexcept
|
||||
{
|
||||
return _dockingSettings != nullptr && _dockingSettings.Side() != Model::DockPosition::None;
|
||||
}
|
||||
|
||||
void IslandWindow::SetAutoHideWindow(bool autoHideWindow) noexcept
|
||||
{
|
||||
_autoHideWindow = autoHideWindow;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Enter quake mode for the monitor this window is currently on. This involves
|
||||
// resizing it to the top half of the monitor.
|
||||
// - Apply the current docking configuration. The window is moved and
|
||||
// resized to the appropriate edge of the nearest monitor according
|
||||
// to _dockingSettings (side, width, height). If _centered is set,
|
||||
// the window is offset towards the centre of the monitor along the
|
||||
// non-docked axis.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void IslandWindow::_enterQuakeMode()
|
||||
void IslandWindow::_applyDocking()
|
||||
{
|
||||
if (!_window)
|
||||
if (!_window || !_dockingSettings || _dockingSettings.Side() == Model::DockPosition::None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1664,7 +1715,7 @@ void IslandWindow::_enterQuakeMode()
|
||||
auto hmon = MonitorFromRect(&windowRect, MONITOR_DEFAULTTONEAREST);
|
||||
|
||||
// Get the size and position of the window that we should occupy
|
||||
const auto newRect{ _getQuakeModeSize(hmon) };
|
||||
const auto newRect{ _getDockedSize(hmon) };
|
||||
|
||||
SetWindowPos(GetHandle(),
|
||||
HWND_TOP,
|
||||
@@ -1676,14 +1727,14 @@ void IslandWindow::_enterQuakeMode()
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Get the size and position of the window that a "quake mode" should occupy
|
||||
// on the given monitor.
|
||||
// - The window will occupy the top half of the monitor.
|
||||
// - Calculate the position and size of the docked window on the given
|
||||
// monitor. The result depends on _dockingSettings (side, width,
|
||||
// height) and _centered.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// - hmon: the monitor to dock on.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
til::rect IslandWindow::_getQuakeModeSize(HMONITOR hmon)
|
||||
// - A til::rect describing the window rectangle in screen coordinates.
|
||||
til::rect IslandWindow::_getDockedSize(HMONITOR hmon)
|
||||
{
|
||||
MONITORINFO nearestMonitorInfo;
|
||||
|
||||
@@ -1704,17 +1755,61 @@ til::rect IslandWindow::_getQuakeModeSize(HMONITOR hmon)
|
||||
const til::size ncSize{ GetTotalNonClientExclusiveSize(dpix) };
|
||||
const auto availableSpace = desktopDimensions + ncSize;
|
||||
|
||||
// GH#10201 - The borders are still visible in quake mode, so make us 1px
|
||||
// smaller on either side to account for that, so they don't hang onto
|
||||
// adjacent monitors.
|
||||
const til::point origin{
|
||||
::base::ClampSub(nearestMonitorInfo.rcWork.left, (ncSize.width / 2)) + 1,
|
||||
(nearestMonitorInfo.rcWork.top)
|
||||
};
|
||||
const til::size dimensions{
|
||||
availableSpace.width - 2,
|
||||
availableSpace.height / 2
|
||||
};
|
||||
const auto singleBorderWidth = ncSize.width / 2;
|
||||
const auto singleBorderHeight = ncSize.height / 2;
|
||||
|
||||
// If it's >1, then use that as a number of px.
|
||||
// If it's <= 1, then use that as a multiplier on the available space
|
||||
const auto settingsWidth = _dockingSettings.Width();
|
||||
const auto width{ settingsWidth > 1.0 ? settingsWidth : (availableSpace.width * settingsWidth) };
|
||||
const auto settingsHeight = _dockingSettings.Height();
|
||||
const auto height{ settingsHeight > 1.0 ? settingsHeight : (availableSpace.height * settingsHeight) };
|
||||
|
||||
const til::size dimensions = { til::math::rounding,
|
||||
width,
|
||||
height };
|
||||
|
||||
// Account for centerOnLaunch too
|
||||
const til::size fromSide = _centered ? (til::size{ til::math::rounding,
|
||||
(availableSpace.width - width) / 2.0,
|
||||
(availableSpace.height - height) / 2.0 }) :
|
||||
(til::size{ 0, 0 });
|
||||
til::point origin;
|
||||
switch (_dockingSettings.Side())
|
||||
{
|
||||
case winrt::Microsoft::Terminal::Settings::Model::DockPosition::Top:
|
||||
{
|
||||
origin = {
|
||||
(nearestMonitorInfo.rcWork.left - (singleBorderWidth) + fromSide.width),
|
||||
(nearestMonitorInfo.rcWork.top)
|
||||
};
|
||||
break;
|
||||
}
|
||||
case winrt::Microsoft::Terminal::Settings::Model::DockPosition::Bottom:
|
||||
{
|
||||
origin = {
|
||||
(nearestMonitorInfo.rcWork.left - (singleBorderWidth) + fromSide.width),
|
||||
(nearestMonitorInfo.rcWork.bottom - singleBorderHeight - (dimensions.height))
|
||||
};
|
||||
break;
|
||||
}
|
||||
case winrt::Microsoft::Terminal::Settings::Model::DockPosition::Left:
|
||||
{
|
||||
origin = {
|
||||
(nearestMonitorInfo.rcWork.left - (singleBorderWidth)),
|
||||
(nearestMonitorInfo.rcWork.top) + fromSide.height
|
||||
};
|
||||
break;
|
||||
}
|
||||
case winrt::Microsoft::Terminal::Settings::Model::DockPosition::Right:
|
||||
{
|
||||
origin = {
|
||||
(nearestMonitorInfo.rcWork.right - (singleBorderWidth) - (dimensions.width)),
|
||||
(nearestMonitorInfo.rcWork.top) + fromSide.height
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return { origin, dimensions };
|
||||
}
|
||||
|
||||
@@ -57,8 +57,8 @@ public:
|
||||
|
||||
void SummonWindow(winrt::TerminalApp::SummonWindowBehavior args);
|
||||
|
||||
bool IsQuakeWindow() const noexcept;
|
||||
void IsQuakeWindow(bool isQuakeWindow) noexcept;
|
||||
winrt::Microsoft::Terminal::Settings::Model::Docking DockSettings() const noexcept;
|
||||
void DockSettings(winrt::Microsoft::Terminal::Settings::Model::Docking settings, const bool centered) noexcept;
|
||||
void SetAutoHideWindow(bool autoHideWindow) noexcept;
|
||||
|
||||
void HideWindow();
|
||||
@@ -131,7 +131,7 @@ protected:
|
||||
void _dropdownWindow(const uint32_t dropdownDuration,
|
||||
const winrt::TerminalApp::MonitorBehavior toMonitor);
|
||||
void _slideUpWindow(const uint32_t dropdownDuration);
|
||||
void _doSlideAnimation(const uint32_t dropdownDuration, const bool down);
|
||||
void _doSlideAnimation(const uint32_t dropdownDuration, const bool appearing);
|
||||
void _globalDismissWindow(const uint32_t dropdownDuration);
|
||||
|
||||
static MONITORINFO _getMonitorForCursor();
|
||||
@@ -141,11 +141,13 @@ protected:
|
||||
void _moveToMonitorOf(HWND foregroundWindow);
|
||||
void _moveToMonitor(const MONITORINFO activeMonitor);
|
||||
|
||||
bool _isQuakeWindow{ false };
|
||||
winrt::Microsoft::Terminal::Settings::Model::Docking _dockingSettings{ nullptr };
|
||||
bool _centered{ false };
|
||||
bool _autoHideWindow{ false };
|
||||
|
||||
void _enterQuakeMode();
|
||||
til::rect _getQuakeModeSize(HMONITOR hmon);
|
||||
void _applyDocking();
|
||||
til::rect _getDockedSize(HMONITOR hmon);
|
||||
bool _docked() const noexcept;
|
||||
|
||||
bool _minimizeToNotificationArea{ false };
|
||||
|
||||
|
||||
@@ -743,23 +743,6 @@ int NonClientIslandWindow::_GetResizeHandleHeight() const noexcept
|
||||
|
||||
if (originalRet != HTCLIENT)
|
||||
{
|
||||
// If we're the quake window, suppress resizing on any side except the
|
||||
// bottom. I don't believe that this actually works on the top. That's
|
||||
// handled below.
|
||||
if (IsQuakeWindow())
|
||||
{
|
||||
switch (originalRet)
|
||||
{
|
||||
case HTBOTTOMRIGHT:
|
||||
case HTRIGHT:
|
||||
case HTTOPRIGHT:
|
||||
case HTTOP:
|
||||
case HTTOPLEFT:
|
||||
case HTLEFT:
|
||||
case HTBOTTOMLEFT:
|
||||
return HTCLIENT;
|
||||
}
|
||||
}
|
||||
return originalRet;
|
||||
}
|
||||
|
||||
@@ -779,9 +762,15 @@ int NonClientIslandWindow::_GetResizeHandleHeight() const noexcept
|
||||
// the top of the drag bar is used to resize the window
|
||||
if (!_isMaximized && isOnResizeBorder)
|
||||
{
|
||||
// However, if we're the quake window, then just return HTCAPTION so we
|
||||
// don't get a resize handle on the top.
|
||||
return IsQuakeWindow() ? HTCAPTION : HTTOP;
|
||||
// If we're docked to the top, return HTCAPTION so we don't get a
|
||||
// resize handle on the side we're docked to. The user can't resize
|
||||
// the window away from the docked edge.
|
||||
if (_docked() && _dockingSettings.Side() == winrt::Microsoft::Terminal::Settings::Model::DockPosition::Top)
|
||||
{
|
||||
return HTCAPTION;
|
||||
}
|
||||
|
||||
return HTTOP;
|
||||
}
|
||||
|
||||
return HTCAPTION;
|
||||
|
||||
@@ -1443,12 +1443,14 @@ void WindowEmperor::_checkWindowsForNotificationIcon()
|
||||
// RequestsTrayIcon setting value, and combine that with the result of each
|
||||
// window (which won't change during a settings reload).
|
||||
const auto globals = _app.Logic().Settings().GlobalSettings();
|
||||
auto needsIcon = globals.AlwaysShowNotificationIcon() || globals.MinimizeToNotificationArea();
|
||||
const auto windowDefaults = _app.Logic().Settings().WindowSettingsDefaults();
|
||||
auto needsIcon = globals.AlwaysShowNotificationIcon() || windowDefaults.MinimizeToNotificationArea();
|
||||
if (!needsIcon)
|
||||
{
|
||||
for (const auto& host : _windows)
|
||||
{
|
||||
needsIcon |= host->Logic().IsQuakeWindow();
|
||||
const auto logic = host->Logic();
|
||||
needsIcon |= logic.GetMinimizeToNotificationArea();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ void FontTests::TestCurrentFontAPIsInvalid()
|
||||
}
|
||||
else
|
||||
{
|
||||
hConsoleOutput = (HANDLE)dwConsoleOutput;
|
||||
hConsoleOutput = ULongToHandle(dwConsoleOutput);
|
||||
}
|
||||
|
||||
if (strOperation == L"Get")
|
||||
@@ -107,7 +107,7 @@ void FontTests::TestGetFontSizeInvalid()
|
||||
// Need to make sure that last error is cleared so that we can verify that lasterror was set by GetConsoleFontSize
|
||||
SetLastError(0);
|
||||
|
||||
auto coordFontSize = OneCoreDelay::GetConsoleFontSize((HANDLE)dwConsoleOutput, 0);
|
||||
auto coordFontSize = OneCoreDelay::GetConsoleFontSize(ULongToHandle(dwConsoleOutput), 0);
|
||||
VERIFY_ARE_EQUAL(coordFontSize, c_coordZero, L"Ensure (0,0) coord returned to indicate failure");
|
||||
VERIFY_ARE_EQUAL(GetLastError(), (DWORD)ERROR_INVALID_HANDLE, L"Ensure last error was set appropriately");
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ void ConhostInternalGetSet::UnknownSequence() noexcept
|
||||
// us from using a more conservative solution (e.g. always fetching the cursor position).
|
||||
if (gci.IsInVtIoMode())
|
||||
{
|
||||
gci.GetActiveOutputBuffer().SetConptyCursorPositionMayBeWrong();
|
||||
gci.GetActiveOutputBuffer().GetActiveBuffer().SetConptyCursorPositionMayBeWrong();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -241,7 +241,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
constexpr bool ends_with_insensitive_ascii(const std::basic_string_view<T, Traits>& str, const std::basic_string_view<T, Traits>& suffix) noexcept
|
||||
{
|
||||
#pragma warning(suppress : 26481) // Don't use pointer arithmetic. Use span instead (bounds.1).
|
||||
return str.size() >= suffix.size() && equals_insensitive_ascii<>({ str.data() - suffix.size(), suffix.size() }, suffix);
|
||||
return str.size() >= suffix.size() && equals_insensitive_ascii<>({ str.data() + str.size() - suffix.size(), suffix.size() }, suffix);
|
||||
}
|
||||
|
||||
constexpr bool ends_with_insensitive_ascii(const std::string_view& str, const std::string_view& prefix) noexcept
|
||||
@@ -251,7 +251,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
|
||||
constexpr bool ends_with_insensitive_ascii(const std::wstring_view& str, const std::wstring_view& prefix) noexcept
|
||||
{
|
||||
return ends_with<>(str, prefix);
|
||||
return ends_with_insensitive_ascii<>(str, prefix);
|
||||
}
|
||||
|
||||
template<typename T, typename Traits>
|
||||
|
||||
@@ -6,8 +6,3 @@
|
||||
|
||||
TARGETNAME = ConInteractivityOneCoreLib
|
||||
TARGETTYPE = LIBRARY
|
||||
|
||||
# VSTS 14847240: Locally suppress individual -Wv:17 compiler warnings.
|
||||
# For more information, visit https://osgwiki.com/wiki/Windows_C%2B%2B_Toolset_Status.
|
||||
USER_C_FLAGS=$(USER_C_FLAGS) /wd4302 # 'conversion': truncation from 'type1' to 'type2'
|
||||
USER_C_FLAGS=$(USER_C_FLAGS) /wd4311 # 'variable': pointer truncation from 'type 1' to 'type 2'
|
||||
|
||||
@@ -119,12 +119,15 @@ DWORD WINAPI Renderer::s_renderThread(void* param) noexcept
|
||||
|
||||
DWORD Renderer::_renderThread() noexcept
|
||||
{
|
||||
while (true)
|
||||
while (_threadKeepRunning.load(std::memory_order_relaxed))
|
||||
{
|
||||
_enable.wait();
|
||||
_waitUntilCanRender();
|
||||
_waitUntilTimerOrRedraw();
|
||||
|
||||
// We just completed what could have been a long wait;
|
||||
// eagerly check again to prevent rendering if we don't
|
||||
// need to.
|
||||
if (!_threadKeepRunning.load(std::memory_order_relaxed))
|
||||
{
|
||||
break;
|
||||
@@ -1058,38 +1061,7 @@ void Renderer::_PaintBufferOutput(_In_ IRenderEngine* const pEngine)
|
||||
ROW* rowBackup = nullptr;
|
||||
if (row == compositionRow)
|
||||
{
|
||||
auto& scratch = buffer.GetScratchpadRow();
|
||||
scratch.CopyFrom(r);
|
||||
rowBackup = &scratch;
|
||||
|
||||
std::wstring_view text{ activeComposition.text };
|
||||
RowWriteState state{
|
||||
.columnLimit = r.GetReadableColumnCount(),
|
||||
.columnEnd = _compositionCache->absoluteOrigin.x,
|
||||
};
|
||||
|
||||
size_t off = 0;
|
||||
for (const auto& range : activeComposition.attributes)
|
||||
{
|
||||
const auto len = range.len;
|
||||
auto attr = range.attr;
|
||||
|
||||
// Use the color at the cursor if TSF didn't specify any explicit color.
|
||||
if (attr.GetBackground().IsDefault())
|
||||
{
|
||||
attr.SetBackground(_compositionCache->baseAttribute.GetBackground());
|
||||
}
|
||||
if (attr.GetForeground().IsDefault())
|
||||
{
|
||||
attr.SetForeground(_compositionCache->baseAttribute.GetForeground());
|
||||
}
|
||||
|
||||
state.text = text.substr(off, len);
|
||||
state.columnBegin = state.columnEnd;
|
||||
const_cast<ROW&>(r).ReplaceText(state);
|
||||
const_cast<ROW&>(r).ReplaceAttributes(state.columnBegin, state.columnEnd, attr);
|
||||
off += len;
|
||||
}
|
||||
rowBackup = _PaintBufferOutputComposition(buffer, r, activeComposition);
|
||||
}
|
||||
const auto restore = wil::scope_exit([&] {
|
||||
if (rowBackup)
|
||||
@@ -1129,6 +1101,107 @@ void Renderer::_PaintBufferOutput(_In_ IRenderEngine* const pEngine)
|
||||
}
|
||||
}
|
||||
|
||||
ROW* Renderer::_PaintBufferOutputComposition(TextBuffer& buffer, const ROW& r, const Composition& activeComposition)
|
||||
{
|
||||
auto& scratch = buffer.GetScratchpadRow();
|
||||
scratch.CopyFrom(r);
|
||||
|
||||
// *Overwrite* the original text with the active composition...
|
||||
til::CoordType compositionEnd = 0;
|
||||
{
|
||||
std::wstring_view text{ activeComposition.text };
|
||||
RowWriteState state{
|
||||
.columnLimit = r.GetReadableColumnCount(),
|
||||
.columnEnd = _compositionCache->absoluteOrigin.x,
|
||||
};
|
||||
|
||||
size_t off = 0;
|
||||
for (const auto& range : activeComposition.attributes)
|
||||
{
|
||||
const auto len = range.len;
|
||||
auto attr = range.attr;
|
||||
|
||||
// Use the color at the cursor if TSF didn't specify any explicit color.
|
||||
if (attr.GetBackground().IsDefault())
|
||||
{
|
||||
attr.SetBackground(_compositionCache->baseAttribute.GetBackground());
|
||||
}
|
||||
if (attr.GetForeground().IsDefault())
|
||||
{
|
||||
attr.SetForeground(_compositionCache->baseAttribute.GetForeground());
|
||||
}
|
||||
|
||||
state.text = text.substr(off, len);
|
||||
state.columnBegin = state.columnEnd;
|
||||
const_cast<ROW&>(r).ReplaceText(state);
|
||||
const_cast<ROW&>(r).ReplaceAttributes(state.columnBegin, state.columnEnd, attr);
|
||||
off += len;
|
||||
}
|
||||
|
||||
compositionEnd = state.columnEnd;
|
||||
}
|
||||
|
||||
// The text we've overwritten may have been crucial to the user,
|
||||
// so copy it back by absorbing available whitespace to the right
|
||||
// and re-inserting the non-whitespace characters instead.
|
||||
const auto compositionWidth = compositionEnd - _compositionCache->absoluteOrigin.x;
|
||||
const auto colLimit = r.GetReadableColumnCount();
|
||||
if (compositionWidth > 0 && compositionEnd < colLimit)
|
||||
{
|
||||
const auto text = scratch.GetText();
|
||||
auto srcCol = _compositionCache->absoluteOrigin.x;
|
||||
auto dstCol = compositionEnd;
|
||||
auto remaining = compositionWidth;
|
||||
size_t i = scratch.GetCharOffset(srcCol);
|
||||
|
||||
while (i < text.size() && dstCol < colLimit)
|
||||
{
|
||||
// Treat whitespace we encounter as a credit towards our composition width.
|
||||
// This loop essentially absorbs the whitespace.
|
||||
while (i < text.size() && til::at(text, i) == L' ' && remaining > 0)
|
||||
{
|
||||
remaining--;
|
||||
srcCol++;
|
||||
i++;
|
||||
}
|
||||
if (remaining <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Find the end of the non-whitespace span: Our span of text to insert.
|
||||
auto spanEnd = i;
|
||||
while (spanEnd < text.size() && til::at(text, spanEnd) != L' ')
|
||||
{
|
||||
spanEnd++;
|
||||
}
|
||||
|
||||
// Copy the non-whitespace segment from the original text (scratch) back in.
|
||||
RowCopyTextFromState state{
|
||||
.source = scratch,
|
||||
.columnBegin = dstCol,
|
||||
.columnLimit = colLimit,
|
||||
.sourceColumnBegin = srcCol,
|
||||
.sourceColumnLimit = scratch.GetLeadingColumnAtCharOffset(spanEnd),
|
||||
};
|
||||
const_cast<ROW&>(r).CopyTextFrom(state);
|
||||
|
||||
const auto srcBeg = gsl::narrow_cast<uint16_t>(srcCol);
|
||||
const auto srcEnd = gsl::narrow_cast<uint16_t>(state.sourceColumnEnd);
|
||||
const auto attr = scratch.Attributes().slice(srcBeg, srcEnd);
|
||||
const auto dstBeg = gsl::narrow_cast<uint16_t>(dstCol);
|
||||
const auto dstEnd = gsl::narrow_cast<uint16_t>(dstCol + attr.size());
|
||||
const_cast<ROW&>(r).Attributes().replace(dstBeg, dstEnd, attr);
|
||||
|
||||
dstCol = state.columnEnd;
|
||||
srcCol = state.sourceColumnEnd;
|
||||
i = spanEnd;
|
||||
}
|
||||
}
|
||||
|
||||
return &scratch;
|
||||
}
|
||||
|
||||
static bool _IsAllSpaces(const std::wstring_view v)
|
||||
{
|
||||
// first non-space char is not found (is npos)
|
||||
|
||||
@@ -121,6 +121,7 @@ namespace Microsoft::Console::Render
|
||||
void _scheduleRenditionBlink();
|
||||
[[nodiscard]] HRESULT _PaintBackground(_In_ IRenderEngine* const pEngine);
|
||||
void _PaintBufferOutput(_In_ IRenderEngine* const pEngine);
|
||||
ROW* _PaintBufferOutputComposition(TextBuffer& buffer, const ROW& r, const Composition& activeComposition);
|
||||
void _PaintBufferOutputHelper(_In_ IRenderEngine* const pEngine, TextBufferCellIterator it, const til::point target);
|
||||
void _PaintBufferOutputGridLineHelper(_In_ IRenderEngine* const pEngine, const TextAttribute textAttribute, const size_t cchLine, const til::point coordTarget);
|
||||
bool _isHoveredHyperlink(const TextAttribute& textAttribute) const noexcept;
|
||||
|
||||
@@ -595,9 +595,12 @@ constexpr T saturate(auto val)
|
||||
RETURN_IF_FAILED(pObjectHandle->GetScreenBuffer(GENERIC_READ, &pObj));
|
||||
|
||||
// See ConptyCursorPositionMayBeWrong() for details.
|
||||
if (pObj->ConptyCursorPositionMayBeWrong())
|
||||
auto& activeBuffer = pObj->GetActiveBuffer();
|
||||
// GetConsoleScreenBufferInfoExImpl uses GetActiveBuffer internally, but
|
||||
// under the console lock.
|
||||
if (activeBuffer.ConptyCursorPositionMayBeWrong())
|
||||
{
|
||||
pObj->WaitForConptyCursorPositionToBeSynchronized();
|
||||
activeBuffer.WaitForConptyCursorPositionToBeSynchronized();
|
||||
}
|
||||
|
||||
m->_pApiRoutines->GetConsoleScreenBufferInfoExImpl(*pObj, ex);
|
||||
|
||||
@@ -166,7 +166,7 @@ void InteractDispatch::MoveCursor(const VTInt row, const VTInt col)
|
||||
|
||||
// Unblock any callers inside SCREEN_INFORMATION::WaitForConptyCursorPositionToBeSynchronized().
|
||||
// The cursor position has now been updated to the terminal's.
|
||||
info.ResetConptyCursorPositionMayBeWrong();
|
||||
info.GetActiveBuffer().ResetConptyCursorPositionMayBeWrong();
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
|
||||
@@ -31,6 +31,7 @@ Enum AssetType {
|
||||
ApplicationBundle
|
||||
PreinstallKit
|
||||
GroupPolicy
|
||||
NugetPackage
|
||||
Zip
|
||||
}
|
||||
|
||||
@@ -87,6 +88,9 @@ Class Asset {
|
||||
} ElseIf (".zip" -eq $local:ext -and $local:filename -like 'GroupPolicy*') {
|
||||
$this.Type = [AssetType]::GroupPolicy
|
||||
$this.Architecture = "all"
|
||||
} ElseIf (".nupkg" -eq $local:ext) {
|
||||
$this.Type = [AssetType]::NugetPackage
|
||||
$this.Architecture = "all"
|
||||
} ElseIf (".zip" -eq $local:ext) {
|
||||
$this.Type = [AssetType]::Zip
|
||||
} ElseIf (".msixbundle" -eq $local:ext) {
|
||||
@@ -108,6 +112,13 @@ Class Asset {
|
||||
Write-Verbose "Parsing AppxManifest.xml"
|
||||
$local:Manifest = [xml](Get-Content (Join-Path $local:directory AppxManifest.xml))
|
||||
$this.ParseManifest($local:Manifest)
|
||||
} ElseIf ($this.Type -Eq [AssetType]::NugetPackage) {
|
||||
Write-Verbose "Cracking nuget package $($local:filename)"
|
||||
& $script:tar -x -f $local:bundlePath -C $local:directory *.nuspec
|
||||
$local:nuspec = Get-ChildItem $local:directory *.nuspec -Recurse | Select-Object -First 1
|
||||
Write-Verbose "Parsing $($local:nuspec.Name)"
|
||||
$local:Manifest = [xml](Get-Content $local:nuspec)
|
||||
$this.ParseNuspec($local:Manifest)
|
||||
} Else {
|
||||
If ($this.Type -Ne [AssetType]::GroupPolicy) {
|
||||
& $script:tar -x -f $this.Path -C $local:directory --strip-components=1 '*/wt.exe'
|
||||
@@ -135,6 +146,12 @@ Class Asset {
|
||||
$this.Version = $Manifest.Package.Identity.Version
|
||||
}
|
||||
|
||||
[void]ParseNuspec([xml]$Nuspec) {
|
||||
$this.Name = $Nuspec.package.metadata.id
|
||||
$this.Version = ($Nuspec.package.metadata.version -split '-')[0]
|
||||
$this.ExpandedVersion = $Nuspec.package.metadata.version
|
||||
}
|
||||
|
||||
[void]ParseFilename([string]$filename) {
|
||||
$parts = [IO.Path]::GetFileNameWithoutExtension($filename).Split("_")
|
||||
$this.Name = $parts[0]
|
||||
@@ -160,6 +177,9 @@ Class Asset {
|
||||
GroupPolicy {
|
||||
"{0}_{1}.zip" -f ($this.Name, $this.Version)
|
||||
}
|
||||
NugetPackage {
|
||||
"{0}.{1}.nupkg" -f ($this.Name, $this.ExpandedVersion)
|
||||
}
|
||||
Default {
|
||||
Throw "Unknown type $($_.Type)"
|
||||
}
|
||||
@@ -253,15 +273,11 @@ Function New-ReleaseBody([Release]$Release) {
|
||||
If (-Not [String]::IsNullOrEmpty($zipAssetVersion)) {
|
||||
$body += "_Binary files inside the unpackaged distribution archive bear the version number ``$zipAssetVersion``._`n`n"
|
||||
}
|
||||
$body += "### Asset Hashes`n`n";
|
||||
ForEach($a in $Release.Assets) {
|
||||
$body += "- {0}`n - SHA256 ``{1}```n" -f ($a.IdealFilename(), (Get-FileHash $a.Path -Algorithm SHA256 | Select-Object -Expand Hash))
|
||||
}
|
||||
Return $body
|
||||
}
|
||||
|
||||
# Collect Assets from $Directory, figure out what those assets are
|
||||
$Assets = Get-ChildItem $Directory -Recurse -Include *.msixbundle, *.zip | ForEach-Object {
|
||||
$Assets = Get-ChildItem $Directory -Recurse -Include *.msixbundle, *.zip, *.nupkg -Exclude *.Wpf.*,*.symbols.nupkg | ForEach-Object {
|
||||
[Asset]::CreateFromFile($_.FullName)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user