mirror of
https://github.com/microsoft/terminal.git
synced 2026-05-21 14:27:22 +00:00
Compare commits
15 Commits
dev/duhowe
...
user/migri
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d2edb0a1ba | ||
|
|
5b0e4b8acf | ||
|
|
d73b4e5022 | ||
|
|
17e6126597 | ||
|
|
7a83c0f167 | ||
|
|
b2666fb346 | ||
|
|
8f4fdf9751 | ||
|
|
33a80191c1 | ||
|
|
84ae7adec6 | ||
|
|
a6ebdd3d4a | ||
|
|
031998bfc3 | ||
|
|
41e08a68bd | ||
|
|
81170aff78 | ||
|
|
c90ace8326 | ||
|
|
fd30d00304 |
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(); }
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="!Exists('CascadiaPackage_TemporaryKey.pfx')">
|
||||
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>
|
||||
<!--<AppxBundle>Never</AppxBundle>-->
|
||||
<AppxBundle>Never</AppxBundle>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="Exists('CascadiaPackage_TemporaryKey.pfx')">
|
||||
<AppxPackageSigningEnabled>true</AppxPackageSigningEnabled>
|
||||
|
||||
@@ -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,89 @@ 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);
|
||||
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->_settings.WindowSettingsDefaults().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 +1175,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,18 +1197,14 @@ 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());
|
||||
VERIFY_ARE_EQUAL(L"a", page->_mruTabs.GetAt(3).Title());
|
||||
});
|
||||
|
||||
Log::Comment(L"Change the tab switch order to MRU switching");
|
||||
TestOnUIThread([&page]() {
|
||||
page->_settings.GlobalSettings().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 +1212,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 +1269,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 +1301,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 +1363,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 +1411,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 +1478,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);
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -293,6 +293,11 @@ namespace winrt::TerminalApp::implementation
|
||||
_systemRowsToScroll = _ReadSystemRowsToScroll();
|
||||
}
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::WindowSettings TerminalPage::_currentWindowSettings() const
|
||||
{
|
||||
return _settings.WindowSettings(_WindowProperties.WindowName());
|
||||
}
|
||||
|
||||
bool TerminalPage::IsRunningElevated() const noexcept
|
||||
{
|
||||
// GH#2455 - Make sure to try/catch calls to Application::Current,
|
||||
@@ -335,7 +340,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.
|
||||
@@ -425,7 +430,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 +439,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(),
|
||||
@@ -951,7 +956,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 +1238,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());
|
||||
@@ -1470,7 +1475,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";
|
||||
@@ -1483,7 +1488,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}();
|
||||
static const auto ambiguousIsWide = [&]() -> bool {
|
||||
return _settings.GlobalSettings().AmbiguousWidth() == AmbiguousWidth::Wide;
|
||||
return _currentWindowSettings().AmbiguousWidth() == AmbiguousWidth::Wide;
|
||||
}();
|
||||
|
||||
TerminalConnection::ITerminalConnection connection{ nullptr };
|
||||
@@ -2312,7 +2317,7 @@ namespace winrt::TerminalApp::implementation
|
||||
safe_void_coroutine TerminalPage::CloseWindow()
|
||||
{
|
||||
if (_HasMultipleTabs() &&
|
||||
_settings.GlobalSettings().ConfirmCloseAllTabs() &&
|
||||
_currentWindowSettings().ConfirmCloseAllTabs() &&
|
||||
!_displayingCloseDialog)
|
||||
{
|
||||
if (_newTabButton && _newTabButton.Flyout())
|
||||
@@ -2837,7 +2842,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 +2931,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 +2959,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 +2972,7 @@ namespace winrt::TerminalApp::implementation
|
||||
text = clipboard::read();
|
||||
}
|
||||
|
||||
if (!bracketedPaste && globalSettings.TrimPaste())
|
||||
if (!bracketedPaste && windowSettings.TrimPaste())
|
||||
{
|
||||
text = winrt::hstring{ Utils::TrimPaste(text) };
|
||||
}
|
||||
@@ -2982,7 +2987,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 +3010,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 +3090,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 +3145,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 +3201,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*/,
|
||||
@@ -3764,7 +3818,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;
|
||||
@@ -3873,17 +3927,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);
|
||||
@@ -4671,7 +4725,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
if (profile == _settings.ProfileDefaults())
|
||||
{
|
||||
return _settings.FindProfile(_settings.GlobalSettings().DefaultProfile());
|
||||
return _settings.FindProfile(_currentWindowSettings().DefaultProfile());
|
||||
}
|
||||
return profile;
|
||||
}
|
||||
@@ -4936,7 +4990,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 +5020,7 @@ namespace winrt::TerminalApp::implementation
|
||||
TitlebarBrush(backgroundSolidBrush);
|
||||
}
|
||||
|
||||
if (!_settings.GlobalSettings().ShowTabsInTitlebar())
|
||||
if (!_currentWindowSettings().ShowTabsInTitlebar())
|
||||
{
|
||||
_tabRow.Background(TitlebarBrush());
|
||||
}
|
||||
@@ -5202,7 +5256,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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -267,22 +267,22 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
bool TerminalWindow::GetShowTabsInTitlebar()
|
||||
{
|
||||
return _settings.GlobalSettings().ShowTabsInTitlebar();
|
||||
return _settings.WindowSettingsDefaults().ShowTabsInTitlebar();
|
||||
}
|
||||
|
||||
bool TerminalWindow::GetInitialAlwaysOnTop()
|
||||
{
|
||||
return _settings.GlobalSettings().AlwaysOnTop();
|
||||
return _settings.WindowSettingsDefaults().AlwaysOnTop();
|
||||
}
|
||||
|
||||
bool TerminalWindow::GetInitialShowTabsFullscreen()
|
||||
{
|
||||
return _settings.GlobalSettings().ShowTabsFullscreen();
|
||||
return _settings.WindowSettingsDefaults().ShowTabsFullscreen();
|
||||
}
|
||||
|
||||
bool TerminalWindow::GetMinimizeToNotificationArea()
|
||||
{
|
||||
return _settings.GlobalSettings().MinimizeToNotificationArea();
|
||||
return _settings.WindowSettingsDefaults().MinimizeToNotificationArea();
|
||||
}
|
||||
|
||||
bool TerminalWindow::GetAlwaysShowNotificationIcon()
|
||||
@@ -292,7 +292,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
bool TerminalWindow::GetShowTitleInTitlebar()
|
||||
{
|
||||
return _settings.GlobalSettings().ShowTitleInTitlebar();
|
||||
return _settings.WindowSettingsDefaults().ShowTitleInTitlebar();
|
||||
}
|
||||
|
||||
Microsoft::Terminal::Settings::Model::Theme TerminalWindow::Theme()
|
||||
@@ -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(_settings.WindowSettingsDefaults().LaunchMode()) == LaunchMode::FocusMode;
|
||||
|
||||
const auto scale = static_cast<float>(dpi) / static_cast<float>(USER_DEFAULT_SCREEN_DPI);
|
||||
if (const auto layout = LoadPersistedLayout())
|
||||
@@ -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 (_settings.WindowSettingsDefaults().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 (_settings.WindowSettingsDefaults().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 = _settings.WindowSettingsDefaults().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{ _settings.WindowSettingsDefaults().InitialPosition() };
|
||||
|
||||
if (const auto layout = LoadPersistedLayout())
|
||||
{
|
||||
@@ -770,7 +770,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
return !_contentBounds &&
|
||||
!hadPersistedPosition &&
|
||||
_settings.GlobalSettings().CenterOnLaunch() &&
|
||||
_settings.WindowSettingsDefaults().CenterOnLaunch() &&
|
||||
(_appArgs && !_appArgs->ParsedArgs().GetPosition().has_value());
|
||||
}
|
||||
|
||||
@@ -1188,7 +1188,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
bool TerminalWindow::AutoHideWindow()
|
||||
{
|
||||
return _settings.GlobalSettings().AutoHideWindow();
|
||||
return _settings.WindowSettingsDefaults().AutoHideWindow();
|
||||
}
|
||||
|
||||
void TerminalWindow::UpdateSettingsHandler(const winrt::IInspectable& /*sender*/,
|
||||
@@ -1332,13 +1332,13 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
if (!FocusMode())
|
||||
{
|
||||
if (!_settings.GlobalSettings().AlwaysShowTabs())
|
||||
if (!_settings.WindowSettingsDefaults().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 (!_settings.WindowSettingsDefaults().ShowTabsInTitlebar())
|
||||
{
|
||||
// Hide the title bar = off, Always show tabs = on.
|
||||
static constexpr auto titlebarAndTabBarHeight = 40;
|
||||
|
||||
@@ -78,7 +78,6 @@
|
||||
<Project>{18D09A24-8240-42D6-8CB6-236EEE820263}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\WinRTUtils\WinRTUtils.vcxproj">
|
||||
<Private>true</Private>
|
||||
<Project>{CA5CAD1A-039A-4929-BA2A-8BEB2E4106FE}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include "winrt/Windows.Data.Json.h"
|
||||
#include <Windows.h>
|
||||
|
||||
#include <wrl.h>
|
||||
#include <winhttp.h>
|
||||
#include <wil/resource.h>
|
||||
|
||||
|
||||
@@ -179,7 +179,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
void ControlCore::_setupDispatcherAndCallbacks()
|
||||
{
|
||||
///* TODO(DH) */ return;
|
||||
// Get our dispatcher. If we're hosted in-proc with XAML, this will get
|
||||
// us the same dispatcher as TermControl::Dispatcher(). If we're out of
|
||||
// proc, this'll return null. We'll need to instead make a new
|
||||
@@ -434,15 +433,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_terminal->Create(viewportSize, Utils::ClampToShortMax(_settings.HistorySize(), 0), *_renderer);
|
||||
_terminal->UpdateSettings(_settings);
|
||||
|
||||
if (_hookup == HookupMode::ForComposition)
|
||||
{
|
||||
// Tell the render engine to notify us when the swap chain changes.
|
||||
// We do this after we initially set the swapchain so as to avoid
|
||||
// unnecessary callbacks (and locking problems)
|
||||
_renderEngine->SetCallback([this](HANDLE handle) {
|
||||
_renderEngineSwapChainChanged(handle);
|
||||
});
|
||||
}
|
||||
// Tell the render engine to notify us when the swap chain changes.
|
||||
// We do this after we initially set the swapchain so as to avoid
|
||||
// unnecessary callbacks (and locking problems)
|
||||
_renderEngine->SetCallback([this](HANDLE handle) {
|
||||
_renderEngineSwapChainChanged(handle);
|
||||
});
|
||||
|
||||
_renderEngine->SetRetroTerminalEffect(_settings.RetroTerminalEffect());
|
||||
_renderEngine->SetPixelShaderPath(_settings.PixelShaderPath());
|
||||
@@ -463,23 +459,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ControlCore::InitializeWithHwnd(const float actualWidth,
|
||||
const float actualHeight,
|
||||
const float compositionScale,
|
||||
const uint64_t hwnd)
|
||||
{
|
||||
_owningHwnd = hwnd;
|
||||
_hookup = HookupMode::ForHwnd;
|
||||
|
||||
auto i = Initialize(actualWidth, actualHeight, compositionScale);
|
||||
if (i)
|
||||
{
|
||||
auto lock = _terminal->LockForWriting();
|
||||
(void)_renderEngine->SetHwnd(reinterpret_cast<HWND>(hwnd));
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Tell the renderer to start painting.
|
||||
// - !! IMPORTANT !! Make sure that we've attached our swap chain to an
|
||||
@@ -1980,7 +1959,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
RendererWarning.raise(*this, winrt::make<RendererWarningArgs>(hr, winrt::hstring{ parameter }));
|
||||
}
|
||||
|
||||
/* TODO(DH) */ void ControlCore::_renderEngineSwapChainChanged(const HANDLE sourceHandle)
|
||||
safe_void_coroutine ControlCore::_renderEngineSwapChainChanged(const HANDLE sourceHandle)
|
||||
{
|
||||
// `sourceHandle` is a weak ref to a HANDLE that's ultimately owned by the
|
||||
// render engine's own unique_handle. We'll add another ref to it here.
|
||||
@@ -1998,7 +1977,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
// Concurrent read of _dispatcher is safe, because Detach() calls TriggerTeardown()
|
||||
// which blocks until this call returns. _dispatcher will only be changed afterwards.
|
||||
// TODO(DH) co_await wil::resume_foreground(_dispatcher);
|
||||
co_await wil::resume_foreground(_dispatcher);
|
||||
|
||||
if (auto core{ weakThis.get() })
|
||||
{
|
||||
@@ -2962,39 +2941,4 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
_terminal->PreviewText(input);
|
||||
}
|
||||
|
||||
ControlCore::TimerHandle ControlCore::RegisterTimer(const char* name, std::function<void()> callback)
|
||||
{
|
||||
return _renderer->RegisterTimer(name, [cb = std::move(callback)](auto&&, auto&&) {
|
||||
cb();
|
||||
});
|
||||
}
|
||||
bool ControlCore::IsTimerRunning(TimerHandle h)
|
||||
{
|
||||
return _renderer->IsTimerRunning(h);
|
||||
}
|
||||
void ControlCore::StartRepeatingTimer(TimerHandle h, uint64_t micros)
|
||||
{
|
||||
_renderer->StartRepeatingTimer(h, std::chrono::microseconds(micros));
|
||||
}
|
||||
void ControlCore::StopTimer(TimerHandle h)
|
||||
{
|
||||
_renderer->StopTimer(h);
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::Size ControlCore::RenderedSize()
|
||||
{
|
||||
return { _panelWidth, _panelHeight };
|
||||
}
|
||||
|
||||
void ControlCore::ResizeToDimensions(uint32_t width, uint32_t height, winrt::Windows::Foundation::Size& newSizeInPixels)
|
||||
{
|
||||
if (!_renderEngine)
|
||||
{
|
||||
throw winrt::hresult_error(E_INVALIDARG);
|
||||
}
|
||||
auto pixelSize = _renderEngine->GetViewportInPixels(Viewport::FromDimensions({ 0, 0 }, til::size{ static_cast<til::CoordType>(width), static_cast<til::CoordType>(height) }));
|
||||
SizeOrScaleChanged(static_cast<float>(pixelSize.Width()), static_cast<float>(pixelSize.Height()), _compositionScale);
|
||||
newSizeInPixels = RenderedSize();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
#include "../../cascadia/TerminalCore/Terminal.hpp"
|
||||
#include "../../renderer/inc/FontInfoDesired.hpp"
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace Microsoft::Console::Render::Atlas
|
||||
{
|
||||
class AtlasEngine;
|
||||
@@ -80,12 +78,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
struct ControlCore : ControlCoreT<ControlCore>
|
||||
{
|
||||
private:
|
||||
enum class HookupMode
|
||||
{
|
||||
ForHwnd = 0x0,
|
||||
ForComposition = 0x1,
|
||||
};
|
||||
public:
|
||||
ControlCore(Control::IControlSettings settings,
|
||||
Control::IControlAppearance unfocusedAppearance,
|
||||
@@ -95,10 +87,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
bool Initialize(const float actualWidth,
|
||||
const float actualHeight,
|
||||
const float compositionScale);
|
||||
bool InitializeWithHwnd(const float actualWidth,
|
||||
const float actualHeight,
|
||||
const float compositionScale,
|
||||
const uint64_t hwnd);
|
||||
void EnablePainting();
|
||||
|
||||
void Detach();
|
||||
@@ -274,17 +262,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
bool ShouldShowSelectCommand();
|
||||
bool ShouldShowSelectOutput();
|
||||
|
||||
winrt::Windows::Foundation::Size RenderedSize();
|
||||
void ResizeToDimensions(uint32_t width, uint32_t height, winrt::Windows::Foundation::Size& newSizeInPixels);
|
||||
|
||||
void PreviewInput(std::wstring_view input);
|
||||
|
||||
using TimerHandle = ::Microsoft::Console::Render::TimerHandle;
|
||||
TimerHandle RegisterTimer(const char* name, std::function<void()> callback);
|
||||
bool IsTimerRunning(TimerHandle h);
|
||||
void StartRepeatingTimer(TimerHandle h, uint64_t micros);
|
||||
void StopTimer(TimerHandle h);
|
||||
|
||||
RUNTIME_SETTING(float, Opacity, _settings.Opacity());
|
||||
RUNTIME_SETTING(float, FocusedOpacity, FocusedAppearance().Opacity());
|
||||
RUNTIME_SETTING(bool, UseAcrylic, _settings.UseAcrylic());
|
||||
@@ -361,7 +340,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
#pragma region RendererCallbacks
|
||||
void _rendererWarning(const HRESULT hr, wil::zwstring_view parameter);
|
||||
/* TODO(DH) */ void _renderEngineSwapChainChanged(const HANDLE handle);
|
||||
safe_void_coroutine _renderEngineSwapChainChanged(const HANDLE handle);
|
||||
void _rendererBackgroundColorChanged();
|
||||
void _rendererTabColorChanged();
|
||||
void _rendererEnteredErrorState();
|
||||
@@ -396,7 +375,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
//
|
||||
// Though, the unit tests don't actually run in TAEF's main
|
||||
// thread, so we don't care when we're running in tests.
|
||||
assert(_hookup == HookupMode::ForHwnd || _inUnitTests || _dispatcher.HasThreadAccess());
|
||||
assert(_inUnitTests || _dispatcher.HasThreadAccess());
|
||||
}
|
||||
#endif
|
||||
return _closing;
|
||||
@@ -442,7 +421,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
std::atomic<bool> _initializedTerminal{ false };
|
||||
bool _isReadOnly{ false };
|
||||
bool _closing{ false };
|
||||
HookupMode _hookup{ HookupMode::ForComposition };
|
||||
|
||||
struct StashedColorScheme
|
||||
{
|
||||
|
||||
@@ -93,9 +93,6 @@ namespace Microsoft.Terminal.Control
|
||||
Boolean Initialize(Single actualWidth,
|
||||
Single actualHeight,
|
||||
Single compositionScale);
|
||||
Boolean InitializeWithHwnd(Single actualWidth,
|
||||
Single actualHeight,
|
||||
Single compositionScale, UInt64 hwnd);
|
||||
|
||||
void UpdateSettings(IControlSettings settings, IControlAppearance appearance);
|
||||
void ApplyAppearance(Boolean focused);
|
||||
@@ -187,9 +184,6 @@ namespace Microsoft.Terminal.Control
|
||||
Boolean ShouldShowSelectCommand();
|
||||
Boolean ShouldShowSelectOutput();
|
||||
|
||||
Windows.Foundation.Size RenderedSize { get; };
|
||||
void ResizeToDimensions(UInt32 width, UInt32 height, out Windows.Foundation.Size newSizeInPixels);
|
||||
|
||||
void OpenCWD();
|
||||
|
||||
void ClearQuickFix();
|
||||
|
||||
@@ -68,8 +68,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
_createInteractivityTimers();
|
||||
}
|
||||
|
||||
uint64_t ControlInteractivity::Id()
|
||||
@@ -96,14 +94,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
LOG_IF_FAILED(_uiaEngine->Disable());
|
||||
_core->DetachUiaEngine(_uiaEngine.get());
|
||||
}
|
||||
_destroyInteractivityTimers();
|
||||
_core->Detach();
|
||||
}
|
||||
|
||||
void ControlInteractivity::AttachToNewControl()
|
||||
{
|
||||
_core->AttachToNewControl();
|
||||
//_createInteractivityTimers();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -135,31 +131,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void ControlInteractivity::Close()
|
||||
{
|
||||
Closed.raise(*this, nullptr);
|
||||
_destroyInteractivityTimers();
|
||||
if (_core)
|
||||
{
|
||||
_core->Close();
|
||||
}
|
||||
}
|
||||
|
||||
void ControlInteractivity::_createInteractivityTimers()
|
||||
{
|
||||
_autoScrollTimer = _core->RegisterTimer("autoscroll", [weak = get_weak()]() {
|
||||
if (auto strong = weak.get())
|
||||
{
|
||||
strong->_updateAutoScroll();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ControlInteractivity::_destroyInteractivityTimers()
|
||||
{
|
||||
if (_autoScrollTimer)
|
||||
{
|
||||
_core->StopTimer(_autoScrollTimer);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Returns the number of clicks that occurred (double and triple click support).
|
||||
// Every call to this function registers a click.
|
||||
@@ -392,7 +369,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_touchAnchor = contactPoint;
|
||||
}
|
||||
|
||||
bool ControlInteractivity::PointerMoved(const uint32_t pointerId,
|
||||
bool ControlInteractivity::PointerMoved(const uint32_t /*pointerId*/,
|
||||
Control::MouseButtonState buttonState,
|
||||
const unsigned int pointerUpdateKind,
|
||||
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
||||
@@ -452,40 +429,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
|
||||
SetEndSelectionPoint(pixelPosition);
|
||||
|
||||
// GH#9109 - Only start an auto-scroll when the drag actually
|
||||
// started within our bounds. Otherwise, someone could start a drag
|
||||
// outside the terminal control, drag into the padding, and trick us
|
||||
// into starting to scroll.
|
||||
{
|
||||
// We want to find the distance relative to the bounds of the
|
||||
// SwapChainPanel, not the entire control. If they drag out of
|
||||
// the bounds of the text, into the padding, we still what that
|
||||
// to auto-scroll
|
||||
const auto height = _core->ViewHeight() * _core->FontSize().Height;
|
||||
const auto cursorBelowBottomDist = pixelPosition.Y - height;
|
||||
const auto cursorAboveTopDist = -1 * pixelPosition.Y;
|
||||
|
||||
constexpr auto MinAutoScrollDist = 2.0; // Arbitrary value
|
||||
auto newAutoScrollVelocity = 0.0;
|
||||
if (cursorBelowBottomDist > MinAutoScrollDist)
|
||||
{
|
||||
newAutoScrollVelocity = _getAutoScrollSpeed(cursorBelowBottomDist);
|
||||
}
|
||||
else if (cursorAboveTopDist > MinAutoScrollDist)
|
||||
{
|
||||
newAutoScrollVelocity = -1.0 * _getAutoScrollSpeed(cursorAboveTopDist);
|
||||
}
|
||||
|
||||
if (newAutoScrollVelocity != 0)
|
||||
{
|
||||
_tryStartAutoScroll(pointerId, pixelPosition, newAutoScrollVelocity);
|
||||
}
|
||||
else
|
||||
{
|
||||
_tryStopAutoScroll(pointerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_core->SetHoveredCell(terminalPosition.to_core_point());
|
||||
@@ -528,7 +471,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
}
|
||||
|
||||
void ControlInteractivity::PointerReleased(const uint32_t pointerId,
|
||||
void ControlInteractivity::PointerReleased(const uint32_t /*pointerId*/,
|
||||
Control::MouseButtonState buttonState,
|
||||
const unsigned int pointerUpdateKind,
|
||||
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
||||
@@ -559,7 +502,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
|
||||
_singleClickTouchdownPos = std::nullopt;
|
||||
_tryStopAutoScroll(pointerId);
|
||||
}
|
||||
|
||||
void ControlInteractivity::TouchReleased()
|
||||
@@ -855,97 +797,4 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
return _core->GetRenderData();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Calculates speed of single axis of auto scrolling. It has to allow for both
|
||||
// fast and precise selection.
|
||||
// Arguments:
|
||||
// - cursorDistanceFromBorder: distance from viewport border to cursor, in pixels. Must be non-negative.
|
||||
// Return Value:
|
||||
// - positive speed in characters / sec
|
||||
double ControlInteractivity::_getAutoScrollSpeed(double cursorDistanceFromBorder) const
|
||||
{
|
||||
// The numbers below just feel well, feel free to change.
|
||||
// TODO: Maybe account for space beyond border that user has available
|
||||
return std::pow(cursorDistanceFromBorder, 2.0) / 25.0 + 2.0;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Starts new pointer related auto scroll behavior, or continues existing one.
|
||||
// Does nothing when there is already auto scroll associated with another pointer.
|
||||
// Arguments:
|
||||
// - pointerId, point: info about pointer that causes auto scroll. Pointer's position
|
||||
// is later used to update selection.
|
||||
// - scrollVelocity: target velocity of scrolling in characters / sec
|
||||
void ControlInteractivity::_tryStartAutoScroll(const uint32_t pointerId, const Core::Point& point, const double scrollVelocity)
|
||||
{
|
||||
// Allow only one pointer at the time
|
||||
if (!_autoScrollingPointerId ||
|
||||
_autoScrollingPointerId == pointerId)
|
||||
{
|
||||
_autoScrollingPointerId = pointerId;
|
||||
_autoScrollingPointerPoint = point;
|
||||
_autoScrollVelocity = scrollVelocity;
|
||||
|
||||
// If this is first time the auto scroll update is about to be called,
|
||||
// kick-start it by initializing its time delta as if it started now
|
||||
if (!_lastAutoScrollUpdateTime)
|
||||
{
|
||||
_lastAutoScrollUpdateTime = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
// Apparently this check is not necessary but greatly improves performance
|
||||
if (!_core->IsTimerRunning(_autoScrollTimer))
|
||||
{
|
||||
static constexpr auto AutoScrollUpdateInterval = std::chrono::microseconds(static_cast<int>(1.0 / 30.0 * 1000000));
|
||||
_core->StartRepeatingTimer(_autoScrollTimer, AutoScrollUpdateInterval.count());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Stops auto scroll if it's active and is associated with supplied pointer id.
|
||||
// Arguments:
|
||||
// - pointerId: id of pointer for which to stop auto scroll
|
||||
void ControlInteractivity::_tryStopAutoScroll(const uint32_t pointerId)
|
||||
{
|
||||
if (_autoScrollingPointerId &&
|
||||
pointerId == _autoScrollingPointerId)
|
||||
{
|
||||
_autoScrollingPointerId = std::nullopt;
|
||||
_autoScrollingPointerPoint = std::nullopt;
|
||||
_autoScrollVelocity = 0;
|
||||
_lastAutoScrollUpdateTime = std::nullopt;
|
||||
|
||||
// Apparently this check is not necessary but greatly improves performance
|
||||
_core->StopTimer(_autoScrollTimer);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Called continuously to gradually scroll viewport when user is mouse
|
||||
// selecting outside it (to 'follow' the cursor).
|
||||
// Arguments:
|
||||
// - none
|
||||
void ControlInteractivity::_updateAutoScroll()
|
||||
{
|
||||
if (_autoScrollVelocity != 0)
|
||||
{
|
||||
const auto timeNow = std::chrono::high_resolution_clock::now();
|
||||
|
||||
if (_lastAutoScrollUpdateTime)
|
||||
{
|
||||
static constexpr auto microSecPerSec = 1000000.0;
|
||||
const auto deltaTime = std::chrono::duration_cast<std::chrono::microseconds>(timeNow - *_lastAutoScrollUpdateTime).count() / microSecPerSec;
|
||||
UpdateScrollbar(static_cast<float>(_core->ScrollOffset()) + static_cast<float>(_autoScrollVelocity * deltaTime) /* TODO(DH) */);
|
||||
|
||||
if (_autoScrollingPointerPoint)
|
||||
{
|
||||
SetEndSelectionPoint(*_autoScrollingPointerPoint);
|
||||
}
|
||||
}
|
||||
|
||||
_lastAutoScrollUpdateTime = timeNow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,24 +143,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
static std::atomic<uint64_t> _nextId;
|
||||
|
||||
bool _focused{ false };
|
||||
|
||||
// Auto scroll occurs when user, while selecting, drags cursor outside
|
||||
// viewport. View is then scrolled to 'follow' the cursor.
|
||||
double _autoScrollVelocity;
|
||||
std::optional<uint32_t> _autoScrollingPointerId;
|
||||
std::optional<Core::Point> _autoScrollingPointerPoint;
|
||||
ControlCore::TimerHandle _autoScrollTimer;
|
||||
std::optional<std::chrono::high_resolution_clock::time_point> _lastAutoScrollUpdateTime;
|
||||
bool _pointerPressedInBounds{ false };
|
||||
|
||||
void _tryStartAutoScroll(const uint32_t id, const Core::Point& point, const double scrollVelocity);
|
||||
void _tryStopAutoScroll(const uint32_t pointerId);
|
||||
void _updateAutoScroll();
|
||||
double _getAutoScrollSpeed(double cursorDistanceFromBorder) const;
|
||||
|
||||
void _createInteractivityTimers();
|
||||
void _destroyInteractivityTimers();
|
||||
|
||||
unsigned int _numberOfClicks(Core::Point clickPos, Timestamp clickTime);
|
||||
void _updateSystemParameterSettings() noexcept;
|
||||
|
||||
|
||||
@@ -1,641 +0,0 @@
|
||||
#include "pch.h"
|
||||
#include "FlatC.h"
|
||||
#include "winrt/Microsoft.Terminal.Control.h"
|
||||
#include "winrt/Microsoft.Terminal.Core.h"
|
||||
#include "../TerminalCore/ControlKeyStates.hpp"
|
||||
#include "../types/inc/colorTable.hpp"
|
||||
#include "../inc/DefaultSettings.h"
|
||||
#include "../inc/cppwinrt_utils.h"
|
||||
#include "../../tsf/Handle.h"
|
||||
|
||||
#include "ControlCore.h"
|
||||
#include "ControlInteractivity.h"
|
||||
|
||||
#include <windowsx.h>
|
||||
|
||||
#pragma warning(disable : 4100)
|
||||
|
||||
#define HARDCODED_PROPERTY(type, name, ...) \
|
||||
type name() const \
|
||||
{ \
|
||||
return type{ __VA_ARGS__ }; \
|
||||
} \
|
||||
void name(const type&) \
|
||||
{ \
|
||||
}
|
||||
|
||||
using namespace winrt::Microsoft::Terminal::Control;
|
||||
using namespace winrt::Microsoft::Terminal::Core;
|
||||
using CKS = ::Microsoft::Terminal::Core::ControlKeyStates;
|
||||
|
||||
static CKS getControlKeyState() noexcept
|
||||
{
|
||||
struct KeyModifier
|
||||
{
|
||||
int vkey;
|
||||
CKS flags;
|
||||
};
|
||||
|
||||
constexpr std::array<KeyModifier, 5> modifiers{ {
|
||||
{ VK_RMENU, CKS::RightAltPressed },
|
||||
{ VK_LMENU, CKS::LeftAltPressed },
|
||||
{ VK_RCONTROL, CKS::RightCtrlPressed },
|
||||
{ VK_LCONTROL, CKS::LeftCtrlPressed },
|
||||
{ VK_SHIFT, CKS::ShiftPressed },
|
||||
} };
|
||||
|
||||
CKS flags;
|
||||
|
||||
for (const auto& mod : modifiers)
|
||||
{
|
||||
const auto state = GetKeyState(mod.vkey);
|
||||
const auto isDown = state < 0;
|
||||
|
||||
if (isDown)
|
||||
{
|
||||
flags |= mod.flags;
|
||||
}
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static MouseButtonState MouseButtonStateFromWParam(WPARAM wParam)
|
||||
{
|
||||
MouseButtonState state{};
|
||||
WI_UpdateFlag(state, MouseButtonState::IsLeftButtonDown, WI_IsFlagSet(wParam, MK_LBUTTON));
|
||||
WI_UpdateFlag(state, MouseButtonState::IsMiddleButtonDown, WI_IsFlagSet(wParam, MK_MBUTTON));
|
||||
WI_UpdateFlag(state, MouseButtonState::IsRightButtonDown, WI_IsFlagSet(wParam, MK_RBUTTON));
|
||||
return state;
|
||||
}
|
||||
|
||||
static Point PointFromLParam(LPARAM lParam)
|
||||
{
|
||||
return { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
||||
}
|
||||
|
||||
struct CsBridgeConnection : public winrt::implements<CsBridgeConnection, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection>
|
||||
{
|
||||
void Initialize(IInspectable x) {}
|
||||
void Start() {}
|
||||
void WriteInput(winrt::array_view<const char16_t> d)
|
||||
{
|
||||
if (_pfnWriteCallback)
|
||||
{
|
||||
_pfnWriteCallback(reinterpret_cast<const wchar_t*>(d.data()));
|
||||
}
|
||||
}
|
||||
void Resize(uint32_t r, uint32_t c) {}
|
||||
void Close() {}
|
||||
winrt::Microsoft::Terminal::TerminalConnection::ConnectionState State() const noexcept { return winrt::Microsoft::Terminal::TerminalConnection::ConnectionState::Connected; }
|
||||
WINRT_CALLBACK(TerminalOutput, winrt::Microsoft::Terminal::TerminalConnection::TerminalOutputHandler);
|
||||
|
||||
TYPED_EVENT(StateChanged, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection, winrt::Windows::Foundation::IInspectable);
|
||||
|
||||
public:
|
||||
HARDCODED_PROPERTY(winrt::guid, SessionId, winrt::guid{});
|
||||
|
||||
public:
|
||||
PWRITECB _pfnWriteCallback{ nullptr };
|
||||
void OriginateOutputFromConnection(const wchar_t* data)
|
||||
{
|
||||
std::wstring_view wsv{ data };
|
||||
_TerminalOutputHandlers(winrt::array_view<const char16_t>(reinterpret_cast<const char16_t*>(wsv.data()), static_cast<uint32_t>(wsv.size())));
|
||||
}
|
||||
};
|
||||
|
||||
struct CsBridgeTerminalSettings : winrt::implements<CsBridgeTerminalSettings, IControlSettings, ICoreSettings, IControlAppearance, ICoreAppearance, ICoreScheme>
|
||||
{
|
||||
using IFontAxesMap = winrt::Windows::Foundation::Collections::IMap<winrt::hstring, float>;
|
||||
using IFontFeatureMap = winrt::Windows::Foundation::Collections::IMap<winrt::hstring, float>;
|
||||
CsBridgeTerminalSettings()
|
||||
{
|
||||
const auto campbellSpan = Microsoft::Console::Utils::CampbellColorTable();
|
||||
std::transform(campbellSpan.begin(), campbellSpan.end(), std::begin(_theme.ColorTable), [](auto&& color) {
|
||||
return color;
|
||||
});
|
||||
}
|
||||
~CsBridgeTerminalSettings() = default;
|
||||
|
||||
void GetColorTable(winrt::com_array<::winrt::Microsoft::Terminal::Core::Color>& table) noexcept
|
||||
{
|
||||
std::array<winrt::Microsoft::Terminal::Core::Color, COLOR_TABLE_SIZE> colorTable{};
|
||||
std::transform(&_theme.ColorTable[0], &_theme.ColorTable[16], colorTable.begin(), [](auto&& color) {
|
||||
return static_cast<winrt::Microsoft::Terminal::Core::Color>(til::color{ color });
|
||||
});
|
||||
|
||||
table = winrt::com_array(colorTable.begin(), colorTable.end());
|
||||
}
|
||||
|
||||
til::color DefaultForeground() const
|
||||
{
|
||||
return _theme.DefaultForeground;
|
||||
}
|
||||
til::color DefaultBackground() const
|
||||
{
|
||||
return _theme.DefaultBackground;
|
||||
}
|
||||
til::color SelectionBackground() const
|
||||
{
|
||||
return til::color{ _theme.DefaultSelectionBackground };
|
||||
}
|
||||
winrt::hstring FontFace() const
|
||||
{
|
||||
return _fontFace;
|
||||
}
|
||||
float FontSize() const
|
||||
{
|
||||
return _fontSize;
|
||||
}
|
||||
winrt::Microsoft::Terminal::Core::CursorStyle CursorShape() const
|
||||
{
|
||||
return static_cast<winrt::Microsoft::Terminal::Core::CursorStyle>(_theme.CursorStyle);
|
||||
}
|
||||
|
||||
void DefaultForeground(const til::color&) {}
|
||||
void DefaultBackground(const til::color&) {}
|
||||
void SelectionBackground(const til::color&) {}
|
||||
void FontFace(const winrt::hstring&) {}
|
||||
void FontSize(const float&) {}
|
||||
void CursorShape(const winrt::Microsoft::Terminal::Core::CursorStyle&) {}
|
||||
|
||||
HARDCODED_PROPERTY(int32_t, HistorySize, DEFAULT_HISTORY_SIZE);
|
||||
HARDCODED_PROPERTY(int32_t, InitialRows, 30);
|
||||
HARDCODED_PROPERTY(int32_t, InitialCols, 80);
|
||||
HARDCODED_PROPERTY(bool, SnapOnInput, true);
|
||||
HARDCODED_PROPERTY(bool, AltGrAliasing, true);
|
||||
HARDCODED_PROPERTY(til::color, CursorColor, DEFAULT_CURSOR_COLOR);
|
||||
HARDCODED_PROPERTY(uint32_t, CursorHeight, DEFAULT_CURSOR_HEIGHT);
|
||||
HARDCODED_PROPERTY(winrt::hstring, WordDelimiters, DEFAULT_WORD_DELIMITERS);
|
||||
HARDCODED_PROPERTY(bool, CopyOnSelect, false);
|
||||
HARDCODED_PROPERTY(bool, InputServiceWarning, true);
|
||||
HARDCODED_PROPERTY(bool, FocusFollowMouse, false);
|
||||
HARDCODED_PROPERTY(bool, TrimBlockSelection, false);
|
||||
HARDCODED_PROPERTY(bool, DetectURLs, true);
|
||||
HARDCODED_PROPERTY(winrt::Windows::Foundation::IReference<winrt::Microsoft::Terminal::Core::Color>, TabColor, nullptr);
|
||||
HARDCODED_PROPERTY(winrt::Windows::Foundation::IReference<winrt::Microsoft::Terminal::Core::Color>, StartingTabColor, nullptr);
|
||||
HARDCODED_PROPERTY(bool, UseAcrylic, false);
|
||||
HARDCODED_PROPERTY(float, Opacity, 1.0);
|
||||
HARDCODED_PROPERTY(winrt::hstring, Padding, DEFAULT_PADDING);
|
||||
HARDCODED_PROPERTY(winrt::Windows::UI::Text::FontWeight, FontWeight, winrt::Windows::UI::Text::FontWeight{ 400 });
|
||||
HARDCODED_PROPERTY(IFontAxesMap, FontAxes);
|
||||
HARDCODED_PROPERTY(IFontFeatureMap, FontFeatures);
|
||||
HARDCODED_PROPERTY(winrt::hstring, BackgroundImage);
|
||||
HARDCODED_PROPERTY(float, BackgroundImageOpacity, 1.0);
|
||||
HARDCODED_PROPERTY(winrt::Windows::UI::Xaml::Media::Stretch, BackgroundImageStretchMode, winrt::Windows::UI::Xaml::Media::Stretch::UniformToFill);
|
||||
HARDCODED_PROPERTY(winrt::Windows::UI::Xaml::HorizontalAlignment, BackgroundImageHorizontalAlignment, winrt::Windows::UI::Xaml::HorizontalAlignment::Center);
|
||||
HARDCODED_PROPERTY(winrt::Windows::UI::Xaml::VerticalAlignment, BackgroundImageVerticalAlignment, winrt::Windows::UI::Xaml::VerticalAlignment::Center);
|
||||
HARDCODED_PROPERTY(winrt::hstring, Commandline);
|
||||
HARDCODED_PROPERTY(winrt::hstring, StartingDirectory);
|
||||
HARDCODED_PROPERTY(winrt::hstring, StartingTitle);
|
||||
HARDCODED_PROPERTY(bool, SuppressApplicationTitle);
|
||||
HARDCODED_PROPERTY(winrt::hstring, EnvironmentVariables);
|
||||
HARDCODED_PROPERTY(winrt::Microsoft::Terminal::Control::ScrollbarState, ScrollState, winrt::Microsoft::Terminal::Control::ScrollbarState::Visible);
|
||||
HARDCODED_PROPERTY(winrt::Microsoft::Terminal::Control::TextAntialiasingMode, AntialiasingMode, winrt::Microsoft::Terminal::Control::TextAntialiasingMode::Grayscale);
|
||||
HARDCODED_PROPERTY(bool, RetroTerminalEffect, false);
|
||||
HARDCODED_PROPERTY(bool, ForceFullRepaintRendering, false);
|
||||
HARDCODED_PROPERTY(bool, SoftwareRendering, false);
|
||||
HARDCODED_PROPERTY(bool, ForceVTInput, false);
|
||||
HARDCODED_PROPERTY(winrt::hstring, PixelShaderPath);
|
||||
HARDCODED_PROPERTY(winrt::hstring, PixelShaderImagePath);
|
||||
HARDCODED_PROPERTY(bool, IntenseIsBright);
|
||||
HARDCODED_PROPERTY(bool, IntenseIsBold);
|
||||
HARDCODED_PROPERTY(bool, ShowMarks);
|
||||
HARDCODED_PROPERTY(bool, UseBackgroundImageForWindow);
|
||||
HARDCODED_PROPERTY(bool, AutoMarkPrompts);
|
||||
HARDCODED_PROPERTY(bool, VtPassthrough);
|
||||
HARDCODED_PROPERTY(bool, UseAtlasEngine, false);
|
||||
HARDCODED_PROPERTY(AdjustTextMode, AdjustIndistinguishableColors, AdjustTextMode::Never);
|
||||
HARDCODED_PROPERTY(bool, RightClickContextMenu, false);
|
||||
HARDCODED_PROPERTY(winrt::hstring, CellWidth, L"");
|
||||
HARDCODED_PROPERTY(winrt::hstring, CellHeight, L"");
|
||||
HARDCODED_PROPERTY(bool, RepositionCursorWithMouse, false);
|
||||
HARDCODED_PROPERTY(bool, EnableUnfocusedAcrylic, false);
|
||||
HARDCODED_PROPERTY(bool, RainbowSuggestions, false);
|
||||
HARDCODED_PROPERTY(bool, AllowVtClipboardWrite, true);
|
||||
HARDCODED_PROPERTY(bool, AllowVtChecksumReport, false);
|
||||
HARDCODED_PROPERTY(winrt::hstring, AnswerbackMessage, L"");
|
||||
HARDCODED_PROPERTY(winrt::Microsoft::Terminal::Control::PathTranslationStyle, PathTranslationStyle, winrt::Microsoft::Terminal::Control::PathTranslationStyle::None);
|
||||
HARDCODED_PROPERTY(winrt::Microsoft::Terminal::Control::DefaultInputScope, DefaultInputScope, winrt::Microsoft::Terminal::Control::DefaultInputScope::Default);
|
||||
HARDCODED_PROPERTY(winrt::Microsoft::Terminal::Control::TextMeasurement, TextMeasurement, winrt::Microsoft::Terminal::Control::TextMeasurement::Graphemes);
|
||||
HARDCODED_PROPERTY(bool, DisablePartialInvalidation, false);
|
||||
HARDCODED_PROPERTY(winrt::Microsoft::Terminal::Control::GraphicsAPI, GraphicsAPI, winrt::Microsoft::Terminal::Control::GraphicsAPI::Automatic);
|
||||
HARDCODED_PROPERTY(winrt::Microsoft::Terminal::Control::CopyFormat, CopyFormatting, winrt::Microsoft::Terminal::Control::CopyFormat::All);
|
||||
HARDCODED_PROPERTY(bool, EnableColorGlyphs, true);
|
||||
HARDCODED_PROPERTY(bool, EnableBuiltinGlyphs, true);
|
||||
HARDCODED_PROPERTY(bool, AllowKittyKeyboardMode, true);
|
||||
HARDCODED_PROPERTY(winrt::hstring, DragDropDelimiter, L" ");
|
||||
HARDCODED_PROPERTY(winrt::Microsoft::Terminal::Control::AmbiguousWidth, AmbiguousWidth, winrt::Microsoft::Terminal::Control::AmbiguousWidth::Narrow);
|
||||
HARDCODED_PROPERTY(bool, ScrollToChangeOpacity, false);
|
||||
HARDCODED_PROPERTY(bool, ScrollToZoom, false);
|
||||
HARDCODED_PROPERTY(winrt::guid, SessionId, winrt::guid{});
|
||||
|
||||
public:
|
||||
void SetTheme(TerminalTheme theme, LPCWSTR fontFamily, til::CoordType fontSize, int newDpi)
|
||||
{
|
||||
_theme = std::move(theme);
|
||||
_fontFace = fontFamily;
|
||||
_fontSize = static_cast<float>(fontSize);
|
||||
}
|
||||
|
||||
private:
|
||||
TerminalTheme _theme;
|
||||
winrt::hstring _fontFace{ L"Cascadia Mono" };
|
||||
float _fontSize = 12.0f;
|
||||
};
|
||||
|
||||
struct HwndTerminal
|
||||
{
|
||||
static constexpr LPCWSTR term_window_class = L"HwndTerminalClass";
|
||||
|
||||
static LRESULT CALLBACK HwndTerminalWndProc(
|
||||
HWND hwnd,
|
||||
UINT uMsg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam) noexcept
|
||||
try
|
||||
{
|
||||
#pragma warning(suppress : 26490) // Win32 APIs can only store void*, have to use reinterpret_cast
|
||||
HwndTerminal* terminal = reinterpret_cast<HwndTerminal*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
|
||||
if (terminal)
|
||||
{
|
||||
return terminal->WindowProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_CAUGHT_EXCEPTION();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool RegisterTermClass(HINSTANCE hInstance) noexcept
|
||||
{
|
||||
WNDCLASSW wc;
|
||||
if (GetClassInfoW(hInstance, term_window_class, &wc))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
wc.style = 0;
|
||||
wc.lpfnWndProc = HwndTerminal::HwndTerminalWndProc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = hInstance;
|
||||
wc.hIcon = nullptr;
|
||||
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||
wc.hbrBackground = nullptr;
|
||||
wc.lpszMenuName = nullptr;
|
||||
wc.lpszClassName = term_window_class;
|
||||
|
||||
return RegisterClassW(&wc) != 0;
|
||||
}
|
||||
|
||||
LRESULT WindowProc(
|
||||
HWND hwnd,
|
||||
UINT uMsg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam) noexcept
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_RBUTTONDOWN:
|
||||
SetCapture(_hwnd.get());
|
||||
_interactivity->PointerPressed(
|
||||
0, // Mouse
|
||||
MouseButtonStateFromWParam(wParam),
|
||||
uMsg,
|
||||
std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count(),
|
||||
getControlKeyState(),
|
||||
PointFromLParam(lParam));
|
||||
return 0;
|
||||
case WM_MOUSEMOVE:
|
||||
_interactivity->PointerMoved(
|
||||
0, // Mouse
|
||||
MouseButtonStateFromWParam(wParam),
|
||||
WM_MOUSEMOVE,
|
||||
getControlKeyState(),
|
||||
PointFromLParam(lParam));
|
||||
return 0;
|
||||
case WM_LBUTTONUP:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
_interactivity->PointerReleased(
|
||||
0, // Mouse
|
||||
MouseButtonStateFromWParam(wParam),
|
||||
uMsg,
|
||||
getControlKeyState(),
|
||||
PointFromLParam(lParam));
|
||||
ReleaseCapture();
|
||||
return 0;
|
||||
case WM_POINTERDOWN:
|
||||
if (!IS_POINTER_INCONTACT_WPARAM(wParam))
|
||||
{
|
||||
break;
|
||||
}
|
||||
SetCapture(_hwnd.get());
|
||||
_interactivity->TouchPressed(PointFromLParam(lParam));
|
||||
return 0;
|
||||
case WM_POINTERUPDATE:
|
||||
if (!IS_POINTER_INCONTACT_WPARAM(wParam))
|
||||
{
|
||||
break;
|
||||
}
|
||||
_interactivity->TouchMoved(PointFromLParam(lParam));
|
||||
return 0;
|
||||
case WM_POINTERUP:
|
||||
if (!IS_POINTER_INCONTACT_WPARAM(wParam))
|
||||
{
|
||||
break;
|
||||
}
|
||||
_interactivity->TouchReleased();
|
||||
ReleaseCapture();
|
||||
return 0;
|
||||
case WM_MOUSEWHEEL:
|
||||
case WM_MOUSEHWHEEL:
|
||||
{
|
||||
winrt::Microsoft::Terminal::Core::Point delta{ 0, GET_WHEEL_DELTA_WPARAM(wParam) };
|
||||
if (uMsg == WM_MOUSEHWHEEL)
|
||||
{
|
||||
std::swap(delta.X, delta.Y);
|
||||
}
|
||||
|
||||
if (_interactivity->MouseWheel(getControlKeyState(), delta, PointFromLParam(lParam), MouseButtonStateFromWParam(wParam)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_SETFOCUS:
|
||||
_interactivity->GotFocus();
|
||||
_focused = true;
|
||||
_core->ApplyAppearance(_focused);
|
||||
break;
|
||||
case WM_KILLFOCUS:
|
||||
_interactivity->LostFocus();
|
||||
_focused = true;
|
||||
_core->ApplyAppearance(_focused);
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
wil::unique_hwnd _hwnd;
|
||||
|
||||
HwndTerminal(HWND parentHwnd)
|
||||
{
|
||||
HINSTANCE hInstance = wil::GetModuleInstanceHandle();
|
||||
|
||||
if (RegisterTermClass(hInstance))
|
||||
{
|
||||
_hwnd.reset(CreateWindowExW(
|
||||
0,
|
||||
term_window_class,
|
||||
nullptr,
|
||||
WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
parentHwnd,
|
||||
nullptr,
|
||||
hInstance,
|
||||
nullptr));
|
||||
|
||||
#pragma warning(suppress : 26490) // Win32 APIs can only store void*, so we have to use reinterpret_cast
|
||||
SetWindowLongPtr(_hwnd.get(), GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
|
||||
}
|
||||
|
||||
_settingsBridge = winrt::make_self<CsBridgeTerminalSettings>();
|
||||
_connection = winrt::make_self<CsBridgeConnection>();
|
||||
_interactivity = winrt::make_self<implementation::ControlInteractivity>(*_settingsBridge, nullptr, *_connection);
|
||||
_core.copy_from(winrt::get_self<implementation::ControlCore>(_interactivity->Core()));
|
||||
|
||||
_core->ScrollPositionChanged({ this, &HwndTerminal::_scrollPositionChanged });
|
||||
_interactivity->ScrollPositionChanged({ this, &HwndTerminal::_scrollPositionChanged });
|
||||
}
|
||||
|
||||
/*( PUBLIC API )*/
|
||||
HRESULT SendOutput(LPCWSTR data)
|
||||
{
|
||||
_connection->OriginateOutputFromConnection(data);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT RegisterScrollCallback(PSCROLLCB callback)
|
||||
{
|
||||
_scrollCallback = callback;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT TriggerResize(_In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions)
|
||||
{
|
||||
if (!_initialized)
|
||||
return S_FALSE;
|
||||
|
||||
SetWindowPos(_hwnd.get(), nullptr, 0, 0, width, height, 0);
|
||||
|
||||
// **NOTE** The sizes we get here are unscaled ...
|
||||
auto dpi = GetDpiForWindow(_hwnd.get());
|
||||
float w = static_cast<float>(width * USER_DEFAULT_SCREEN_DPI) / dpi;
|
||||
float h = static_cast<float>(height * USER_DEFAULT_SCREEN_DPI) / dpi;
|
||||
// ... but ControlCore expects scaled sizes.
|
||||
_core->SizeChanged(w, h);
|
||||
|
||||
// TODO(DH): ControlCore has no API that returns the new size in cells
|
||||
//wil::assign_to_opt_param(dimensions, /*thing*/);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT TriggerResizeWithDimension(_In_ til::size dimensions, _Out_ til::size* dimensionsInPixels)
|
||||
{
|
||||
if (!_initialized)
|
||||
return S_FALSE;
|
||||
|
||||
winrt::Windows::Foundation::Size outSizeInPixels;
|
||||
_core->ResizeToDimensions(dimensions.width, dimensions.height, outSizeInPixels);
|
||||
wil::assign_to_opt_param(dimensionsInPixels, til::size{ til::math::rounding, outSizeInPixels });
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CalculateResize(_In_ til::CoordType width, _In_ til::CoordType height, _Out_ til::size* dimensions)
|
||||
{
|
||||
// TODO(DH): It seems weird to have to do this manually.
|
||||
auto fontSizeInPx = _core->FontSize();
|
||||
wil::assign_to_opt_param(dimensions, til::size{
|
||||
static_cast<til::CoordType>(width / fontSizeInPx.Width),
|
||||
static_cast<til::CoordType>(height / fontSizeInPx.Height),
|
||||
});
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT DpiChanged(int newDpi)
|
||||
{
|
||||
_core->ScaleChanged((float)newDpi / 96.0f);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT UserScroll(int viewTop)
|
||||
{
|
||||
_interactivity->UpdateScrollbar(static_cast<float>(viewTop) /* TODO(DH) */);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT GetSelection(const wchar_t** out)
|
||||
{
|
||||
auto strings = _core->SelectedText(true);
|
||||
auto concatenated = std::accumulate(std::begin(strings), std::end(strings), std::wstring{}, [](auto&& l, auto&& r) {
|
||||
return l + r;
|
||||
});
|
||||
auto returnText = wil::make_cotaskmem_string_nothrow(concatenated.c_str());
|
||||
*out = returnText.release();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT IsSelectionActive(bool* out)
|
||||
{
|
||||
*out = _core->HasSelection();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT SetTheme(TerminalTheme theme, LPCWSTR fontFamily, til::CoordType fontSize, int newDpi)
|
||||
{
|
||||
_settingsBridge->SetTheme(theme, fontFamily, fontSize, newDpi);
|
||||
_core->UpdateSettings(*_settingsBridge, nullptr);
|
||||
_interactivity->UpdateSettings();
|
||||
_core->ScaleChanged((static_cast<float>(newDpi) / USER_DEFAULT_SCREEN_DPI));
|
||||
_core->ApplyAppearance(_focused);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT RegisterWriteCallback(PWRITECB callback)
|
||||
{
|
||||
_connection->_pfnWriteCallback = callback;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT SendKeyEvent(WORD vkey, WORD scanCode, WORD flags, bool keyDown)
|
||||
{
|
||||
_core->TrySendKeyEvent(vkey, scanCode, getControlKeyState(), keyDown);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT SendCharEvent(wchar_t ch, WORD flags, WORD scanCode)
|
||||
{
|
||||
_core->SendCharEvent(ch, scanCode, getControlKeyState());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
RECT windowRect;
|
||||
GetWindowRect(_hwnd.get(), &windowRect);
|
||||
auto dpi = GetDpiForWindow(_hwnd.get());
|
||||
// BODGY: the +/-1 is because ControlCore will ignore an Initialize with zero size (oops)
|
||||
// because in the old days, TermControl would accidentally try to resize the Swap Chain to 0x0 (oops)
|
||||
// and therefore resize the connection to 0x0 (oops)
|
||||
_core->InitializeWithHwnd(
|
||||
gsl::narrow_cast<float>(windowRect.right - windowRect.left + 1),
|
||||
gsl::narrow_cast<float>(windowRect.bottom - windowRect.top + 1),
|
||||
(static_cast<float>(dpi) / USER_DEFAULT_SCREEN_DPI),
|
||||
reinterpret_cast<uint64_t>(_hwnd.get()));
|
||||
_interactivity->Initialize();
|
||||
_core->ApplyAppearance(_focused);
|
||||
|
||||
_core->EnablePainting();
|
||||
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
private:
|
||||
winrt::com_ptr<CsBridgeConnection> _connection;
|
||||
winrt::com_ptr<CsBridgeTerminalSettings> _settingsBridge;
|
||||
winrt::com_ptr<implementation::ControlInteractivity> _interactivity{ nullptr };
|
||||
winrt::com_ptr<implementation::ControlCore> _core{ nullptr };
|
||||
bool _initialized{ false };
|
||||
bool _focused{ false };
|
||||
PSCROLLCB _scrollCallback{};
|
||||
|
||||
void _scrollPositionChanged(const winrt::Windows::Foundation::IInspectable& i, const ScrollPositionChangedArgs& update)
|
||||
{
|
||||
if (_scrollCallback)
|
||||
{
|
||||
_scrollCallback(update.ViewTop(), update.ViewHeight(), update.BufferSize());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
extern "C" void _stdcall AvoidBuggyTSFConsoleFlags()
|
||||
{
|
||||
Microsoft::Console::TSF::Handle::AvoidBuggyTSFConsoleFlags();
|
||||
}
|
||||
|
||||
__declspec(dllexport) HRESULT _stdcall CreateTerminal(HWND parentHwnd, _Out_ void** hwnd, _Out_ PTERM* terminal)
|
||||
{
|
||||
auto inner = new HwndTerminal{ parentHwnd };
|
||||
*terminal = inner;
|
||||
*hwnd = inner->_hwnd.get();
|
||||
inner->Initialize();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
__declspec(dllexport) void _stdcall DestroyTerminal(PTERM terminal)
|
||||
{
|
||||
delete (HwndTerminal*)terminal;
|
||||
}
|
||||
|
||||
// Generate all of the C->C++ bridge functions.
|
||||
#define API_NAME(name) Terminal##name
|
||||
#define GENERATOR_0(name) \
|
||||
__declspec(dllexport) HRESULT _stdcall API_NAME(name)(PTERM terminal) \
|
||||
try \
|
||||
{ \
|
||||
return ((HwndTerminal*)(terminal))->name(); \
|
||||
} \
|
||||
CATCH_RETURN()
|
||||
#define GENERATOR_1(name, t1, a1) \
|
||||
__declspec(dllexport) HRESULT _stdcall API_NAME(name)(PTERM terminal, t1 a1) \
|
||||
try \
|
||||
{ \
|
||||
return ((HwndTerminal*)(terminal))->name(a1); \
|
||||
} \
|
||||
CATCH_RETURN()
|
||||
#define GENERATOR_2(name, t1, a1, t2, a2) \
|
||||
__declspec(dllexport) HRESULT _stdcall API_NAME(name)(PTERM terminal, t1 a1, t2 a2) \
|
||||
try \
|
||||
{ \
|
||||
return ((HwndTerminal*)(terminal))->name(a1, a2); \
|
||||
} \
|
||||
CATCH_RETURN()
|
||||
#define GENERATOR_3(name, t1, a1, t2, a2, t3, a3) \
|
||||
__declspec(dllexport) HRESULT _stdcall API_NAME(name)(PTERM terminal, t1 a1, t2 a2, t3 a3) \
|
||||
try \
|
||||
{ \
|
||||
return ((HwndTerminal*)(terminal))->name(a1, a2, a3); \
|
||||
} \
|
||||
CATCH_RETURN()
|
||||
#define GENERATOR_4(name, t1, a1, t2, a2, t3, a3, t4, a4) \
|
||||
__declspec(dllexport) HRESULT _stdcall API_NAME(name)(PTERM terminal, t1 a1, t2 a2, t3 a3, t4 a4) \
|
||||
try \
|
||||
{ \
|
||||
return ((HwndTerminal*)(terminal))->name(a1, a2, a3, a4); \
|
||||
} \
|
||||
CATCH_RETURN()
|
||||
#define GENERATOR_N(name, t1, a1, t2, a2, t3, a3, t4, a4, MACRO, ...) MACRO
|
||||
#define GENERATOR(...) \
|
||||
GENERATOR_N(__VA_ARGS__, GENERATOR_4, GENERATOR_4, GENERATOR_3, GENERATOR_3, GENERATOR_2, GENERATOR_2, GENERATOR_1, GENERATOR_1, GENERATOR_0) \
|
||||
(__VA_ARGS__)
|
||||
TERMINAL_API_TABLE(GENERATOR)
|
||||
#undef GENERATOR_0
|
||||
#undef GENERATOR_1
|
||||
#undef GENERATOR_2
|
||||
#undef GENERATOR_3
|
||||
#undef GENERATOR_4
|
||||
#undef GENERATOR_N
|
||||
#undef GENERATOR
|
||||
|
||||
#undef API_NAME
|
||||
@@ -1,63 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Keep in sync with TerminalTheme.cs
|
||||
typedef struct _TerminalTheme
|
||||
{
|
||||
COLORREF DefaultBackground;
|
||||
COLORREF DefaultForeground;
|
||||
COLORREF DefaultSelectionBackground;
|
||||
uint32_t CursorStyle; // This will be converted to DispatchTypes::CursorStyle (size_t), but C# cannot marshal an enum type and have it fit in a size_t.
|
||||
COLORREF ColorTable[16];
|
||||
} TerminalTheme;
|
||||
|
||||
using PTERM = void*;
|
||||
using PSCROLLCB = void(_stdcall*)(int, int, int);
|
||||
using PWRITECB = void(_stdcall*)(const wchar_t*);
|
||||
|
||||
#define TERMINAL_API_TABLE(XX) \
|
||||
XX(SendOutput, LPCWSTR, data) \
|
||||
XX(RegisterScrollCallback, PSCROLLCB, callback) \
|
||||
XX(TriggerResize, _In_ til::CoordType, width, _In_ til::CoordType, height, _Out_ til::size*, dimensions) \
|
||||
XX(TriggerResizeWithDimension, _In_ til::size, dimensions, _Out_ til::size*, dimensionsInPixels) \
|
||||
XX(CalculateResize, _In_ til::CoordType, width, _In_ til::CoordType, height, _Out_ til::size*, dimensions) \
|
||||
XX(DpiChanged, int, newDpi) \
|
||||
XX(UserScroll, int, viewTop) \
|
||||
XX(GetSelection, const wchar_t**, out) \
|
||||
XX(IsSelectionActive, bool*, out) \
|
||||
XX(SetTheme, TerminalTheme, theme, LPCWSTR, fontFamily, til::CoordType, fontSize, int, newDpi) \
|
||||
XX(RegisterWriteCallback, PWRITECB, callback) \
|
||||
XX(SendKeyEvent, WORD, vkey, WORD, scanCode, WORD, flags, bool, keyDown) \
|
||||
XX(SendCharEvent, wchar_t, ch, WORD, flags, WORD, scanCode)
|
||||
|
||||
extern "C" {
|
||||
#define API_NAME(name) Terminal##name
|
||||
#define GENERATOR_0(name) \
|
||||
__declspec(dllexport) HRESULT _stdcall API_NAME(name)(PTERM);
|
||||
#define GENERATOR_1(name, t1, a1) \
|
||||
__declspec(dllexport) HRESULT _stdcall API_NAME(name)(PTERM, t1);
|
||||
#define GENERATOR_2(name, t1, a1, t2, a2) \
|
||||
__declspec(dllexport) HRESULT _stdcall API_NAME(name)(PTERM, t1, t2);
|
||||
#define GENERATOR_3(name, t1, a1, t2, a2, t3, a3) \
|
||||
__declspec(dllexport) HRESULT _stdcall API_NAME(name)(PTERM, t1, t2, t3);
|
||||
#define GENERATOR_4(name, t1, a1, t2, a2, t3, a3, t4, a4) \
|
||||
__declspec(dllexport) HRESULT _stdcall API_NAME(name)(PTERM, t1, t2, t3, t4);
|
||||
#define GENERATOR_N(name, t1, a1, t2, a2, t3, a3, t4, a4, MACRO, ...) MACRO
|
||||
#define GENERATOR(...) \
|
||||
GENERATOR_N(__VA_ARGS__, GENERATOR_4, GENERATOR_4, GENERATOR_3, GENERATOR_3, GENERATOR_2, GENERATOR_2, GENERATOR_1, GENERATOR_1, GENERATOR_0) \
|
||||
(__VA_ARGS__)
|
||||
TERMINAL_API_TABLE(GENERATOR)
|
||||
#undef GENERATOR
|
||||
#undef GENERATOR_0
|
||||
#undef GENERATOR_1
|
||||
#undef GENERATOR_2
|
||||
#undef GENERATOR_3
|
||||
#undef GENERATOR_4
|
||||
#undef GENERATOR_N
|
||||
#undef API_NAME
|
||||
|
||||
__declspec(dllexport) HRESULT _stdcall CreateTerminal(HWND parentHwnd, _Out_ void** hwnd, _Out_ PTERM* terminal);
|
||||
__declspec(dllexport) void _stdcall DestroyTerminal(PTERM terminal);
|
||||
};
|
||||
@@ -272,6 +272,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
TermControl::TermControl(Control::ControlInteractivity content) :
|
||||
_interactivity{ content },
|
||||
_isInternalScrollBarUpdate{ false },
|
||||
_autoScrollVelocity{ 0 },
|
||||
_autoScrollingPointerPoint{ std::nullopt },
|
||||
_lastAutoScrollUpdateTime{ std::nullopt },
|
||||
_searchBox{ nullptr }
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -391,6 +394,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_revokers.coreScrollPositionChanged = _core.ScrollPositionChanged(winrt::auto_revoke, { get_weak(), &TermControl::_ScrollPositionChanged });
|
||||
_revokers.WarningBell = _core.WarningBell(winrt::auto_revoke, { get_weak(), &TermControl::_coreWarningBell });
|
||||
|
||||
static constexpr auto AutoScrollUpdateInterval = std::chrono::microseconds(static_cast<int>(1.0 / 30.0 * 1000000));
|
||||
_autoScrollTimer.Interval(AutoScrollUpdateInterval);
|
||||
_autoScrollTimer.Tick({ get_weak(), &TermControl::_UpdateAutoScroll });
|
||||
|
||||
_ApplyUISettings();
|
||||
|
||||
_originalPrimaryElements = winrt::single_threaded_observable_vector<Controls::ICommandBarElement>();
|
||||
@@ -1928,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:
|
||||
@@ -1974,6 +1979,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
Focus(FocusState::Pointer);
|
||||
}
|
||||
|
||||
// Mark that this pointer event actually started within our bounds.
|
||||
// We'll need this later, for PointerMoved events.
|
||||
_pointerPressedInBounds = true;
|
||||
|
||||
if (type == Windows::Devices::Input::PointerDeviceType::Touch)
|
||||
{
|
||||
// NB: I don't think this is correct because the touch should be in the center of the rect.
|
||||
@@ -2030,7 +2039,40 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
TermControl::GetPointerUpdateKind(point),
|
||||
ControlKeyStates(args.KeyModifiers()),
|
||||
pixelPosition);
|
||||
/* TODO(DH) */ UNREFERENCED_PARAMETER(suppressFurtherHandling);
|
||||
|
||||
// GH#9109 - Only start an auto-scroll when the drag actually
|
||||
// started within our bounds. Otherwise, someone could start a drag
|
||||
// outside the terminal control, drag into the padding, and trick us
|
||||
// into starting to scroll.
|
||||
if (!suppressFurtherHandling && _focused && _pointerPressedInBounds && point.Properties().IsLeftButtonPressed())
|
||||
{
|
||||
// We want to find the distance relative to the bounds of the
|
||||
// SwapChainPanel, not the entire control. If they drag out of
|
||||
// the bounds of the text, into the padding, we still what that
|
||||
// to auto-scroll
|
||||
const auto cursorBelowBottomDist = cursorPosition.Y - SwapChainPanel().Margin().Top - SwapChainPanel().ActualHeight();
|
||||
const auto cursorAboveTopDist = -1 * cursorPosition.Y + SwapChainPanel().Margin().Top;
|
||||
|
||||
constexpr auto MinAutoScrollDist = 2.0; // Arbitrary value
|
||||
auto newAutoScrollVelocity = 0.0;
|
||||
if (cursorBelowBottomDist > MinAutoScrollDist)
|
||||
{
|
||||
newAutoScrollVelocity = _GetAutoScrollSpeed(cursorBelowBottomDist);
|
||||
}
|
||||
else if (cursorAboveTopDist > MinAutoScrollDist)
|
||||
{
|
||||
newAutoScrollVelocity = -1.0 * _GetAutoScrollSpeed(cursorAboveTopDist);
|
||||
}
|
||||
|
||||
if (newAutoScrollVelocity != 0)
|
||||
{
|
||||
_TryStartAutoScroll(point, newAutoScrollVelocity);
|
||||
}
|
||||
else
|
||||
{
|
||||
_TryStopAutoScroll(ptr.PointerId());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type == Windows::Devices::Input::PointerDeviceType::Touch)
|
||||
{
|
||||
@@ -2057,6 +2099,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return;
|
||||
}
|
||||
|
||||
_pointerPressedInBounds = false;
|
||||
|
||||
const auto ptr = args.Pointer();
|
||||
const auto point = args.GetCurrentPoint(*this);
|
||||
const auto cursorPosition = point.Position();
|
||||
@@ -2079,6 +2123,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_interactivity.TouchReleased();
|
||||
}
|
||||
|
||||
_TryStopAutoScroll(ptr.PointerId());
|
||||
|
||||
args.Handled(true);
|
||||
}
|
||||
|
||||
@@ -2233,6 +2279,86 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return false;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Starts new pointer related auto scroll behavior, or continues existing one.
|
||||
// Does nothing when there is already auto scroll associated with another pointer.
|
||||
// Arguments:
|
||||
// - pointerPoint: info about pointer that causes auto scroll. Pointer's position
|
||||
// is later used to update selection.
|
||||
// - scrollVelocity: target velocity of scrolling in characters / sec
|
||||
void TermControl::_TryStartAutoScroll(const Windows::UI::Input::PointerPoint& pointerPoint, const double scrollVelocity)
|
||||
{
|
||||
// Allow only one pointer at the time
|
||||
if (!_autoScrollingPointerPoint ||
|
||||
_autoScrollingPointerPoint->PointerId() == pointerPoint.PointerId())
|
||||
{
|
||||
_autoScrollingPointerPoint = pointerPoint;
|
||||
_autoScrollVelocity = scrollVelocity;
|
||||
|
||||
// If this is first time the auto scroll update is about to be called,
|
||||
// kick-start it by initializing its time delta as if it started now
|
||||
if (!_lastAutoScrollUpdateTime)
|
||||
{
|
||||
_lastAutoScrollUpdateTime = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
// Apparently this check is not necessary but greatly improves performance
|
||||
if (!_autoScrollTimer.IsEnabled())
|
||||
{
|
||||
_autoScrollTimer.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Stops auto scroll if it's active and is associated with supplied pointer id.
|
||||
// Arguments:
|
||||
// - pointerId: id of pointer for which to stop auto scroll
|
||||
void TermControl::_TryStopAutoScroll(const uint32_t pointerId)
|
||||
{
|
||||
if (_autoScrollingPointerPoint &&
|
||||
pointerId == _autoScrollingPointerPoint->PointerId())
|
||||
{
|
||||
_autoScrollingPointerPoint = std::nullopt;
|
||||
_autoScrollVelocity = 0;
|
||||
_lastAutoScrollUpdateTime = std::nullopt;
|
||||
|
||||
// Apparently this check is not necessary but greatly improves performance
|
||||
if (_autoScrollTimer.IsEnabled())
|
||||
{
|
||||
_autoScrollTimer.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Called continuously to gradually scroll viewport when user is mouse
|
||||
// selecting outside it (to 'follow' the cursor).
|
||||
// Arguments:
|
||||
// - none
|
||||
void TermControl::_UpdateAutoScroll(const Windows::Foundation::IInspectable& /* sender */,
|
||||
const Windows::Foundation::IInspectable& /* e */)
|
||||
{
|
||||
if (_autoScrollVelocity != 0)
|
||||
{
|
||||
const auto timeNow = std::chrono::high_resolution_clock::now();
|
||||
|
||||
if (_lastAutoScrollUpdateTime)
|
||||
{
|
||||
static constexpr auto microSecPerSec = 1000000.0;
|
||||
const auto deltaTime = std::chrono::duration_cast<std::chrono::microseconds>(timeNow - *_lastAutoScrollUpdateTime).count() / microSecPerSec;
|
||||
ScrollBar().Value(ScrollBar().Value() + _autoScrollVelocity * deltaTime);
|
||||
|
||||
if (_autoScrollingPointerPoint)
|
||||
{
|
||||
_SetEndSelectionPointAtCursor(_autoScrollingPointerPoint->Position());
|
||||
}
|
||||
}
|
||||
|
||||
_lastAutoScrollUpdateTime = timeNow;
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Event handler for the GotFocus event. This is used to...
|
||||
// - enable accessibility notifications for this TermControl
|
||||
@@ -2367,6 +2493,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_core.ScaleChanged(scaleX);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Sets selection's end position to match supplied cursor position, e.g. while mouse dragging.
|
||||
// Arguments:
|
||||
// - cursorPosition: in pixels, relative to the origin of the control
|
||||
void TermControl::_SetEndSelectionPointAtCursor(const Windows::Foundation::Point& cursorPosition)
|
||||
{
|
||||
_interactivity.SetEndSelectionPoint(_toTerminalOrigin(cursorPosition));
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Update the position and size of the scrollbar to match the given
|
||||
// viewport top, viewport height, and buffer size.
|
||||
@@ -2524,6 +2659,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// On Win10 we don't destroy window threads due to bugs in DesktopWindowXamlSource.
|
||||
// In turn, we leak TermControl instances. This results in constant HWND messages
|
||||
// while the thread is supposed to be idle. Stop these timers avoids this.
|
||||
_autoScrollTimer.Stop();
|
||||
_bellLightTimer.Stop();
|
||||
|
||||
// This is absolutely crucial, as the TSF code tries to hold a strong reference to _tsfDataProvider,
|
||||
@@ -2671,8 +2807,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
// UWP XAML scrollbars aren't guaranteed to be the same size as the
|
||||
// ComCtl scrollbars, but it's certainly close enough.
|
||||
auto scrollbarSize = GetSystemMetrics(SM_CXVSCROLL);
|
||||
scrollbarSize = gsl::narrow_cast<decltype(scrollbarSize)>(scrollbarSize * (dpi / 96));
|
||||
const auto scrollbarSize = GetSystemMetricsForDpi(SM_CXVSCROLL, dpi);
|
||||
|
||||
float width = cols * static_cast<float>(actualFontSize.width);
|
||||
|
||||
@@ -2771,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 };
|
||||
}
|
||||
}
|
||||
@@ -2922,6 +3055,20 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
};
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Calculates speed of single axis of auto scrolling. It has to allow for both
|
||||
// fast and precise selection.
|
||||
// Arguments:
|
||||
// - cursorDistanceFromBorder: distance from viewport border to cursor, in pixels. Must be non-negative.
|
||||
// Return Value:
|
||||
// - positive speed in characters / sec
|
||||
double TermControl::_GetAutoScrollSpeed(double cursorDistanceFromBorder) const
|
||||
{
|
||||
// The numbers below just feel well, feel free to change.
|
||||
// TODO: Maybe account for space beyond border that user has available
|
||||
return std::pow(cursorDistanceFromBorder, 2.0) / 25.0 + 2.0;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Async handler for the "Drop" event. If a file was dropped onto our
|
||||
// root, we'll try to get the path of the file dropped onto us, and write
|
||||
|
||||
@@ -300,6 +300,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
bool _isInternalScrollBarUpdate;
|
||||
|
||||
// Auto scroll occurs when user, while selecting, drags cursor outside
|
||||
// viewport. View is then scrolled to 'follow' the cursor.
|
||||
double _autoScrollVelocity;
|
||||
std::optional<Windows::UI::Input::PointerPoint> _autoScrollingPointerPoint;
|
||||
SafeDispatcherTimer _autoScrollTimer;
|
||||
std::optional<std::chrono::high_resolution_clock::time_point> _lastAutoScrollUpdateTime;
|
||||
bool _pointerPressedInBounds{ false };
|
||||
|
||||
winrt::Windows::UI::Composition::ScalarKeyFrameAnimation _bellLightAnimation{ nullptr };
|
||||
winrt::Windows::UI::Composition::ScalarKeyFrameAnimation _bellDarkAnimation{ nullptr };
|
||||
SafeDispatcherTimer _bellLightTimer;
|
||||
@@ -377,6 +385,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
void _BellLightOff(const Windows::Foundation::IInspectable& sender, const Windows::Foundation::IInspectable& e);
|
||||
|
||||
void _SetEndSelectionPointAtCursor(const Windows::Foundation::Point& cursorPosition);
|
||||
|
||||
void _SwapChainSizeChanged(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::SizeChangedEventArgs& e);
|
||||
void _SwapChainScaleChanged(const Windows::UI::Xaml::Controls::SwapChainPanel& sender, const Windows::Foundation::IInspectable& args);
|
||||
|
||||
@@ -385,6 +395,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
bool _CapturePointer(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& e);
|
||||
bool _ReleasePointerCapture(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& e);
|
||||
|
||||
void _TryStartAutoScroll(const Windows::UI::Input::PointerPoint& pointerPoint, const double scrollVelocity);
|
||||
void _TryStopAutoScroll(const uint32_t pointerId);
|
||||
void _UpdateAutoScroll(const Windows::Foundation::IInspectable& sender, const Windows::Foundation::IInspectable& e);
|
||||
|
||||
void _KeyHandler(const Windows::UI::Xaml::Input::KeyRoutedEventArgs& e, const bool keyDown);
|
||||
bool _KeyHandler(WORD vkey, WORD scanCode, ::Microsoft::Terminal::Core::ControlKeyStates modifiers, bool keyDown);
|
||||
static ::Microsoft::Terminal::Core::ControlKeyStates _GetPressedModifierKeys() noexcept;
|
||||
@@ -395,6 +409,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
winrt::Windows::Foundation::Point _toControlOrigin(const til::point terminalPosition);
|
||||
Core::Point _toTerminalOrigin(winrt::Windows::Foundation::Point cursorPosition);
|
||||
|
||||
double _GetAutoScrollSpeed(double cursorDistanceFromBorder) const;
|
||||
|
||||
void _Search(const winrt::hstring& text, const bool goForward, const bool caseSensitive, const bool regularExpression);
|
||||
void _SearchChanged(const winrt::hstring& text, const bool goForward, const bool caseSensitive, const bool regularExpression);
|
||||
void _CloseSearchBoxControl(const winrt::Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& args);
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
<!-- ========================= Headers ======================== -->
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="FlatC.h" />
|
||||
<ClInclude Include="ControlCore.h">
|
||||
<DependentUpon>ControlCore.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
@@ -62,13 +61,14 @@
|
||||
<DependentUpon>InteractivityAutomationPeer.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="XamlUiaTextRange.h" />
|
||||
<ClInclude Include="HwndTerminal.hpp" />
|
||||
<ClInclude Include="HwndTerminalAutomationPeer.hpp" />
|
||||
</ItemGroup>
|
||||
<!-- ========================= Cpp Files ======================== -->
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FlatC.cpp" />
|
||||
<ClCompile Include="ControlCore.cpp">
|
||||
<DependentUpon>ControlCore.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
@@ -102,6 +102,8 @@
|
||||
<DependentUpon>InteractivityAutomationPeer.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="XamlUiaTextRange.cpp" />
|
||||
<ClCompile Include="HwndTerminal.cpp" />
|
||||
<ClCompile Include="HwndTerminalAutomationPeer.cpp" />
|
||||
</ItemGroup>
|
||||
<!-- ========================= idl Files ======================== -->
|
||||
<ItemGroup>
|
||||
@@ -158,7 +160,6 @@
|
||||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\WinRTUtils\WinRTUtils.vcxproj">
|
||||
<Private>true</Private>
|
||||
<Project>{CA5CAD1A-039A-4929-BA2A-8BEB2E4106FE}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
|
||||
@@ -7,16 +7,17 @@ EXPORTS
|
||||
AvoidBuggyTSFConsoleFlags
|
||||
CreateTerminal
|
||||
DestroyTerminal
|
||||
TerminalSendOutput
|
||||
TerminalRegisterScrollCallback
|
||||
TerminalTriggerResize
|
||||
TerminalTriggerResizeWithDimension
|
||||
TerminalCalculateResize
|
||||
TerminalDpiChanged
|
||||
TerminalUserScroll
|
||||
TerminalGetSelection
|
||||
TerminalIsSelectionActive
|
||||
TerminalSetTheme
|
||||
TerminalRegisterScrollCallback
|
||||
TerminalRegisterWriteCallback
|
||||
TerminalSendKeyEvent
|
||||
TerminalSendCharEvent
|
||||
TerminalSendKeyEvent
|
||||
TerminalSendOutput
|
||||
TerminalSetFocused
|
||||
TerminalSetTheme
|
||||
TerminalTriggerResize
|
||||
TerminalTriggerResizeWithDimension
|
||||
TerminalUserScroll
|
||||
|
||||
@@ -115,12 +115,4 @@
|
||||
|
||||
<!-- This -must- go after cppwinrt.build.post.props because that includes many VS-provided props including appcontainer.common.props, which stomps on what cppwinrt.targets did. -->
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
|
||||
|
||||
<!--LATE LATE LATE-->
|
||||
<ItemDefinitionGroup>
|
||||
<Link>
|
||||
<AdditionalDependencies>delayimp.lib;uiautomationcore.lib;oleaut32.lib;onecoreuap.lib;user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<DelayLoadDLLs>uiautomationcore.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
</Project>
|
||||
|
||||
@@ -55,8 +55,9 @@ namespace winrt::Microsoft::Terminal::Settings
|
||||
auto settings{ winrt::make_self<TerminalSettings>() };
|
||||
|
||||
const auto globals = appSettings.GlobalSettings();
|
||||
const auto windowSettings = appSettings.WindowSettingsDefaults();
|
||||
settings->_ApplyProfileSettings(profile);
|
||||
settings->_ApplyGlobalSettings(globals);
|
||||
settings->_ApplyGlobalSettings(windowSettings);
|
||||
settings->_ApplyAppearanceSettings(profile.DefaultAppearance(), globals.ColorSchemes(), globals.CurrentTheme());
|
||||
|
||||
return settings;
|
||||
@@ -362,27 +363,27 @@ namespace winrt::Microsoft::Terminal::Settings
|
||||
// - globalSettings: the global property values we're applying.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalSettings::_ApplyGlobalSettings(const Model::GlobalAppSettings& globalSettings) noexcept
|
||||
void TerminalSettings::_ApplyGlobalSettings(const Model::WindowSettings& windowSettings) noexcept
|
||||
{
|
||||
_InitialRows = globalSettings.InitialRows();
|
||||
_InitialCols = globalSettings.InitialCols();
|
||||
_InitialRows = windowSettings.InitialRows();
|
||||
_InitialCols = windowSettings.InitialCols();
|
||||
|
||||
_WordDelimiters = globalSettings.WordDelimiters();
|
||||
_CopyOnSelect = globalSettings.CopyOnSelect();
|
||||
_CopyFormatting = globalSettings.CopyFormatting();
|
||||
_FocusFollowMouse = globalSettings.FocusFollowMouse();
|
||||
_ScrollToZoom = globalSettings.ScrollToZoom();
|
||||
_ScrollToChangeOpacity = globalSettings.ScrollToChangeOpacity();
|
||||
_GraphicsAPI = globalSettings.GraphicsAPI();
|
||||
_DisablePartialInvalidation = globalSettings.DisablePartialInvalidation();
|
||||
_SoftwareRendering = globalSettings.SoftwareRendering();
|
||||
_TextMeasurement = globalSettings.TextMeasurement();
|
||||
_AmbiguousWidth = globalSettings.AmbiguousWidth();
|
||||
_DefaultInputScope = globalSettings.DefaultInputScope();
|
||||
_UseBackgroundImageForWindow = globalSettings.UseBackgroundImageForWindow();
|
||||
_TrimBlockSelection = globalSettings.TrimBlockSelection();
|
||||
_DetectURLs = globalSettings.DetectURLs();
|
||||
_EnableUnfocusedAcrylic = globalSettings.EnableUnfocusedAcrylic();
|
||||
_WordDelimiters = windowSettings.WordDelimiters();
|
||||
_CopyOnSelect = windowSettings.CopyOnSelect();
|
||||
_CopyFormatting = windowSettings.CopyFormatting();
|
||||
_FocusFollowMouse = windowSettings.FocusFollowMouse();
|
||||
_ScrollToZoom = windowSettings.ScrollToZoom();
|
||||
_ScrollToChangeOpacity = windowSettings.ScrollToChangeOpacity();
|
||||
_GraphicsAPI = windowSettings.GraphicsAPI();
|
||||
_DisablePartialInvalidation = windowSettings.DisablePartialInvalidation();
|
||||
_SoftwareRendering = windowSettings.SoftwareRendering();
|
||||
_TextMeasurement = windowSettings.TextMeasurement();
|
||||
_AmbiguousWidth = windowSettings.AmbiguousWidth();
|
||||
_DefaultInputScope = windowSettings.DefaultInputScope();
|
||||
_UseBackgroundImageForWindow = windowSettings.UseBackgroundImageForWindow();
|
||||
_TrimBlockSelection = windowSettings.TrimBlockSelection();
|
||||
_DetectURLs = windowSettings.DetectURLs();
|
||||
_EnableUnfocusedAcrylic = windowSettings.EnableUnfocusedAcrylic();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
||||
@@ -105,7 +105,7 @@ namespace winrt::Microsoft::Terminal::Settings
|
||||
static winrt::com_ptr<TerminalSettings> _CreateWithProfileCommon(const Model::CascadiaSettings& appSettings, const Model::Profile& profile);
|
||||
void _ApplyProfileSettings(const Model::Profile& profile);
|
||||
|
||||
void _ApplyGlobalSettings(const Model::GlobalAppSettings& globalSettings) noexcept;
|
||||
void _ApplyGlobalSettings(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,8 +22,9 @@ 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) :
|
||||
_GlobalSettings{ globalSettings },
|
||||
_WindowSettings{ windowSettings },
|
||||
_ThemeList{ single_threaded_observable_vector<Model::Theme>() }
|
||||
{
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(NewTabPosition, NewTabPosition, NewTabPosition, L"Globals_NewTabPosition", L"Content");
|
||||
@@ -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,20 +31,21 @@ 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::GlobalAppSettings _GlobalSettings;
|
||||
Model::WindowSettings _WindowSettings;
|
||||
winrt::Windows::Foundation::IInspectable _currentTheme;
|
||||
|
||||
void _UpdateThemeList();
|
||||
|
||||
@@ -9,7 +9,7 @@ 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,7 @@ 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();
|
||||
|
||||
@@ -551,7 +551,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
}
|
||||
else if (*clickedItemTag == interactionTag)
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::Interaction>(), winrt::make<NavigateToPageArgs>(winrt::make<InteractionViewModel>(_settingsClone.GlobalSettings()), *this, elementToFocus));
|
||||
contentFrame().Navigate(xaml_typename<Editor::Interaction>(), winrt::make<NavigateToPageArgs>(winrt::make<InteractionViewModel>(_settingsClone.GlobalSettings(), _settingsClone.WindowSettingsDefaults()), *this, elementToFocus));
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, RS_(L"Nav_Interaction/Content"), BreadcrumbSubPage::None));
|
||||
}
|
||||
else if (*clickedItemTag == renderingTag)
|
||||
@@ -649,7 +649,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
}
|
||||
else if (*clickedItemTag == globalAppearanceTag)
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::GlobalAppearance>(), winrt::make<NavigateToPageArgs>(winrt::make<GlobalAppearanceViewModel>(_settingsClone.GlobalSettings()), *this, elementToFocus));
|
||||
contentFrame().Navigate(xaml_typename<Editor::GlobalAppearance>(), winrt::make<NavigateToPageArgs>(winrt::make<GlobalAppearanceViewModel>(_settingsClone.GlobalSettings(), _settingsClone.WindowSettingsDefaults()), *this, elementToFocus));
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, RS_(L"Nav_Appearance/Content"), BreadcrumbSubPage::None));
|
||||
}
|
||||
else if (*clickedItemTag == addProfileTag)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
@@ -111,6 +111,10 @@ Model::CascadiaSettings CascadiaSettings::Copy() const
|
||||
}
|
||||
|
||||
settings->_globals = _globals->Copy();
|
||||
// temporary: instantiate a new window settings shim
|
||||
// will be removed when we have real per-window settings
|
||||
settings->_windowSettings = winrt::make_self<implementation::WindowSettings>();
|
||||
settings->_windowSettings->Initialize(settings->_globals);
|
||||
settings->_allProfiles = winrt::single_threaded_observable_vector(std::move(allProfiles));
|
||||
settings->_activeProfiles = winrt::single_threaded_observable_vector(std::move(activeProfiles));
|
||||
|
||||
@@ -209,6 +213,19 @@ Model::GlobalAppSettings CascadiaSettings::GlobalSettings() const
|
||||
return *_globals;
|
||||
}
|
||||
|
||||
Model::WindowSettings CascadiaSettings::WindowSettingsDefaults() const
|
||||
{
|
||||
return *_windowSettings;
|
||||
}
|
||||
|
||||
Model::WindowSettings CascadiaSettings::WindowSettings(const winrt::hstring& /*windowName*/) const
|
||||
{
|
||||
// In the WIP implementation, we always return the same WindowSettings
|
||||
// object regardless of window name, since per-window settings
|
||||
// storage is not yet implemented.
|
||||
return *_windowSettings;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Get a reference to our profiles.defaults object
|
||||
// Arguments:
|
||||
@@ -775,7 +792,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(_globals->DefaultProfile()) :
|
||||
ProfileDefaults();
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ Author(s):
|
||||
|
||||
#include "GlobalAppSettings.h"
|
||||
#include "Profile.h"
|
||||
#include "WindowSettings.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model
|
||||
{
|
||||
@@ -163,6 +164,8 @@ 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;
|
||||
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;
|
||||
@@ -228,6 +231,7 @@ 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> _windowSettings = winrt::make_self<implementation::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>();
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "GlobalAppSettings.idl";
|
||||
import "WindowSettings.idl";
|
||||
import "Profile.idl";
|
||||
import "TerminalWarnings.idl";
|
||||
import "DefaultTerminal.idl";
|
||||
@@ -38,6 +39,9 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
|
||||
GlobalAppSettings GlobalSettings { get; };
|
||||
|
||||
WindowSettings WindowSettingsDefaults();
|
||||
WindowSettings WindowSettings(String windowName);
|
||||
|
||||
Profile ProfileDefaults { get; };
|
||||
|
||||
IObservableVector<Profile> AllProfiles { get; };
|
||||
|
||||
@@ -1317,7 +1317,7 @@ void CascadiaSettings::_researchOnLoad()
|
||||
// ----------------------------- RE: Themes ----------------------------
|
||||
const auto numThemes = GlobalSettings().Themes().Size();
|
||||
const auto themeInUse = GlobalSettings().CurrentTheme().Name();
|
||||
const auto changedTheme = GlobalSettings().HasTheme();
|
||||
const auto changedTheme = _globals->HasTheme();
|
||||
|
||||
// system: 0
|
||||
// light: 1
|
||||
@@ -1413,6 +1413,7 @@ CascadiaSettings::CascadiaSettings(SettingsLoader&& loader) :
|
||||
// but we're going to set these fields in our constructor later on anyways.
|
||||
_globals{},
|
||||
_baseLayerProfile{},
|
||||
_windowSettings{},
|
||||
_allProfiles{},
|
||||
_activeProfiles{},
|
||||
_warnings{}
|
||||
@@ -1478,6 +1479,11 @@ CascadiaSettings::CascadiaSettings(SettingsLoader&& loader) :
|
||||
_warnings = winrt::single_threaded_vector(std::move(warnings));
|
||||
_themesChangeLog = std::move(loader.userSettings.themesChangeLog);
|
||||
|
||||
// Initialize the WindowSettings to delegate to the GlobalAppSettings.
|
||||
// In the future, per-window-name settings will be separate objects.
|
||||
_windowSettings = winrt::make_self<implementation::WindowSettings>();
|
||||
_windowSettings->Initialize(_globals);
|
||||
|
||||
_resolveDefaultProfile();
|
||||
_resolveNewTabMenuProfiles();
|
||||
_validateSettings();
|
||||
@@ -1717,7 +1723,7 @@ void CascadiaSettings::_resolveDefaultProfile() const
|
||||
}
|
||||
|
||||
// Use the first profile as the new default.
|
||||
GlobalSettings().DefaultProfile(_allProfiles.GetAt(0).Guid());
|
||||
_globals->DefaultProfile(_allProfiles.GetAt(0).Guid());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
||||
@@ -51,63 +51,18 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
};
|
||||
|
||||
[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);
|
||||
// ---- Global-only settings (not per-window) ----
|
||||
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);
|
||||
|
||||
// ---- Color schemes ----
|
||||
Windows.Foundation.Collections.IMapView<String, ColorScheme> ColorSchemes();
|
||||
void AddColorScheme(ColorScheme scheme);
|
||||
void RemoveColorScheme(String schemeName);
|
||||
@@ -115,9 +70,9 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
|
||||
ActionMap ActionMap { get; };
|
||||
|
||||
// ---- Themes ----
|
||||
Windows.Foundation.Collections.IMapView<String, Theme> Themes();
|
||||
void AddTheme(Theme theme);
|
||||
INHERITABLE_SETTING(ThemePair, Theme);
|
||||
Theme CurrentTheme { get; };
|
||||
|
||||
Boolean ShouldUsePersistedLayout();
|
||||
|
||||
@@ -18,7 +18,20 @@ Author(s):
|
||||
// Macro format (defaultArgs are optional):
|
||||
// (type, name, jsonKey, defaultArgs)
|
||||
|
||||
#define MTSM_GLOBAL_SETTINGS(X) \
|
||||
// Settings that are truly app-global (not per-window)
|
||||
#define MTSM_GLOBAL_ONLY_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)
|
||||
|
||||
// Settings that are per-window (may vary by window name in the future)
|
||||
#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,39 +53,36 @@ Author(s):
|
||||
X(bool, ShowTitleInTitlebar, "showTerminalTitleInTitlebar", true) \
|
||||
X(bool, ConfirmCloseAllTabs, "warning.confirmCloseAllTabs", true) \
|
||||
X(Model::ThemePair, Theme, "theme") \
|
||||
X(hstring, Language, "language") \
|
||||
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(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)
|
||||
|
||||
// MTSM_GLOBAL_SETTINGS is the union of global-only and window settings.
|
||||
// GlobalAppSettings uses this to keep all settings on one object (for now).
|
||||
#define MTSM_GLOBAL_SETTINGS(X) \
|
||||
MTSM_GLOBAL_ONLY_SETTINGS(X) \
|
||||
MTSM_WINDOW_SETTINGS(X)
|
||||
|
||||
// Also add these settings to:
|
||||
// * Profile.idl
|
||||
// * TerminalSettings.h
|
||||
|
||||
@@ -82,6 +82,9 @@
|
||||
<ClInclude Include="GlobalAppSettings.h">
|
||||
<DependentUpon>GlobalAppSettings.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="WindowSettings.h">
|
||||
<DependentUpon>WindowSettings.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>WindowSettings.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="KeyChordSerialization.cpp">
|
||||
<DependentUpon>KeyChordSerialization.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
@@ -222,6 +228,7 @@
|
||||
<Midl Include="Command.idl" />
|
||||
<Midl Include="DefaultTerminal.idl" />
|
||||
<Midl Include="GlobalAppSettings.idl" />
|
||||
<Midl Include="WindowSettings.idl" />
|
||||
<Midl Include="Profile.idl" />
|
||||
<Midl Include="EnumMappings.idl" />
|
||||
<Midl Include="TerminalWarnings.idl" />
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
<ClCompile Include="CascadiaSettings.cpp" />
|
||||
<ClCompile Include="CascadiaSettingsSerialization.cpp" />
|
||||
<ClCompile Include="GlobalAppSettings.cpp" />
|
||||
<ClCompile Include="WindowSettings.cpp" />
|
||||
<ClCompile Include="KeyChordSerialization.cpp" />
|
||||
<ClCompile Include="Profile.cpp" />
|
||||
<ClCompile Include="ColorScheme.cpp" />
|
||||
@@ -66,6 +67,7 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="CascadiaSettings.h" />
|
||||
<ClInclude Include="GlobalAppSettings.h" />
|
||||
<ClInclude Include="WindowSettings.h" />
|
||||
<ClInclude Include="TerminalSettingsSerializationHelpers.h" />
|
||||
<ClInclude Include="KeyChordSerialization.h" />
|
||||
<ClInclude Include="Profile.h" />
|
||||
@@ -104,6 +106,7 @@
|
||||
<Midl Include="ColorScheme.idl" />
|
||||
<Midl Include="Command.idl" />
|
||||
<Midl Include="GlobalAppSettings.idl" />
|
||||
<Midl Include="WindowSettings.idl" />
|
||||
<Midl Include="Profile.idl" />
|
||||
<Midl Include="TerminalWarnings.idl" />
|
||||
<Midl Include="CascadiaSettings.idl" />
|
||||
|
||||
57
src/cascadia/TerminalSettingsModel/WindowSettings.cpp
Normal file
57
src/cascadia/TerminalSettingsModel/WindowSettings.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "WindowSettings.h"
|
||||
#include "WindowSettings.g.cpp"
|
||||
|
||||
#include "GlobalAppSettings.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
{
|
||||
void WindowSettings::Initialize(const com_ptr<GlobalAppSettings>& globals)
|
||||
{
|
||||
_globals = globals;
|
||||
}
|
||||
|
||||
hstring WindowSettings::Name() const
|
||||
{
|
||||
// In the WIP implementation, there is only one set of window settings
|
||||
// (backed by GlobalAppSettings), so the name is always empty.
|
||||
return L"";
|
||||
}
|
||||
|
||||
winrt::guid WindowSettings::DefaultProfile() const
|
||||
{
|
||||
return _globals->DefaultProfile();
|
||||
}
|
||||
|
||||
void WindowSettings::DefaultProfile(const winrt::guid& value)
|
||||
{
|
||||
_globals->DefaultProfile(value);
|
||||
}
|
||||
|
||||
hstring WindowSettings::UnparsedDefaultProfile() const
|
||||
{
|
||||
return _globals->UnparsedDefaultProfile();
|
||||
}
|
||||
|
||||
void WindowSettings::UnparsedDefaultProfile(const hstring& value)
|
||||
{
|
||||
_globals->UnparsedDefaultProfile(value);
|
||||
}
|
||||
|
||||
bool WindowSettings::HasUnparsedDefaultProfile() const
|
||||
{
|
||||
return _globals->HasUnparsedDefaultProfile();
|
||||
}
|
||||
|
||||
void WindowSettings::ClearUnparsedDefaultProfile()
|
||||
{
|
||||
_globals->ClearUnparsedDefaultProfile();
|
||||
}
|
||||
|
||||
// The MTSM_WINDOW_SETTINGS delegate methods are defined inline
|
||||
// in WindowSettings.h via the WINDOW_SETTINGS_DELEGATE macro.
|
||||
|
||||
}
|
||||
61
src/cascadia/TerminalSettingsModel/WindowSettings.h
Normal file
61
src/cascadia/TerminalSettingsModel/WindowSettings.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- WindowSettings.h
|
||||
|
||||
Abstract:
|
||||
- This class represents per-window settings. In the current WIP implementation,
|
||||
it delegates all property access to a GlobalAppSettings object, since we
|
||||
haven't yet split the actual storage into per-window instances.
|
||||
|
||||
Author(s):
|
||||
- Mike Griese - April 2026
|
||||
|
||||
--*/
|
||||
#pragma once
|
||||
|
||||
#include "WindowSettings.g.h"
|
||||
#include "MTSMSettings.h"
|
||||
#include "GlobalAppSettings.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
{
|
||||
struct WindowSettings : WindowSettingsT<WindowSettings>
|
||||
{
|
||||
public:
|
||||
// Default constructor required by WinRT activation
|
||||
WindowSettings() = default;
|
||||
|
||||
// Construct a WindowSettings that delegates to the given GlobalAppSettings.
|
||||
void Initialize(const com_ptr<GlobalAppSettings>& globals);
|
||||
|
||||
hstring Name() const;
|
||||
|
||||
winrt::guid DefaultProfile() const;
|
||||
void DefaultProfile(const winrt::guid& value);
|
||||
|
||||
hstring UnparsedDefaultProfile() const;
|
||||
void UnparsedDefaultProfile(const hstring& value);
|
||||
bool HasUnparsedDefaultProfile() const;
|
||||
void ClearUnparsedDefaultProfile();
|
||||
|
||||
// Delegate all MTSM_WINDOW_SETTINGS to GlobalAppSettings via inline methods.
|
||||
#define WINDOW_SETTINGS_DELEGATE(type, name, ...) \
|
||||
type name() const { return _globals->name(); } \
|
||||
void name(const type& value) { _globals->name(value); } \
|
||||
bool Has##name() const { return _globals->Has##name(); } \
|
||||
void Clear##name() { _globals->Clear##name(); }
|
||||
MTSM_WINDOW_SETTINGS(WINDOW_SETTINGS_DELEGATE)
|
||||
#undef WINDOW_SETTINGS_DELEGATE
|
||||
|
||||
private:
|
||||
com_ptr<GlobalAppSettings> _globals{ nullptr };
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(WindowSettings);
|
||||
}
|
||||
65
src/cascadia/TerminalSettingsModel/WindowSettings.idl
Normal file
65
src/cascadia/TerminalSettingsModel/WindowSettings.idl
Normal file
@@ -0,0 +1,65 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "IInheritable.idl.h"
|
||||
|
||||
import "GlobalAppSettings.idl";
|
||||
import "NewTabMenuEntry.idl";
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Model
|
||||
{
|
||||
[default_interface] runtimeclass WindowSettings
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -695,7 +695,7 @@ 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) };
|
||||
|
||||
@@ -76,7 +76,6 @@ static void EnsureAllResourcesArePresent(const ScopedResourceLoader& loader)
|
||||
|
||||
#endif
|
||||
|
||||
static ScopedResourceLoader no_resources{ ScopedResourceLoader::NoResourcesT{} };
|
||||
const ScopedResourceLoader& GetLibraryResourceLoader()
|
||||
try
|
||||
{
|
||||
@@ -86,30 +85,18 @@ try
|
||||
#endif
|
||||
return loader;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_CAUGHT_EXCEPTION();
|
||||
return no_resources;
|
||||
}
|
||||
CATCH_FAIL_FAST()
|
||||
|
||||
winrt::hstring GetLibraryResourceString(const std::wstring_view key)
|
||||
try
|
||||
{
|
||||
return GetLibraryResourceLoader().GetLocalizedString(key);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_CAUGHT_EXCEPTION();
|
||||
return winrt::hstring{};
|
||||
}
|
||||
CATCH_FAIL_FAST()
|
||||
|
||||
bool HasLibraryResourceWithName(const std::wstring_view key)
|
||||
try
|
||||
{
|
||||
return GetLibraryResourceLoader().HasResourceWithName(key);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_CAUGHT_EXCEPTION();
|
||||
return false;
|
||||
}
|
||||
CATCH_FAIL_FAST()
|
||||
|
||||
@@ -6,12 +6,7 @@
|
||||
class ScopedResourceLoader
|
||||
{
|
||||
public:
|
||||
struct NoResourcesT
|
||||
{
|
||||
};
|
||||
ScopedResourceLoader(const std::wstring_view resourceLocatorBase);
|
||||
ScopedResourceLoader(const NoResourcesT&) :
|
||||
_resourceMap{ nullptr }, _resourceContext{ nullptr } {}
|
||||
winrt::Windows::ApplicationModel::Resources::Core::ResourceMap GetResourceMap() const noexcept;
|
||||
winrt::hstring GetLocalizedString(const std::wstring_view resourceName) const;
|
||||
bool HasResourceWithName(const std::wstring_view resourceName) const;
|
||||
|
||||
@@ -1442,8 +1442,9 @@ void WindowEmperor::_checkWindowsForNotificationIcon()
|
||||
// themselves getting the new settings, only ask the app logic for the
|
||||
// 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 settings = _app.Logic().Settings();
|
||||
const auto globals = settings.GlobalSettings();
|
||||
auto needsIcon = globals.AlwaysShowNotificationIcon() || settings.WindowSettingsDefaults().MinimizeToNotificationArea();
|
||||
if (!needsIcon)
|
||||
{
|
||||
for (const auto& host : _windows)
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Castle.Core" publicKeyToken="407dd0808d44fbdc" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0"/>
|
||||
<assemblyIdentity name="Castle.Core" publicKeyToken="407dd0808d44fbdc" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
|
||||
@@ -177,10 +177,7 @@ namespace Microsoft.Terminal.Wpf
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = false)]
|
||||
public static extern void CreateTerminal(IntPtr parent, out IntPtr hwnd, out IntPtr terminal);
|
||||
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern void DestroyTerminal(IntPtr terminal);
|
||||
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = false)]
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = true)]
|
||||
public static extern void TerminalSendOutput(IntPtr terminal, string lpdata);
|
||||
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = false)]
|
||||
@@ -192,44 +189,44 @@ namespace Microsoft.Terminal.Wpf
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = false)]
|
||||
public static extern void TerminalCalculateResize(IntPtr terminal, int width, int height, out TilSize dimensions);
|
||||
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = false)]
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = true)]
|
||||
public static extern void TerminalDpiChanged(IntPtr terminal, int newDpi);
|
||||
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = false)]
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = true)]
|
||||
public static extern void TerminalRegisterScrollCallback(IntPtr terminal, [MarshalAs(UnmanagedType.FunctionPtr)] ScrollCallback callback);
|
||||
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = false)]
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = true)]
|
||||
public static extern void TerminalRegisterWriteCallback(IntPtr terminal, [MarshalAs(UnmanagedType.FunctionPtr)] WriteCallback callback);
|
||||
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = false)]
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = true)]
|
||||
public static extern void TerminalUserScroll(IntPtr terminal, int viewTop);
|
||||
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = false)]
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = true)]
|
||||
[return: MarshalAs(UnmanagedType.LPWStr)]
|
||||
public static extern string TerminalGetSelection(IntPtr terminal);
|
||||
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = false)]
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = true)]
|
||||
[return: MarshalAs(UnmanagedType.I1)]
|
||||
public static extern bool TerminalIsSelectionActive(IntPtr terminal);
|
||||
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = false)]
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern void DestroyTerminal(IntPtr terminal);
|
||||
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = true)]
|
||||
public static extern void TerminalSendKeyEvent(IntPtr terminal, ushort vkey, ushort scanCode, ushort flags, bool keyDown);
|
||||
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = false)]
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = true)]
|
||||
public static extern void TerminalSendCharEvent(IntPtr terminal, char ch, ushort scanCode, ushort flags);
|
||||
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = false)]
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = true)]
|
||||
public static extern void TerminalSetTheme(IntPtr terminal, [MarshalAs(UnmanagedType.Struct)] TerminalTheme theme, string fontFamily, short fontSize, int newDpi);
|
||||
|
||||
[DllImport("Microsoft.Terminal.Control.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, PreserveSig = true)]
|
||||
public static extern void TerminalSetFocused(IntPtr terminal, bool focused);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern IntPtr SetFocus(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern IntPtr GetFocus();
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern short GetKeyState(int keyCode);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct WINDOWPOS
|
||||
{
|
||||
|
||||
@@ -37,6 +37,7 @@ namespace Microsoft.Terminal.Wpf
|
||||
NativeMethods.AvoidBuggyTSFConsoleFlags();
|
||||
|
||||
this.MessageHook += this.TerminalContainer_MessageHook;
|
||||
this.GotFocus += this.TerminalContainer_GotFocus;
|
||||
this.Focusable = true;
|
||||
}
|
||||
|
||||
@@ -323,12 +324,24 @@ namespace Microsoft.Terminal.Wpf
|
||||
character = (char)vKey;
|
||||
}
|
||||
|
||||
private void TerminalContainer_GotFocus(object sender, RoutedEventArgs e)
|
||||
{
|
||||
e.Handled = true;
|
||||
NativeMethods.SetFocus(this.hwnd);
|
||||
}
|
||||
|
||||
private IntPtr TerminalContainer_MessageHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
||||
{
|
||||
if (hwnd == this.hwnd)
|
||||
{
|
||||
switch ((NativeMethods.WindowMessage)msg)
|
||||
{
|
||||
case NativeMethods.WindowMessage.WM_SETFOCUS:
|
||||
NativeMethods.TerminalSetFocused(this.terminal, true);
|
||||
break;
|
||||
case NativeMethods.WindowMessage.WM_KILLFOCUS:
|
||||
NativeMethods.TerminalSetFocused(this.terminal, false);
|
||||
break;
|
||||
case NativeMethods.WindowMessage.WM_MOUSEACTIVATE:
|
||||
this.Focus();
|
||||
NativeMethods.SetFocus(this.hwnd);
|
||||
@@ -336,7 +349,6 @@ namespace Microsoft.Terminal.Wpf
|
||||
case NativeMethods.WindowMessage.WM_SYSKEYDOWN: // fallthrough
|
||||
case NativeMethods.WindowMessage.WM_KEYDOWN:
|
||||
{
|
||||
// WM_KEYDOWN lParam layout documentation: https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-keydown
|
||||
UnpackKeyMessage(wParam, lParam, out ushort vkey, out ushort scanCode, out ushort flags);
|
||||
NativeMethods.TerminalSendKeyEvent(this.terminal, vkey, scanCode, flags, true);
|
||||
break;
|
||||
@@ -391,10 +403,10 @@ namespace Microsoft.Terminal.Wpf
|
||||
this.Connection?.Resize((uint)dimensions.Y, (uint)dimensions.X);
|
||||
break;
|
||||
|
||||
//case NativeMethods.WindowMessage.WM_MOUSEWHEEL:
|
||||
//var delta = (short)(((long)wParam) >> 16);
|
||||
//this.UserScrolled?.Invoke(this, delta);
|
||||
//break;
|
||||
case NativeMethods.WindowMessage.WM_MOUSEWHEEL:
|
||||
var delta = (short)(((long)wParam) >> 16);
|
||||
this.UserScrolled?.Invoke(this, delta);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,117 +11,6 @@ namespace WpfTerminalTestNetCore
|
||||
{
|
||||
public class EchoConnection : Microsoft.Terminal.Wpf.ITerminalConnection
|
||||
{
|
||||
byte[] __foo_txt = {
|
||||
0x1b, 0x5b, 0x48, 0x1b, 0x5b, 0x32, 0x4a, 0x1b, 0x5b, 0x33, 0x4a, 0x0d,
|
||||
0x0a, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b, 0x31, 0x31, 0x38, 0x6d,
|
||||
0x54, 0x1b, 0x5b, 0x30, 0x6d, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b,
|
||||
0x31, 0x35, 0x34, 0x6d, 0x68, 0x1b, 0x5b, 0x30, 0x6d, 0x1b, 0x5b, 0x33,
|
||||
0x38, 0x3b, 0x35, 0x3b, 0x31, 0x35, 0x34, 0x6d, 0x61, 0x1b, 0x5b, 0x30,
|
||||
0x6d, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b, 0x31, 0x35, 0x34, 0x6d,
|
||||
0x6e, 0x1b, 0x5b, 0x30, 0x6d, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b,
|
||||
0x31, 0x34, 0x38, 0x6d, 0x6b, 0x1b, 0x5b, 0x30, 0x6d, 0x1b, 0x5b, 0x33,
|
||||
0x38, 0x3b, 0x35, 0x3b, 0x31, 0x38, 0x34, 0x6d, 0x73, 0x1b, 0x5b, 0x30,
|
||||
0x6d, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b, 0x31, 0x38, 0x34, 0x6d,
|
||||
0x20, 0x1b, 0x5b, 0x30, 0x6d, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b,
|
||||
0x31, 0x38, 0x34, 0x6d, 0x66, 0x1b, 0x5b, 0x30, 0x6d, 0x1b, 0x5b, 0x33,
|
||||
0x38, 0x3b, 0x35, 0x3b, 0x31, 0x37, 0x38, 0x6d, 0x6f, 0x1b, 0x5b, 0x30,
|
||||
0x6d, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b, 0x32, 0x31, 0x34, 0x6d,
|
||||
0x72, 0x1b, 0x5b, 0x30, 0x6d, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b,
|
||||
0x32, 0x31, 0x34, 0x6d, 0x20, 0x1b, 0x5b, 0x30, 0x6d, 0x1b, 0x5b, 0x33,
|
||||
0x38, 0x3b, 0x35, 0x3b, 0x32, 0x31, 0x34, 0x6d, 0x76, 0x1b, 0x5b, 0x30,
|
||||
0x6d, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b, 0x32, 0x30, 0x38, 0x6d,
|
||||
0x69, 0x1b, 0x5b, 0x30, 0x6d, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b,
|
||||
0x32, 0x30, 0x38, 0x6d, 0x73, 0x1b, 0x5b, 0x30, 0x6d, 0x1b, 0x5b, 0x33,
|
||||
0x38, 0x3b, 0x35, 0x3b, 0x32, 0x30, 0x38, 0x6d, 0x69, 0x1b, 0x5b, 0x30,
|
||||
0x6d, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b, 0x32, 0x30, 0x33, 0x6d,
|
||||
0x74, 0x1b, 0x5b, 0x30, 0x6d, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b,
|
||||
0x32, 0x30, 0x33, 0x6d, 0x69, 0x1b, 0x5b, 0x30, 0x6d, 0x1b, 0x5b, 0x33,
|
||||
0x38, 0x3b, 0x35, 0x3b, 0x32, 0x30, 0x33, 0x6d, 0x6e, 0x1b, 0x5b, 0x30,
|
||||
0x6d, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b, 0x32, 0x30, 0x33, 0x6d,
|
||||
0x67, 0x1b, 0x5b, 0x30, 0x6d, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b,
|
||||
0x31, 0x39, 0x38, 0x6d, 0x20, 0x1b, 0x5b, 0x30, 0x6d, 0x1b, 0x5b, 0x33,
|
||||
0x38, 0x3b, 0x35, 0x3b, 0x31, 0x39, 0x38, 0x6d, 0x6d, 0x1b, 0x5b, 0x30,
|
||||
0x6d, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b, 0x31, 0x39, 0x38, 0x6d,
|
||||
0x79, 0x1b, 0x5b, 0x30, 0x6d, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b,
|
||||
0x31, 0x39, 0x39, 0x6d, 0x20, 0x1b, 0x5b, 0x30, 0x6d, 0x1b, 0x5b, 0x33,
|
||||
0x38, 0x3b, 0x35, 0x3b, 0x31, 0x39, 0x39, 0x6d, 0x77, 0x1b, 0x5b, 0x30,
|
||||
0x6d, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b, 0x31, 0x39, 0x39, 0x6d,
|
||||
0x65, 0x1b, 0x5b, 0x30, 0x6d, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b,
|
||||
0x31, 0x36, 0x33, 0x6d, 0x62, 0x1b, 0x5b, 0x30, 0x6d, 0x1b, 0x5b, 0x33,
|
||||
0x38, 0x3b, 0x35, 0x3b, 0x31, 0x36, 0x34, 0x6d, 0x73, 0x1b, 0x5b, 0x30,
|
||||
0x6d, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b, 0x31, 0x36, 0x34, 0x6d,
|
||||
0x69, 0x1b, 0x5b, 0x30, 0x6d, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b,
|
||||
0x31, 0x36, 0x34, 0x6d, 0x74, 0x1b, 0x5b, 0x30, 0x6d, 0x1b, 0x5b, 0x33,
|
||||
0x38, 0x3b, 0x35, 0x3b, 0x31, 0x32, 0x38, 0x6d, 0x65, 0x1b, 0x5b, 0x30,
|
||||
0x6d, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b, 0x31, 0x32, 0x39, 0x6d,
|
||||
0x21, 0x1b, 0x5b, 0x30, 0x6d, 0x0d, 0x0a, 0x0d, 0x0a, 0x54, 0x68, 0x69,
|
||||
0x73, 0x20, 0x69, 0x73, 0x20, 0x6d, 0x79, 0x20, 0x63, 0x6f, 0x6f, 0x6c,
|
||||
0x20, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x20, 0x61, 0x62, 0x6f,
|
||||
0x75, 0x74, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x73,
|
||||
0x0d, 0x0a, 0x48, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20,
|
||||
0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6f, 0x6f, 0x6c,
|
||||
0x20, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x73, 0x0d, 0x0a,
|
||||
0x2a, 0x20, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x54, 0x65,
|
||||
0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70,
|
||||
0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
|
||||
0x6f, 0x6d, 0x2f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74,
|
||||
0x2f, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x29, 0x0d, 0x0a,
|
||||
0x0d, 0x0a, 0x1b, 0x5b, 0x35, 0x6d, 0x5b, 0x55, 0x4e, 0x44, 0x45, 0x52,
|
||||
0x20, 0x43, 0x4f, 0x4e, 0x53, 0x54, 0x52, 0x55, 0x43, 0x54, 0x49, 0x4f,
|
||||
0x4e, 0x5d, 0x1b, 0x5b, 0x6d, 0x0d, 0x0a, 0x0d, 0x0a, 0x59, 0x6f, 0x75,
|
||||
0x20, 0x61, 0x72, 0x65, 0x20, 0x76, 0x69, 0x73, 0x69, 0x74, 0x6f, 0x72,
|
||||
0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x1b, 0x5b, 0x35, 0x33,
|
||||
0x3b, 0x34, 0x3b, 0x39, 0x32, 0x6d, 0x30, 0x30, 0x30, 0x30, 0x32, 0x1b,
|
||||
0x5b, 0x6d, 0x20, 0x74, 0x6f, 0x20, 0x6d, 0x79, 0x20, 0x77, 0x65, 0x62,
|
||||
0x73, 0x69, 0x74, 0x65, 0x2e, 0x0d, 0x0a, 0x0d, 0x0a, 0x1b, 0x5b, 0x33,
|
||||
0x38, 0x3b, 0x35, 0x3b, 0x32, 0x34, 0x34, 0x6d, 0x1b, 0x5b, 0x35, 0x33,
|
||||
0x6d, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61,
|
||||
0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x6f,
|
||||
0x6f, 0x6c, 0x20, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x73,
|
||||
0x20, 0x77, 0x65, 0x62, 0x72, 0x69, 0x6e, 0x67, 0x21, 0x20, 0x1b, 0x5b,
|
||||
0x35, 0x35, 0x6d, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x56, 0x69, 0x73, 0x69,
|
||||
0x74, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x73, 0x69, 0x74, 0x65,
|
||||
0x73, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x65, 0x62,
|
||||
0x20, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x2e, 0x2e, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x1b, 0x5b, 0x39, 0x34, 0x6d, 0x1b, 0x5d, 0x38, 0x3b,
|
||||
0x69, 0x64, 0x3d, 0x70, 0x72, 0x65, 0x76, 0x3b, 0x68, 0x74, 0x74, 0x70,
|
||||
0x73, 0x3a, 0x2f, 0x2f, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c,
|
||||
0x2e, 0x73, 0x69, 0x74, 0x65, 0x2f, 0x3f, 0x70, 0x72, 0x65, 0x76, 0x69,
|
||||
0x6f, 0x75, 0x73, 0x3d, 0x31, 0x1b, 0x5c, 0x50, 0x72, 0x65, 0x76, 0x69,
|
||||
0x6f, 0x75, 0x73, 0x1b, 0x5d, 0x38, 0x3b, 0x3b, 0x1b, 0x5c, 0x1b, 0x5b,
|
||||
0x6d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1b, 0x5b, 0x39, 0x34, 0x6d, 0x1b,
|
||||
0x5d, 0x38, 0x3b, 0x69, 0x64, 0x3d, 0x72, 0x61, 0x6e, 0x64, 0x3b, 0x68,
|
||||
0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x74, 0x65, 0x72, 0x6d, 0x69,
|
||||
0x6e, 0x61, 0x6c, 0x2e, 0x73, 0x69, 0x74, 0x65, 0x2f, 0x3f, 0x72, 0x61,
|
||||
0x6e, 0x64, 0x6f, 0x6d, 0x3d, 0x31, 0x1b, 0x5c, 0x52, 0x61, 0x6e, 0x64,
|
||||
0x6f, 0x6d, 0x1b, 0x5d, 0x38, 0x3b, 0x3b, 0x1b, 0x5c, 0x1b, 0x5b, 0x6d,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x1b, 0x5b, 0x39, 0x34, 0x6d, 0x1b, 0x5d,
|
||||
0x38, 0x3b, 0x69, 0x64, 0x3d, 0x6e, 0x65, 0x78, 0x74, 0x3b, 0x68, 0x74,
|
||||
0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e,
|
||||
0x61, 0x6c, 0x2e, 0x73, 0x69, 0x74, 0x65, 0x2f, 0x3f, 0x6e, 0x65, 0x78,
|
||||
0x74, 0x3d, 0x31, 0x1b, 0x5c, 0x4e, 0x65, 0x78, 0x74, 0x1b, 0x5d, 0x38,
|
||||
0x3b, 0x3b, 0x1b, 0x5c, 0x1b, 0x5b, 0x6d, 0x20, 0x0d, 0x0a, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x1b, 0x5b, 0x39, 0x34, 0x6d, 0x1b, 0x5d,
|
||||
0x38, 0x3b, 0x69, 0x64, 0x3d, 0x70, 0x72, 0x65, 0x76, 0x3b, 0x68, 0x74,
|
||||
0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e,
|
||||
0x61, 0x6c, 0x2e, 0x73, 0x69, 0x74, 0x65, 0x2f, 0x3f, 0x70, 0x72, 0x65,
|
||||
0x76, 0x69, 0x6f, 0x75, 0x73, 0x3d, 0x31, 0x1b, 0x5c, 0x20, 0x20, 0x53,
|
||||
0x69, 0x74, 0x65, 0x20, 0x20, 0x1b, 0x5d, 0x38, 0x3b, 0x3b, 0x1b, 0x5c,
|
||||
0x1b, 0x5b, 0x6d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1b, 0x5b, 0x39, 0x34, 0x6d,
|
||||
0x1b, 0x5d, 0x38, 0x3b, 0x69, 0x64, 0x3d, 0x6e, 0x65, 0x78, 0x74, 0x3b,
|
||||
0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x74, 0x65, 0x72, 0x6d,
|
||||
0x69, 0x6e, 0x61, 0x6c, 0x2e, 0x73, 0x69, 0x74, 0x65, 0x2f, 0x3f, 0x6e,
|
||||
0x65, 0x78, 0x74, 0x3d, 0x31, 0x1b, 0x5c, 0x53, 0x69, 0x74, 0x65, 0x1b,
|
||||
0x5d, 0x38, 0x3b, 0x3b, 0x1b, 0x5c, 0x1b, 0x5b, 0x6d, 0x20, 0x0d, 0x0a,
|
||||
0x1b, 0x5b, 0x34, 0x3b, 0x33, 0x38, 0x3b, 0x35, 0x3b, 0x32, 0x34, 0x34,
|
||||
0x6d, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1b, 0x5b,
|
||||
0x6d, 0x0d, 0x0a
|
||||
};
|
||||
public event EventHandler<TerminalOutputEventArgs> TerminalOutput;
|
||||
|
||||
public void Resize(uint rows, uint columns)
|
||||
@@ -129,15 +18,10 @@ namespace WpfTerminalTestNetCore
|
||||
return;
|
||||
}
|
||||
|
||||
private void _preamble()
|
||||
{
|
||||
_print(System.Text.Encoding.UTF8.GetString(__foo_txt));
|
||||
_print("^A: prt esc ^B: sgrmouse ^C: win32im ^D: again!\r\n");
|
||||
return;
|
||||
}
|
||||
public void Start()
|
||||
{
|
||||
_preamble();
|
||||
TerminalOutput.Invoke(this, new TerminalOutputEventArgs("ECHO CONNECTION\r\n^A: toggle printable ESC\r\n^B: toggle SGR mouse mode\r\n^C: toggle win32 input mode\r\n\r\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
private bool _escapeMode;
|
||||
@@ -178,27 +62,18 @@ namespace WpfTerminalTestNetCore
|
||||
TerminalOutput.Invoke(this, new TerminalOutputEventArgs($"Printable ESC mode: {_escapeMode}\r\n"));
|
||||
}
|
||||
}
|
||||
else if (data[0] == '\x04')
|
||||
{
|
||||
_preamble();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Echo back to the terminal, but make backspace/newline work properly.
|
||||
var str = data.Replace("\r", "\r\n").Replace("\x7f", "\x08 \x08");
|
||||
_print(str);
|
||||
if (_escapeMode)
|
||||
{
|
||||
str = str.Replace("\x1b", "\u241b");
|
||||
}
|
||||
TerminalOutput.Invoke(this, new TerminalOutputEventArgs(str));
|
||||
}
|
||||
}
|
||||
|
||||
private void _print(string str)
|
||||
{
|
||||
if (_escapeMode)
|
||||
{
|
||||
str = str.Replace("\x1b", "\u241b");
|
||||
}
|
||||
TerminalOutput.Invoke(this, new TerminalOutputEventArgs(str));
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
This diagnostic is broken in VS 17.7 which our CI currently uses. It's fixed in 17.8.
|
||||
-->
|
||||
<DisableSpecificWarnings>4201;4312;4467;5105;26434;26445;26456;26478;26494;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<PreprocessorDefinitions>_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;_WINDOWS;EXTERNAL_BUILD;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_WINDOWS;EXTERNAL_BUILD;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Castle.Core" publicKeyToken="407dd0808d44fbdc" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0"/>
|
||||
<assemblyIdentity name="Castle.Core" publicKeyToken="407dd0808d44fbdc" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
|
||||
@@ -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);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user